You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "Voss, Marko" <Ma...@zeiss.com> on 2015/06/03 11:33:44 UTC

Problems with forwarding

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.



Ø  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.


Thank you in advance and best regards,

Marko

Re: AW: Problems with forwarding

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

Sure, in this case create a JAX-RS Application implementation and 
register it as a 'javax.ws.rs.Application' parameter. This custom 
Application can configure RequestDispatcherProvider in the code

HTH, Sergey


On 09/06/15 06:03, Voss, Marko wrote:
> Hi Sergey,
>
> thank you very much for your input. Ok I want to try the RequestDispatcherProvider, but how do I setup this one with the following structure to call the setResourcePaths?
>
>      <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>jaxrs.providers</param-name>
>              <param-value>
>              org.apache.cxf.jaxrs.provider.RequestDispatcherProvider
>              </param-value>
>          </init-param><load-on-startup>1</load-on-startup>
>      </servlet>
>
> In other words, I want to setup multiple resources, so I need to use the method:
>
> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider.setResourcePaths(Map<String, String>)
>
> I know how to do the setup for
>
> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider.setResourcePath(String)
>
> It is:
>
> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider(resourcePath=.jsp)
>
> But how to setup a Map here?
>
> Or can I setup multiple providers at once? Have not tried this one yet.
>
>
> Thank you very much and best regards,
>
> Marko
>
>
> -----Ursprüngliche Nachricht-----
> Von: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Gesendet: Freitag, 5. Juni 2015 14:55
> An: users@cxf.apache.org
> Betreff: Re: Problems with forwarding
>
> 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
>>
>


AW: Problems with forwarding

Posted by "Voss, Marko" <Ma...@zeiss.com>.
Hi Sergey,

thank you very much for your input. Ok I want to try the RequestDispatcherProvider, but how do I setup this one with the following structure to call the setResourcePaths?

    <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>jaxrs.providers</param-name>
            <param-value>
            org.apache.cxf.jaxrs.provider.RequestDispatcherProvider
            </param-value>
        </init-param><load-on-startup>1</load-on-startup>
    </servlet>

In other words, I want to setup multiple resources, so I need to use the method:

org.apache.cxf.jaxrs.provider.RequestDispatcherProvider.setResourcePaths(Map<String, String>)

I know how to do the setup for

org.apache.cxf.jaxrs.provider.RequestDispatcherProvider.setResourcePath(String)

It is:

org.apache.cxf.jaxrs.provider.RequestDispatcherProvider(resourcePath=.jsp)

But how to setup a Map here?

Or can I setup multiple providers at once? Have not tried this one yet.


Thank you very much and best regards,

Marko


-----Ursprüngliche Nachricht-----
Von: Sergey Beryozkin [mailto:sberyozkin@gmail.com] 
Gesendet: Freitag, 5. Juni 2015 14:55
An: users@cxf.apache.org
Betreff: Re: Problems with forwarding

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
>


Re: Problems with forwarding

Posted by Sergey Beryozkin <sb...@gmail.com>.
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
>