Hi Marko, sorry for a delay,
On 03/06/15 10:33, Voss, Marko wrote:
Hello,
I do have a problem with forwarding done in CXF.
I have a service implementation like this:
@Path("/foo")
public interface FooSpec {
@GET
Response foo(@QueryParam("bar") String bar, @Context HttpServletRequest
request, @Context HttpServletResponse response);
}
public class Foo implements FooSpec {
@Context
private ServletContext servletContext;
public Response foo(final String bar, final HttpServletRequest request,
final HttpServletResponse response) {
final RequestDispatcher view =
servletContext.getRequestDispatcher("/hello.jsp");
try {
view.forward(request, response);
} catch (Exception e) {
return
Response.serverError().entity(e.getMessage()).build();
}
return null;
}
}
And I am using a JAXRS-Servlet like this:
<servlet>
<servlet-name>JavaServer Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>RestfulApp</servlet-name>
<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
<init-param>
<param-name>jaxrs.serviceClasses</param-name>
<param-value>
org.foo.bar.Foo
</param-value>
</init-param>
<init-param>
<param-name>redirects-list</param-name>
<param-value>([\w/])+.css ([\w/])+.jsp ([\w/])+.faces ([\w/])+.js ([\w/])+.gif
([\w/])+.jpg ([\w/])+.jpeg ([\w/])+.png</param-value> <!-- matches: /images/hello.jpg
for example -->
</init-param>
<init-param>
<param-name>redirect-servlet-path</param-name>
<param-value>/</param-value>
</init-param>
<init-param>
<param-name>redirect-servlet-name</param-name>
<param-value>JavaServer Faces Servlet</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RestfulApp</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>JavaServer Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
JSP pages are located at the following location:
/appcontext/*.jsp
REST-services are located at the following location:
/appcontext/rest/*
Ø ISSUE 1
When performing the very first request to this service after deployment, I get
the following exception. This happens only the very first time. After this
exception (on reload), it works well until next re-deployment/restart.
com.sap.engine.services.servlets_jsp.server.exceptions.ServletNotFoundException:
Requested resource [/foo] is not found.
When analyzing this in Firefox, it states, that the request URI is:
http://server:port/appcontext/rest/foo
So the request seem to be valid but for some reason, it looks like the request
would be:
http://server:port/appcontext/foo
But that is not the case.
When checking the other REST services, every single one of them throws this
exception on the very first request. The RequestDispatcher seems to have a
problem on the first request per REST service.
I'm not really sure what the problem is but recall that I updated CXF to
ensure that when RequestDispatcher is requested directly from the
injected ServletContext (as opposed to using CXF
RequestDispatcherProvider) then CXF will not try to do any subsequent
processing of the response, can you try CXF 3.0.5 ?
As a side note I'd recommend migrating to RequestDispatcherProvider
anyway as it will make your code more JAX-RS centric and eventually more
easier to migrate when the MVC spec gets out...
Ø ISSUE 2
When I have done a forwarding to a JSP page, it does keep the /rest context
from the JAXRS servlet, even when I do specify redirect-servlet-name with the
JSP servlet.
So when defining relative links in that JSP page, the do get the /rest part
added to them. So I guess the JAXRS servlet does add its context to the JSP
servlet.
I've checked CXF AbstractHttpServlet code (in rt/transports/http), if
redirect-serlvlet-path is set then it will use it as a servlet path,
which is "/" in the above configuration.
I wonder if it is due to the fact that you initiate the forwarding from
the JAX-RS code and at that point of time, due to the fact the code
directly interact with ServletContext, the current servlet path (/rest)
is recorded.
I think you should either make sure the initial redirect to "/hello.jsp"
goes immediately from the CXF servlet or again, use
RequestDispatcherProvider where you can configure the custom servlet
path such as "/"
HTH, Sergey
Thank you in advance and best regards,
Marko