spring boot version is 2.0.0.RELEASE.
test class:
#RunWith(SpringRunner.class)
#SpringBootTest(classes={Application.class},webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)
#AutoConfigureMockMvc(secure = false)
public class ProcControllerTest {
#Autowired
private MockMvc mockMvc;
#Test
public void testGetProc() throws Exception {
String requestUrl = "/app/rest/query/proc";
// Request json body
JSONObject jsonBody = new JSONObject();
jsonBody.put("id", "101");
String contentBody = jsonBody.toJSONString();
MvcResult mvcResult = mockMvc.perform(post(requestUrl)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(contentBody)
).andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
assertThat(response.getStatus()).isEqualTo(200);
}
}
I alse tried another test config :
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {Application.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//#AutoConfigureMockMvc(secure = false)
public class ProcessInstanceControllerMockMvcTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext wac;
#Before
public void before() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
Application.class is below:
#SpringBootApplication
#Import({ApplicationConfiguration.class})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder
builder) {
return builder.sources(Application.class);
}
#Bean
public ServletRegistrationBean apiDispatcher(){
DispatcherServlet api = new DispatcherServlet();
api.setContextClass(AnnotationConfigWebApplicationContext.class);
api.setContextConfigLocation(ApiDispatcherServletConfiguration.class.getName());
ServletRegistrationBean registrationBean = new ServletRegistrationBean();
registrationBean.setServlet(api);
registrationBean.addUrlMappings("/api/*");
registrationBean.setLoadOnStartup(1);
registrationBean.setAsyncSupported(true);
registrationBean.setName("api");
return registrationBean;
}
#Bean
public ServletRegistrationBean appDispatcher(){
DispatcherServlet app = new DispatcherServlet();
app.setContextClass(AnnotationConfigWebApplicationContext.class);
app.setContextConfigLocation(AppDispatcherServletConfiguration.class.getName());
ServletRegistrationBean registrationBean = new ServletRegistrationBean();
registrationBean.setServlet(app);
registrationBean.addUrlMappings("/app/*");
registrationBean.setLoadOnStartup(1);
registrationBean.setAsyncSupported(true);
registrationBean.setName("app");
return registrationBean;
}
}
The test run simple log is below :
10:58:26.015[main][INFO ]Initializing Spring FrameworkServlet '' o.a.c.c.C.[.[.[/].log:180
10:58:26.015[main][INFO ]FrameworkServlet '': initialization started o.s.t.w.s.TestDispatcherServlet.initServletBean:494
10:58:26.699[main][INFO ]Mapped ...... Multi line
10:58:30.408[main][INFO ]FrameworkServlet '': initialization completed in 4392 ms o.s.t.w.s.TestDispatcherServlet.initServletBean:513
10:58:31.159[main][INFO ]SpringTemplateLoader for FreeMarker: using resource loader[org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#61f80d55: startup date [Wed Jul 04 10:57:51 CST 2018]; root of context hierarchy] and template loader path [classpath:/templates/] o.s.u.f.SpringTemplateLoader.:62
10:58:31.163[main][INFO ]ClassTemplateLoader for Spring macros added to FreeMarker configuration o.s.w.s.v.f.FreeMarkerConfigurer.postProcessTemplateLoaders:131
10:58:33.065[main][INFO ]Starting ProtocolHandler ["http-nio-auto-1"] o.a.c.h.Http11NioProtocol.log:180
10:58:33.082[main][INFO ]Using a shared selector for servlet write/read o.a.t.u.n.NioSelectorPool.log:180
10:58:33.114[main][INFO ]Initializing Spring FrameworkServlet 'app' o.a.c.c.C.[.[.[/].log:180
10:58:33.115[main][INFO ]FrameworkServlet 'app': initialization started o.s.w.s.DispatcherServlet.initServletBean:494
10:58:33.121[main][INFO ]Refreshing WebApplicationContext for namespace 'app-servlet': startup date [Wed Jul 04 10:58:33 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#61f80d55 o.s.w.c.s.AnnotationConfigWebApplicationContext.prepareRefresh:589
10:58:33.123[main][INFO ]Successfully resolved class for [com.fg.app.servlet.AppDispatcherServletConfiguration] o.s.w.c.s.AnnotationConfigWebApplicationContext.loadBeanDefinitions:233
10:58:34.034[main][INFO ]JSR-330 'javax.inject.Inject' annotation found and supported for autowiring o.s.b.f.a.AutowiredAnnotationBeanPostProcessor.:154
10:58:26.699[main][INFO ]Mapped ...... Multi line
10:58:35.186[main][INFO ]FrameworkServlet 'app': initialization completed in 2071 ms o.s.w.s.DispatcherServlet.initServletBean:513
10:58:35.199[main][INFO ]Initializing Spring FrameworkServlet 'api' o.a.c.c.C.[.[.[/].log:180
10:58:35.200[main][INFO ]FrameworkServlet 'api': initialization started o.s.w.s.DispatcherServlet.initServletBean:494
10:58:35.201[main][INFO ]Refreshing WebApplicationContext for namespace 'api-servlet': startup date [Wed Jul 04 10:58:35 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#61f80d55 o.s.w.c.s.AnnotationConfigWebApplicationContext.prepareRefresh:589
10:58:35.202[main][INFO ]Successfully resolved class for [com.fg.app.servlet.ApiDispatcherServletConfiguration] o.s.w.c.s.AnnotationConfigWebApplicationContext.loadBeanDefinitions:233
10:58:35.661[main][INFO ]JSR-330 'javax.inject.Inject' annotation found and supported for autowiring o.s.b.f.a.AutowiredAnnotationBeanPostProcessor.:154
10:58:26.699[main][INFO ]Mapped ...... Multi line
10:58:36.303[main][INFO ]FrameworkServlet 'api': initialization completed in 1103 ms o.s.w.s.DispatcherServlet.initServletBean:513
10:58:36.305[main][INFO ]Tomcat started on port(s): 53711 (http) with context path '' o.s.b.w.e.t.TomcatWebServer.start:205
10:58:36.309[main][INFO ]Started ProcControllerTest in 46.914 seconds (JVM running for 51.157) c.f.a.ProcControllerTest.logStarted:59
10:58:37.160[Thread-9][INFO ]Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#61f80d55: startup date [Wed Jul 04 10:57:51 CST 2018]; root of context hierarchy o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext.doClose:989
10:58:37.180[Thread-9][INFO ]Closing JPA EntityManagerFactory for persistence unit 'default' o.s.o.j.LocalContainerEntityManagerFactoryBean.destroy:572
10:58:37.196[Thread-9][INFO ]{dataSource-1} closed c.a.d.p.DruidDataSource.close:1823
10:58:37.360[localhost-startStop-2][INFO ]Closing WebApplicationContext for namespace 'app-servlet': startup date [Wed Jul 04 10:58:33 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#61f80d55 o.s.w.c.s.AnnotationConfigWebApplicationContext.doClose:989
10:58:37.364[localhost-startStop-2][INFO ]Closing WebApplicationContext for namespace 'api-servlet': startup date [Wed Jul 04 10:58:35 CST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#61f80d55 o.s.w.c.s.AnnotationConfigWebApplicationContext.doClose:989
Test Result :org.junit.ComparisonFailure: Expected :200 Actual :404
Through the above log, I guess the class TestDispatcherServlet is the reason. when I use TestRestTemplate, it does not init TestDispatcherServlet, and works fun.
MockMvc uses a DispatcherServlet different from the one registered by the app. The URLs you pass to it should be the exact same URLs you specified in your #Controller annotations.
Related
My client runs on Tomcat and Server is on Wildfly 11.
The EJB is:
package dao;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import model.User;
#Stateless
public class UserDaoImpl implements UserDao {
#PersistenceContext(unitName = "nju")
protected EntityManager em;
#Override
public String login(String userName, String password) {
try {
Query query = em.createQuery("from User u where u.userName='" + userName + "'");
#SuppressWarnings("unchecked")
List<User> list = query.getResultList();
em.clear();
if (list.isEmpty()) {
return "failure";
} else if (list.get(0).getPassword().equals(password)) {
return "success";
}
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
return "failure";
}
}
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="nju">
<description>This unit manages users.</description>
<jta-data-source>java:/MySqlDS</jta-data-source>
<properties>
<property name="showSql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
</properties>
</persistence-unit>
When I run server, the output contains
18:53:38,997 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 62) WFLYCLINF0002: Started client-mappings cache from ejb container
18:53:39,005 INFO [org.jboss.as.jpa] (ServerService Thread Pool -- 62) WFLYJPA0010: Starting Persistence Unit (phase 2 of 2) Service 'J2EEServer.war#nju'
So the location of persistence.xml is not wrong.
However, when I run client and call the function in EJB. There is NullPointerException which indicates that the entitymanager is not injected.
In client I use a factory to get EJB. The method is
private static Object getEJB(String JNDIPath) {
Hashtable<String, String> jndiProperties = new Hashtable<>();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
try {
Context context = new InitialContext(jndiProperties);
return context.lookup(JNDIPath);
} catch (NamingException e) {
e.printStackTrace();
}
return null;
}
The exception only shows on wildfly and when it occurs, the tomcat message is
org.jboss.ejb.client.EJBClient <clinit>
INFO: JBoss EJB Client version 2.1.4.Final
org.xnio.Xnio <clinit>
INFO: XNIO version 3.4.0.Final
org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.4.0.Final
org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 4.0.21.Final
org.jboss.ejb.client.remoting.VersionReceiver handleMessage
INFO: EJBCLIENT000017: Received server version 3 and marshalling strategies [river]
org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate
INFO: EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext#51e6ae57, receiver=Remoting connection EJB receiver [connection=org.jboss.ejb.client.remoting.ConnectionPool$PooledConnection#5281b661,channel=jboss.ejb,nodename=microwin10-115]} on channel Channel ID 8d8bb52c (outbound) of Remoting connection 3607d423 to localhost/127.0.0.1:8080 of endpoint "client-endpoint" <41cb456e>
org.jboss.ejb.client.remoting.ChannelAssociation$ResponseReceiver handleEnd
INFO: EJBCLIENT000016: Channel Channel ID 8d8bb52c (outbound) of Remoting connection 3607d423 to localhost/127.0.0.1:8080 of endpoint "client-endpoint" <41cb456e> can no longer process messages
How can I solve this problem?
I finally find the solution!!
In my project, my previous Service code is
#Stateless
public class UserServiceImpl implements UserService {
private UserDao userdao=Factory.getUserDao();
#Override
public String login(String userName, String password) {
return userdao.login(userName, password);
}
#Override
public String register(User user) {
return userdao.register(user);
}
}
And in the Factory, I get the object by using new UserDaoImpl(). That's the question!
The EntityManager will not be injected if the object is used like this way.
So I delete the Factory and change the code in Service
#Stateless
public class UserServiceImpl implements UserService {
/**
* Will be injected
*/
#EJB
private UserDao userdao;
#Override
public String login(String userName, String password) {
return userdao.login(userName, password);
}
#Override
public String register(User user) {
return userdao.register(user);
}
}
That works perfectly.
I wrote a Rest API using Spring boot and Rest Template .Simplest one . Here is the code that I wrote in the controller .
package wsJson;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/api")
public class RestCon {
private AtomicLong id;
public Bean b;
#RequestMapping("/bean")
public Bean getBeans(#RequestParam(value="name")String name){
return new Bean(id.incrementAndGet(), name);
}
}
Bean is simple and the main class just runs the Spring Boot App .
Whenever I run the code it runs in localhost:8080 . But as I go to the URL
http://localhost:8080/api/bean?name=User1
it gives
Request Error (invalid_request)
Your request could not be processed. Request could not be handled This
could be caused by a misconfiguration, or possibly a malformed
request.
Can anyone help me understand the problem and how to solve it?
This code works normally, but in my office I am sitting behind proxy network and this code fails like this! Does anyone have any idea why is it so!
Edit:
After I run the app , I can see after entering the controller following gets logged in console:
2017-08-25 16:43:18.325 INFO 1056 --- [ main]
s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for
#ControllerAdvice:
org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#d3d15a:
startup date [Fri Aug 25 16:43:16 IST 2017]; root of context hierarchy
2017-08-25 16:43:18.419 INFO 1056 --- [ main]
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped
"{[/greeting],methods=[GET]}" onto public hello.Greeting
hello.GreetingController.greeting(java.lang.String) 2017-08-25
16:43:18.422 INFO 1056 --- [ main]
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto
public
org.springframework.http.ResponseEntity>
org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-08-25 16:43:18.422 INFO 1056 --- [ main]
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped
"{[/error],produces=[text/html]}" onto public
org.springframework.web.servlet.ModelAndView
org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-08-25 16:43:18.444 INFO 1056 --- [ main]
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path
[/webjars/] onto handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-08-25 16:43:18.444 INFO 1056 --- [ main]
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/] onto
handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-08-25 16:43:18.495 INFO 1056 --- [ main]
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path
[/**/favicon.ico] onto handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-08-25 16:43:18.633 INFO 1056 --- [ main]
o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX
exposure on startup 2017-08-25 16:43:18.817 INFO 1056 --- [
main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on
port(s): 8080 (http) 2017-08-25 16:43:18.833 INFO 1056 --- [
main] hello.Application : Started Application
in 3.063 seconds (JVM running for 3.729)
main class:
package wsJson;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
bean class:
package wsJson;
public class Bean {
public long id;
public String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Bean(long id, String name) {
super();
this.id = id;
this.name = name;
}
}
App made using spring-boot 1.5.6-RELEASE
This has nothing to do with your spring-boot application.
If you have an exception in your application logs please let us know about the stack trace. In your code snippet id is not initialised so your code can't work:
here is an example of code i tested :
#SpringBootApplication
#RestController
#RequestMapping("/api")
public class TestApplication {
private AtomicLong id = new AtomicLong();
#RequestMapping("/bean")
public String getBeans(#RequestParam(value="name")String name){
return new Bean(id.incrementAndGet(), name).toString();
}
class Bean{
public Bean(long l, String name) {
}
}
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
Test your application locally without that proxy so your can be sure your application works.
You posted your app startup logs and it looks like your controller is not mapper . Maybe your controller is not scanned by the application.
You controller has to be in a sub package of the package containing the class that is annotated by #SpringBootApplication so the component scanner can see it.
I am using eclipse kepler IDE.
I am getting java.lang.nullpointerexception and i know the reason because i am getting null in con object and con is used to call a method createStatement() which is throwing this exception.
I jst want to know why this con object accessing null from MyListener.java through getAttribute() method.
I have created msaccess DB and datasource named servletTest. But i don't know
why con is accessing null that's why it is giving exception.
Exception is given below:
Feb 05, 2014 11:48:12 AM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.8.0\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files/Java/jre8/bin/client;C:/Program Files/Java/jre8/bin;C:/Program Files/Java/jre8/lib/i386;C:\Windows\System32;C:\Program Files\Java\jdk1.8.0\bin;C:\Users\praveen\Desktop\eclipse;;.
Feb 05, 2014 11:48:12 AM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:advanced java' did not find a matching property.
Feb 05, 2014 11:48:12 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Feb 05, 2014 11:48:12 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Feb 05, 2014 11:48:12 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1175 ms
Feb 05, 2014 11:48:12 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Feb 05, 2014 11:48:12 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.50
Feb 05, 2014 11:48:14 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Feb 05, 2014 11:48:14 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Feb 05, 2014 11:48:14 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 1189 ms
java.lang.NullPointerException
at com.student.servletcontextevent.FetchData.doGet(FetchData.java:47)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
**inde.html**
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
fetch records
</body>
</html>
**FetchData**
package com.student.servletcontextevent;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class FetchData
*/
#WebServlet("/FetchData")
public class FetchData extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public FetchData() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try {
// Retrieving connection object from ServletContext object
ServletContext ctx = getServletContext();
Connection con = (Connection) ctx.getAttribute("mycon");
// retieving data from emp table
Statement ps = con.createStatement();
ResultSet rs = ps.executeQuery("Select * from emp");
while (rs.next()) {
out.print("<br>" + rs.getString(1) + " " + rs.getString(2));
}
con.close();
} catch (Exception e) {
e.printStackTrace();
}
out.close();
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
**MyListener**
package com.student.servletcontextevent;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MyListener
*/
#WebServlet("/MyListener")
public class MyListener extends HttpServlet implements ServletContextListener {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public MyListener() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
/**
* #see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent event) {
// TODO Auto-generated method stub
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String dataSourceName = "servletTest";
String dbUrl = "jdbc:odbc:" + dataSourceName;
Connection con=DriverManager.getConnection(dbUrl);
//storing connection object as an attribute in ServletContext
ServletContext ctx=event.getServletContext();
ctx.setAttribute("mycon", con);
}catch(Exception e){e.printStackTrace();}
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
Your listener class shouldn't extend HttpServlet, since it's not a servlet, but only a ServletContextListener. And as such, it should be annotated with #WebListener, and not with #WebServlet.
That said, you shouldn't use a single database connection in your webapp since, obviously, if two requests are handled concurrently, both will the use the same connection and will thus be unable to do their transactional work correctly.
Read the documentation of your servlet container to understand how to properly create a DataSource and access it from the servlets (see http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html for Tomcat). Each request handling method should get a connection from the DataSource, use it, then close the connection. Also, don't use the JDBC/ODBC bridge, which is buggy, slow and completely obsolete. Use the JDBC driver for your database. Every database on earth has a JDBC driver these days.
A side note to finish: whether you're using Eclipse, NetBeans or Notepad to write your code has nothing to do with the exception you're getting, at runtime, once your code is executed inside your web container. The IDE is completely irrelevant to your question.
Are you sure you can connect to your database?
My guess is 'con' is null in FetchData servlet because an exception is thrown in MyListener when connecting to database or MyListener is never used at all.
Indeed database connection should not be managed programmatically in your application, if you google for 'tomc1t database jndi' you should find a great tutorial.
Just to add more to #JB Nizet's correct answer..
Reasons for null pointer exception on database connection:
1) Not able to access database.
2) database access might require username and password which is not supplied or incorrect.
3) Wrong database name/url.
And just some suggestions :
1) Why are you creating connection object in listener? You can create them in seperate java file and access those in your servlets and not listeners.
2)Why are you saving connection object(con) in servlet context? Makes no sense to me.. Since you are sure that your application uses single database, you can make connection object static, and you can access it just by classname.
I have a restfull implementation using Jersey and Tomcat7. I have 3 resources called RegionService, ClientService and NoteService defined in my campher.rest package.
When I try to add another resource called TestResource, and Tomcat starts, it gives me the following error below. I don't understand how /{notes} conflicts with /{test}??
Please help, my hair will thank you.
Aug 22, 2012 2:23:39 AM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class campher.rest.NoteService
class campher.rest.ClientService
class campher.rest.TestResource
class campher.rest.RegionService
Aug 22, 2012 2:23:39 AM com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
Aug 22, 2012 2:23:40 AM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.12 02/15/2012 04:51 PM'
Aug 22, 2012 2:23:40 AM com.sun.jersey.spi.inject.Errors processErrorMessages
SEVERE: The following errors and warnings have been detected with resource and/or provider classes:
SEVERE: Conflicting URI templates. The URI template /{test} for root resource class campher.rest.TestResource and the URI template /{notes} transform to the same regular expression /([^/]+?)(/.*)?
Aug 22, 2012 2:23:40 AM org.apache.catalina.core.ApplicationContext log
SEVERE: StandardWrapper.Throwable
Here are the skeleton implementations of those 4 services.
package campher.rest;
#Path("regions")
public class RegionService {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response regions() {}
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Region addRegion(Region region){}
#PUT
#Consumes(MediaType.APPLICATION_JSON)
public Region updateRegion(Region region){}
#GET #Path("{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getRegion(#PathParam("id") long id) {}
#DELETE #Path("{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response deleteRegion(#PathParam("id") long id) {}
#GET #Path("{id}/clients")
#Produces(MediaType.APPLICATION_JSON)
public Response getClients(#PathParam("id") long id) {}
}
package campher.rest;
#Path("clients")
public class ClientService {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response clients() {}
#GET #Path("{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getClient(#PathParam("id") long id) {}
#GET #Path("{id}/notes")
#Produces(MediaType.APPLICATION_JSON)
public Response getNotes(#PathParam("id") long id) {}
#GET #Path("{id}/alerts")
#Produces(MediaType.APPLICATION_JSON)
public Response getAlerts(#PathParam("id") long id) {}
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Client addClient(Client client){}
#PUT
#Consumes(MediaType.APPLICATION_JSON)
public Client updateClient(Client client){}
#DELETE #Path("{id}")
#Consumes(MediaType.APPLICATION_JSON)
public Response deleteClient(#PathParam("id") long id){}
}
package campher.rest;
#Path("{notes}")
public class NoteService {
#GET #Path("{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getNote(#PathParam("id") long id) {}
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Note addNote(Note note){}
#PUT
#Consumes(MediaType.APPLICATION_JSON)
public Note updateNote(Note note){}
#DELETE #Path("{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response deleteNote(#PathParam("id") long id) {}
}
package campher.rest;
import javax.ws.rs.Path;
#Path("{test}")
public class TestResource {
}
#Path("test")
will match <web-root>/test
#Path("{test}")
will match <web-root>/foo and <web-root>/bar. The word test here is merely the path-param map key to associate foo and bar values.
Notice the presence and absence of {} around the names. They completely change the meaning of the expression. Their presence indicates that you want to extract that out and put it in an instance variable annotated with #PathParam("name-between-brackets").
Your #Path("{test}") and #Path("{notes}") both are essentially asking Jersey to look for root URLs of the form http://<host:port>/<webapp>/{capture-text} and copy the capture-text into test and notes path variables respectively. This is ambiguous.
I am working on some test program for SpringData MongoDB, I have done it same as it's mentioned on http://static.springsource.org/spring-data/data-document/docs/1.0.0.M2/reference/html/#mongo.core. But it's showing exceptions:
package com.springMongo.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Criteria;
import com.springMongo.config.MongoConfig;
import com.springMongo.person.Person;
public class MongoApp {
private static final Log log = LogFactory.getLog(MongoApp.class);
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MongoConfig.class);
MongoOperations mongoOps = ctx.getBean(MongoOperations.class);
mongoOps.insert(new Person("1234", "Joe"));
log.info(mongoOps.findOne(new Query(Criteria.where("name").is("Joe")), Person.class));
}
}
package com.springMongo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import com.mongodb.Mongo;
/**
* Spring MongoDB configuration file
*
*/
#Configuration
public class MongoConfig extends AbstractMongoConfiguration {
#Override
public Mongo mongo() throws Exception {
return new Mongo("128.0.0.1",10001);
}
#Override
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo() , "try_db");
}
#Override
public String getDatabaseName() {
// TODO Auto-generated method stub
return null;
}
}
package com.springMongo.person;
public class Person {
private String id;
private String name;
public Person(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
#Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}
}
But after running MongoApp.java, I am getting following exception:
Jan 3, 2012 12:41:28 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#7c64dc11: startup date [Tue Jan 03 12:41:28 IST 2012]; root of context hierarchy
Jan 3, 2012 12:41:29 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#2b275d39: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,mongoConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,mongo,mongoTemplate,mongoDbFactory,mongoMappingContext,mappingMongoConverter]; root of factory hierarchy
Jan 3, 2012 12:41:29 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#2b275d39: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,mongoConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,mongo,mongoTemplate,mongoDbFactory,mongoMappingContext,mappingMongoConverter]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDbFactory' defined in class com.springMongo.config.MongoConfig: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.data.mongodb.MongoDbFactory org.springframework.data.mongodb.config.AbstractMongoConfiguration.mongoDbFactory() throws java.lang.Exception] threw exception; nested exception is java.lang.IllegalArgumentException: Database name must not be empty
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1015)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73)
at com.springMongo.core.MongoApp.main(MongoApp.java:21)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.data.mongodb.MongoDbFactory org.springframework.data.mongodb.config.AbstractMongoConfiguration.mongoDbFactory() throws java.lang.Exception] threw exception; nested exception is java.lang.IllegalArgumentException: Database name must not be empty
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:169)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
... 13 more
Caused by: java.lang.IllegalArgumentException: Database name must not be empty
at org.springframework.util.Assert.hasText(Assert.java:162)
at org.springframework.data.mongodb.core.SimpleMongoDbFactory.<init>(SimpleMongoDbFactory.java:58)
at org.springframework.data.mongodb.config.AbstractMongoConfiguration.mongoDbFactory(AbstractMongoConfiguration.java:54)
at com.springMongo.config.MongoConfig$$EnhancerByCGLIB$$2129bffe.CGLIB$mongoDbFactory$3(<generated>)
at com.springMongo.config.MongoConfig$$EnhancerByCGLIB$$2129bffe$$FastClassByCGLIB$$7ac56fd1.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:215)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:280)
at com.springMongo.config.MongoConfig$$EnhancerByCGLIB$$2129bffe.mongoDbFactory(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:149)
... 14 more
Bad IP address? 128.0.0.1 should be 127.0.0.1
You need to specify database name via getDatabaseName()