Dear all,
I don't know whether this letter will be received, if someone read this letter please reply to me. thanks!
I found a bug from Jersey 1.0. if using any method to request a resource and that the result will be forward to a JSP file,
then found that all the value setted to the response object will be lost. after check the source code found problem as bellow:
Source code from "com.sun.jersey.impl.application.WebApplicationImpl" in handleRequest method
public void handleRequest(ContainerRequest request, ContainerResponseWriter responseWriter)
throws IOException {
final ContainerResponse response = new ContainerResponse(
this,
request,
responseWriter);
handleRequest(request, response);
}
as above we see that HttpServletResponse is wrapped by the ContainerResponseWriter object. for invoking method of
" public void handleRequest(ContainerRequest request, ContainerResponse response) throws IOException " ContainerResponse wraps the
ContainerResponseWriter again.
so here I found the problem that the value setted in ContainerResponse object not save back to orginal HttpServletRequest..
finally it cause to com.sun.jersey.impl.container.servlet.JSPTemplateProcessor 's method named "writeTo" can only get a unchaged HttpServletResponse instance.
public void writeTo(String resolvedPath, Object model, OutputStream out) throws IOException {
RequestDispatcher d = servletContext.getRequestDispatcher(resolvedPath);
if (d == null) {
throw new ContainerException("No request dispatcher for: " + resolvedPath);
}
d = new RequestDispatcherWrapper(d, ui.getMatchedResources().get(0), model);
try {
// Matt mark here. actually the HttpServletResponse get from current thread object is unchanged.
d.forward(requestInvoker.get(), responseInvoker.get());
} catch (Exception e) {
e.printStackTrace();
throw new ContainerException(e);
}
}
Here I add one line code to solve this problem
com.sun.jersey.impl.application.WebApplicationImpl
public void handleRequest(ContainerRequest request, ContainerResponse response) throws IOException {
try {
final WebApplicationContext localContext = new
WebApplicationContext(this, request, response);
context.set(localContext);
//...
try {
for (ContainerResponseFilter f : responseFilters)
response = f.filter(request, response);
} catch (WebApplicationException e) {
mapWebApplicationException(e, response);
} catch (RuntimeException e) {
if (!mapException(e, response)) {
context.set(null);
throw e;
}
}
//matt add here
//before write method save the response header value back to store HttpServletResoponse object
response.getContainerResponseWriter().writeStatusAndHeaders(-1, response);
try {
response.write();
} catch (WebApplicationException e) {
if (response.isCommitted()) {
throw e;
} else {
mapWebApplicationException(e, response);
response.write();
}
} finally {
context.set(null);
}
}
Your reply is expecting!
Yours Matt!
2008-10-28 from beijin China.