问题
Im doing a small test on suspending a asynch request using jersey but im getting an error. Let me show you what im trying to do and by the way the server is up and running just this request is failing:
Path("/json/metallica")
public class JSONService {
@GET
@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
public void getAsynchHealthyTracks(@Suspended AsyncResponse asyncResponse){
HealthService.getInstance().getHealththyTracks(asyncResponse);
}
}
when i call this from my local host on tomcat i get the following error:
HTTP Status 500 - javax.ws.rs.ProcessingException: Attempt to suspend a connection of an asynchronous request failed in the underlying container.
type Exception report
message javax.ws.rs.ProcessingException: Attempt to suspend a connection of an asynchronous request failed in the underlying container.
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: javax.ws.rs.ProcessingException: Attempt to suspend a connection of an asynchronous request failed in the underlying container.
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:391)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
root cause
javax.ws.rs.ProcessingException: Attempt to suspend a connection of an asynchronous request failed in the underlying container.
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:312)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:103)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:271)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
org.glassfish.jersey.internal.Errors.process(Errors.java:315)
org.glassfish.jersey.internal.Errors.process(Errors.java:297)
org.glassfish.jersey.internal.Errors.process(Errors.java:267)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:372)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
I have already the <async-supported>true</async-supported>
in my web.xml file and here is the contents of the web.xml file:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.example.ema,com.fasterxml.jackson.jaxrs.json</param-value>
<async-supported>true</async-supported>
<load-on-startup>1</load-on-startup>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
the health service itself just builds a pojo object and should send it back as a json. Anyway, here is the service:
public class HealthService {
private static HealthService instance = null;
protected HealthService() {
// Exists only to defeat instantiation.
}
public static HealthService getInstance() {
if(instance == null) {
instance = new HealthService();
}
return instance;
}
public void getHealthyTracks(AsyncResponse asyncResponse){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Track track = new Track();
track.setSinger("micheal jackson");
track.setTitle("thriller");
asyncResponse.resume(track);
}
}
i put a break point and it does not even reach the initial jersey call. the server just stops. My end goal is just to sleep for a few seconds and then send back a response.
UPDATE: Here is a photo of the web.xml as it is now:
回答1:
A small change is required to the Servlet configuration, within the web.xml
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.javapapers.webservices.rest.jersey</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
Observe the position/nesting of the "async-support" element, it has been positioned as a child element under the "servlet" element.
回答2:
I figured out the issue. the tag "true" should NOT be put in the init params section. It should be put just inside the servlet tag in the web.xml file. My web.xml now looks like this:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<async-supported>true</async-supported>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.example.ema,com.fasterxml.jackson.jaxrs.json</param-value>
<load-on-startup>1</load-on-startup>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
来源:https://stackoverflow.com/questions/31420631/jersey-error-when-trying-to-suspend-a-connection-of-an-asynchronous-request