Hi Sergey, I am running into a different issue with this. The forwarding calls a JSP, which requires a stylesheet.
The JAXRS service, which is performing the forwarding is located at: /appcontext/rest/service The JSP is located at: /appcontext/foo.jsp The stylesheet will be loaded from: /appcontext/rest/css/stylesheet.css Instead of: /appcontext/css/stylesheet.css Even if I put the stylesheet into a rest folder, it does not work, because the JAXRS servlet, "thinks" it has to handle a rest service request. Why is the stylesheet loaded like this? How can I avoid this behavior? Thank you in advance and best regards, Marko -----Ursprüngliche Nachricht----- Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] Gesendet: Montag, 20. April 2015 14:36 An: users@cxf.apache.org Betreff: Re: AW: AW: How to forward requests to a JSP page when using CXFNonSpringJaxrsServlet Hi Marko Great stuff, and it will only become better once JAX-RS 2.1 and new MVC spec get released and combined :-) Thanks, Sergey On 20/04/15 13:33, Voss, Marko wrote: > Hi Sergey, > > yes, it works now by injecting the HttpServletRequest and -Response as > parameters. I do not know, why it did not work the first time. > > Maybe I really put the @Context in the implementation instead of the > interface... I do not remember. :-) > > > Have a nice day Sergey and thank you for your continuous help! > > Best regards, > Marko > > -----Ursprüngliche Nachricht----- > Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] > Gesendet: Freitag, 10. April 2015 12:01 > An: users@cxf.apache.org > Betreff: Re: AW: How to forward requests to a JSP page when using > CXFNonSpringJaxrsServlet > > Hi, > I had a quick check yesterday, I have a test where one of JAX-RS contexts is > injected into a field and it depends on Java Proxy/InvocationHandler. > InvocationHandler is not invoked when a field proxy is simply passed > somewhere else as by reference, so there's no way (I can't see any way to be > more precise :-)) of using this latest code with NetWeawer. > > A thread local HttpServletRequest proxy implements HttpServletRequest > interface but apparently it is not sufficient with NetWeaver. Note, > the exception message may be misleading, it may well be nothing to do > with the fact a thread local proxy is passed further, but rather to do > with some class loader issue specific to NetWeaver > > So if you'd like to use this code then inject the contexts as > parameters, in the short term at least > > Sergey > > > > On 09/04/15 14:52, Sergey Beryozkin wrote: >> Hi >> >> OK, this explains it then. So the injected request and response >> proxies are passed further by reference. >> >> I guess NetWeaver is not using a base HttpServletRequest in the >> assignment/cast, otherwise it would likely not be a problem at all. >> >> Hmm... Unless this basic Java reference action can not be handled at >> a proxy level then it would not work... Using >> RequestDispatcherProvider in a dynamic mode is much simpler for sure :-). >> >> I'll investigate and see if anything can be done here at all... >> >> Re Context in method signatures - the only reason I can see why it >> does not work in your case is that you have an interface and the >> implementation - you need to put all the JAX-RS annotations on the >> interface methods, instead of some annotations on the interface and >> some >> - on the implementation, otherwise a JAX-RS rule that the annotations >> are not inherited once a given method has some of them works, often >> resulting in non-functional endpoints >> >> Sergey >> >> >> On 09/04/15 14:31, Voss, Marko wrote: >>> Hi Sergey, >>> >>> this is the code I am using: >>> >>> @Context >>> private ServletContext servletContext; >>> >>> @Context >>> private HttpServletRequest servletRequest; >>> >>> @Context >>> private HttpServletResponse servletResponse; >>> >>> @Override >>> public Response logon() { >>> try { >>> >>> this.servletContext.getRequestDispatcher(url).forward(this.servletRe >>> q >>> uest, >>> this.servletResponse); >>> } catch (Exception e) { >>> throw new WebApplicationException(e); >>> } >>> return null; >>> } >>> >>> I have to use @Context resources as class fields because of using >>> @Context on method parameters does not work. The JAXRS endpoints >>> will not exist then for methods like that. I do not know why. >>> >>> >>> Best regards, >>> Marko >>> >>> -----Ursprüngliche Nachricht----- >>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] >>> Gesendet: Donnerstag, 9. April 2015 15:09 >>> An: users@cxf.apache.org >>> Betreff: Re: How to forward requests to a JSP page when using >>> CXFNonSpringJaxrsServlet >>> >>> Hi Marko, >>> >>> no problems, that does not clear things up though, except that it >>> points to the fact that may be you use >>> >>> @Context >>> HttpServletRequest request; >>> >>> request.getServletContext().getRequestDispatcher() ? >>> >>> I can not connect a reference to ThreadLocalHttpServletRequest with >>> the earlier code you posted otherwise, where you showed >>> ServletContext being injected...If ServletContext is to be injected >>> then the runtime does not create ThreadLocalHttpServletRequest at all. >>> >>> if it is the case then I'll need to enhance the solution to 1. to >>> intercept request.getServletContext() calls. >>> >>> But I've realized you do not have to wait for a snapshot in order to >>> check why the exception is raised. Unfortunately I'm still not sure >>> why a cast to ThreadLocalHttpServletRequest is attempted. Assuming >>> you do have HttpServletRequest injected then what I said earlier >>> about thread locals applies the same way... >>> >>> You might want to pass contexts as JAX-RS method parameters which >>> would avoid creating thread locals at the cost of making the >>> signatures more verbose, but I'm curious why you have an exception >>> if the context is injected into a field >>> >>> Cheers, Sergey >>> >>> On 09/04/15 13:53, Voss, Marko wrote: >>>> Hi Sergey, >>>> >>>> I can test the SNAPSHOT by tomorrow at the earliest because of our >>>> artifactory is not updating before tonight. I rebuild the code to >>>> reproduce the ClassCastException. >>>> >>>> Looks like I remembered that message the wrong way. I am sorry. :-) >>>> >>>> This is a ClassLoader issue: >>>> >>>> >>>> WARNING: javax.ws.rs.WebApplicationException: >>>> java.lang.ClassCastException: class >>>> org.apache.cxf.jaxrs.impl.tl.ThreadLocalHttpServletRequest:foo.bar/ >>>> C >>>> at >>>> aloguefactory_...@com.sap.engine.boot.loader.ResourceMultiParentCla >>>> s sL oader@5125c637@alive incompatible with class >>>> com.sap.engine.services.servlets_jsp.server.runtime.client.HttpServ >>>> l >>>> et >>>> RequestFacadeWrapper:service:servlet_...@com.sap.engine.boot.loader. >>>> Re sourceMultiParentClassLoader@477afcff@alive >>>> at >>>> foo.bar.logon.web.jaxrs.impl.LogOnServiceImpl.logon(LogOnServiceImp >>>> l >>>> .j >>>> ava:70) >>>> >>>> LogOnServiceImpl is the JAXRS service we are talking about the >>>> whole time. CatalogueFactory_ear has absolutely nothing to do with >>>> this service at this point and I have no idea, why this is even >>>> being mentioned here. LogOnServiceImpl is in another EAR. The issue >>>> is, that the HttpServletRequestFacadeWrapper for JSP pages provided >>>> by NetWeaver cannot be castet to the ThreadLocalHttpServletRequest >>>> of CXF, which makes sense. >>>> >>>> >>>> Does this change the issue? >>>> >>>> >>>> Best regards, >>>> Marko >>>> >>>> -----Ursprüngliche Nachricht----- >>>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] >>>> Gesendet: Donnerstag, 9. April 2015 11:40 >>>> An: users@cxf.apache.org >>>> Betreff: Re: AW: AW: AW: AW: How to forward requests to a JSP page >>>> when using CXFNonSpringJaxrsServlet >>>> >>>> Hi, >>>> sure, it is done, what I'd like to ask you though is to test a >>>> snapshot, The fix I did is basically about wrapping a returned >>>> RequestDispatcher and setting the property checked by CXF in a >>>> couple of places. >>>> >>>> I'm actually not sure why you saw a class cast exception with >>>> Option >>>> 1 before my fix. Copying the relevant text here: >>>> >>>> >>>>>> 1. I tried to implement the forwarding as it was >>>> already done >>>> >>>>>> by the old servlet using: >>>> >>>>>> >>>> >>>>>> @Context >>>> >>>>>> private ServletContext context; >>>> >>>>>> >>>> >>>>>> context.getRequestDispatcher(url).forward(request, >>>> response); >>>>>> >>>>>> But this does not work, because of a >>>> ClassCastException happening. >>>> >>>>>> The exception message was like: The ThreadLocal instance >>>> for >>>>>> ServletContext could not be casted to the >>>> RequestDispatcher >>>>>> instance, which is provided by the server. >>>> (NetWeaver) >>>>>> >>>>>> The ThreadLocal object is provided by >>>> CXF and the >>>>>> RequestDispatcher implementation is provided by >>>> NetWeaver. Of >>>>>> course, this will not work. >>>> >>>> I'm not sure I understand to be honest. The thread local object >>>> provided by CXF keeps current ServletContext objects (created by >>>> NetWeaver I assume). So the runtime will do >>>> >>>> threadLocal.put(currentServletContext) >>>> >>>> and then >>>> >>>> context.getRequestDispatcher(url) >>>> >>>> is effectively >>>> >>>> ((ServletContext)threadLocal.get()).getRequestDispatcher(url) >>>> >>>> so I'm not sure where ClassCastException is coming from... >>>> >>>> Please investigate on your end by debugging the code... >>>> >>>> Cheers, Sergey >>>> >>>> >>>> >>>> >>>> On 09/04/15 07:24, Voss, Marko wrote: >>>>> Hi Sergey, >>>>> >>>>> yes, we use a 2.7.x CXF version. I think, that is because of the >>>>> old NetWeaver server we have to use. Can you please fix this for >>>>> 2.7.16 as well? Thank you very much. :-) >>>>> >>>>> >>>>> Best regards, >>>>> Marko >>>>> >>>>> -----Ursprüngliche Nachricht----- >>>>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] >>>>> Gesendet: Mittwoch, 8. April 2015 18:59 >>>>> An: users@cxf.apache.org >>>>> Betreff: Re: AW: AW: AW: How to forward requests to a JSP page >>>>> when using CXFNonSpringJaxrsServlet >>>>> >>>>> Hi Marko >>>>> >>>>> See https://issues.apache.org/jira/browse/CXF-6337 >>>>> >>>>> Can you please test either 3.0.5-SNAPSHOT or 3.1.0-SNAPSHOT ? >>>>> Do you need it for CXF 2.7.16 ? >>>>> >>>>> Sergey >>>>> >>>>> On 08/04/15 13:31, Sergey Beryozkin wrote: >>>>>> Hi Marko >>>>>> >>>>>> That should be possible to get fixed. >>>>>> As I said, the query parameters are passed along either way but >>>>>> if you can not modify JSP or these query parameters are actually >>>>>> representing some custom parameters, then yes, I can see why >>>>>> option >>>>>> 1 makes sense. >>>>>> >>>>>> By the way, RequestDispatcher supports dynamic resource paths set >>>>>> on the message context, so if you have CXF MessageContext >>>>>> injected then you'd set a property on it, >>>>>> >>>>>> "redirect.resource.path"="my.jsp?a=b" >>>>>> >>>>>> and it will work, but it is very much CXF specific.... >>>>>> >>>>>> I'll try to get option 1 done before the releases... >>>>>> >>>>>> Cheers, Sergey >>>>>> >>>>>> On 08/04/15 13:13, Voss, Marko wrote: >>>>>>> Hi Sergey, >>>>>>> >>>>>>> yes, it would be great, if variant 1 would work fine. (No >>>>>>> ClassCastException) >>>>>>> >>>>>>> servletContext.getRequestDispatcher("my.jsp?a=b").forward() >>>>>>> >>>>>>> >>>>>>> Is it possible to fix this? >>>>>>> >>>>>>> >>>>>>> Best regards, >>>>>>> Marko >>>>>>> >>>>>>> >>>>>>> -----Ursprüngliche Nachricht----- >>>>>>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] >>>>>>> Gesendet: Mittwoch, 8. April 2015 14:07 >>>>>>> An: users@cxf.apache.org >>>>>>> Betreff: Re: AW: AW: How to forward requests to a JSP page when >>>>>>> using CXFNonSpringJaxrsServlet >>>>>>> >>>>>>> Hi >>>>>>> >>>>>>> Not at the moment, how does it work in general, is it >>>>>>> >>>>>>> servletContext.getRequestDispatcher("my.jsp?a=b").forward() ? >>>>>>> >>>>>>> Note that RequestDispatcherProvider sets query parameters (as >>>>>>> well as path and other request properties) as HttpServletRequest >>>>>>> parameters, see >>>>>>> >>>>>>> https://fisheye6.atlassian.com/browse/cxf/rt/frontend/jaxrs/src/ >>>>>>> m >>>>>>> ai >>>>>>> n >>>>>>> / >>>>>>> java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.jav >>>>>>> a >>>>>>> ?r >>>>>>> = >>>>>>> 3 >>>>>>> 309231e467225b18b24d90d77153a0c572a17e0#to342 >>>>>>> >>>>>>> >>>>>>> Cheers, Sergey >>>>>>> >>>>>>> On 08/04/15 12:37, Voss, Marko wrote: >>>>>>>> Hi Sergey, >>>>>>>> >>>>>>>> can I somehow tell the RequestDispatcher to use the String of >>>>>>>> the Response Entity for redirection? Just saw, that there are >>>>>>>> also query parameters added to the JSP URL in some cases... >>>>>>>> >>>>>>>> >>>>>>>> Thanks and best regards, >>>>>>>> Marko >>>>>>>> >>>>>>>> -----Ursprüngliche Nachricht----- >>>>>>>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] >>>>>>>> Gesendet: Mittwoch, 8. April 2015 13:03 >>>>>>>> An: users@cxf.apache.org >>>>>>>> Betreff: Re: AW: How to forward requests to a JSP page when >>>>>>>> using CXFNonSpringJaxrsServlet >>>>>>>> >>>>>>>> Hi Marko >>>>>>>> >>>>>>>> This is one way to do it, yes, does not even has to be on the >>>>>>>> same line, example, >>>>>>>> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider >>>>>>>> ( >>>>>>>> resource.Status.JSP1=/hello.jsp resource.Status.JSP2=/foo.jsp >>>>>>>> ) >>>>>>>> >>>>>>>> Perhaps another alternative is to wrap an enum value into a >>>>>>>> bean class and redirect to a single JSP resource, which will >>>>>>>> get the bean, check the enum, delegate to specific JSPs... >>>>>>>> >>>>>>>> Cheers, Sergey >>>>>>>> >>>>>>>> On 08/04/15 06:47, Voss, Marko wrote: >>>>>>>>> Hello Sergey, >>>>>>>>> >>>>>>>>> variant 2 was just an idea but is not really helpful, because >>>>>>>>> of we need to do some logic in order to decide, which JSP to call. >>>>>>>>> So we have to execute some code. >>>>>>>>> >>>>>>>>> So the idea I got is the following: The servlet does execute >>>>>>>>> the code and returns an enum value. Based on the enum value, >>>>>>>>> the RequestDispatcher decides, which JSP to call. This might >>>>>>>>> look like >>>>>>>>> this: >>>>>>>>> >>>>>>>>> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider(resource. >>>>>>>>> S >>>>>>>>> t >>>>>>>>> at >>>>>>>>> u >>>>>>>>> s.JSP1=/hello.jsp >>>>>>>>> resource.Status.JSP2=/foo.jsp) >>>>>>>>> >>>>>>>>> The Response object gets the enum value as its entity. >>>>>>>>> >>>>>>>>> Is this correct? >>>>>>>>> >>>>>>>>> >>>>>>>>> Thank you very much and best regards, >>>>>>>>> >>>>>>>>> Marko >>>>>>>>> >>>>>>>>> -----Ursprüngliche Nachricht----- >>>>>>>>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] >>>>>>>>> Gesendet: Dienstag, 7. April 2015 17:40 >>>>>>>>> An: users@cxf.apache.org >>>>>>>>> Betreff: Re: How to forward requests to a JSP page when using >>>>>>>>> CXFNonSpringJaxrsServlet >>>>>>>>> >>>>>>>>> Hi, >>>>>>>>> >>>>>>>>> Please see comments below >>>>>>>>> On 07/04/15 14:42, Voss, Marko wrote: >>>>>>>>>> Hello, >>>>>>>>>> >>>>>>>>>> I do have the following situation: >>>>>>>>>> >>>>>>>>>> We have to use the CXFNonSpringJaxrsServlet for implementing >>>>>>>>>> the REST endpoints. >>>>>>>>>> >>>>>>>>>> The main servlet (old code to be replaced by the new REST >>>>>>>>>> endpoints) of the application does implement internal >>>>>>>>>> forwarding to JSP pages. >>>>>>>>>> (for example to a login page) >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> 1. I tried to implement the forwarding as it was already done >>>>>>>>>> by the old servlet using: >>>>>>>>>> >>>>>>>>>> @Context >>>>>>>>>> private ServletContext context; >>>>>>>>>> >>>>>>>>>> context.getRequestDispatcher(url).forward(request, response); >>>>>>>>>> >>>>>>>>>> But this does not work, because of a ClassCastException happening. >>>>>>>>>> The exception message was like: The ThreadLocal instance for >>>>>>>>>> ServletContext could not be casted to the RequestDispatcher >>>>>>>>>> instance, which is provided by the server. (NetWeaver) >>>>>>>>>> >>>>>>>>>> The ThreadLocal object is provided by CXF and the >>>>>>>>>> RequestDispatcher implementation is provided by NetWeaver. Of >>>>>>>>>> course, this will not work. >>>>>>>>> Hmm, interesting, may make sense supporting this variation, >>>>>>>>> I'll have a look... >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> 2. I was trying to use the RequestDispatcherProvider of CXF, >>>>>>>>>> but how can you configure this provider using the >>>>>>>>>> CXFNonSpringJaxrsServlet? >>>>>>>>>> >>>>>>>>>> <servlet> >>>>>>>>>> <servlet-name>RestfulApp</servlet-name> >>>>>>>>>> >>>>>>>>>> <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrs >>>>>>>>>> S >>>>>>>>>> er >>>>>>>>>> v >>>>>>>>>> l >>>>>>>>>> et</servlet-class> >>>>>>>>>> >>>>>>>>>> <init-param> >>>>>>>>>> >>>>>>>>>> <param-name>jaxrs.serviceClasses</param-name> >>>>>>>>>> <param-value> >>>>>>>>>> ... >>>>>>>>>> </param-value> >>>>>>>>>> </init-param> >>>>>>>>>> <init-param> >>>>>>>>>> >>>>>>>>>> <param-name>jaxrs.providers</param-name> >>>>>>>>>> <param-value> >>>>>>>>>> >>>>>>>>>> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider >>>>>>>>>> <!-- How to configure this one >>>>>>>>>> here??? --> >>>>>>>>>> </param-value> >>>>>>>>>> </init-param> >>>>>>>>>> <load-on-startup>1</load-on-startup> >>>>>>>>>> </servlet> >>>>>>>>>> >>>>>>>>> >>>>>>>>> The simplest way to do at a servlet level is to use redirect >>>>>>>>> parameters, see >>>>>>>>> >>>>>>>>> https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=sys >>>>>>>>> t >>>>>>>>> es >>>>>>>>> t >>>>>>>>> s >>>>>>>>> /j >>>>>>>>> a >>>>>>>>> xrs/src/test/resources/jaxrs_dispatch/WEB-INF/web.xml;h=a22123 >>>>>>>>> 3 >>>>>>>>> 7b >>>>>>>>> d >>>>>>>>> 6 >>>>>>>>> a9 >>>>>>>>> e >>>>>>>>> d7a212b21a6826850581601121;hb=HEAD >>>>>>>>> >>>>>>>>> or indeed you can directly configure this provider (and other >>>>>>>>> providers) as a parameter, do something like >>>>>>>>> >>>>>>>>> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider(resour >>>>>>>>> c >>>>>>>>> eP >>>>>>>>> a >>>>>>>>> t >>>>>>>>> h= >>>>>>>>> / >>>>>>>>> WEB-INF/jsp/test.jsp >>>>>>>>> someotherproperty=somevalue) >>>>>>>>> >>>>>>>>> >>>>>>>>>> >>>>>>>>>> 3. I was trying to implement a RequestHandler, which worked >>>>>>>>>> but when the forwarding happens, I get spammed by error >>>>>>>>>> messages on server side, that the OutputStreams of the >>>>>>>>>> servlets are already taken by a getWriter() method. This spam >>>>>>>>>> should be avoided. >>>>>>>>>> Example >>>>>>>>>> Spam: >>>>>>>>>> >>>>>>>>>> WARNING: Interceptor for >>>>>>>>>> {http://impl.jaxrs.web.foo.bar/}MyServiceImpl has thrown >>>>>>>>>> exception, unwinding now >>>>>>>>>> com.sap.engine.services.servlets_jsp.server.exceptions.WebIllegalStateException: >>>>>>>>>> >>>>>>>>>> The stream has already been taken by method [getWriter()]. >>>>>>>>>> at >>>>>>>>>> com.sap.engine.services.servlets_jsp.server.runtime.client.Ht >>>>>>>>>> t >>>>>>>>>> pS >>>>>>>>>> e >>>>>>>>>> r >>>>>>>>>> vl >>>>>>>>>> e >>>>>>>>>> tResponseFacade.getOutputStream(HttpServletResponseFacade.jav >>>>>>>>>> a >>>>>>>>>> :2 >>>>>>>>>> 4 >>>>>>>>>> 4 >>>>>>>>>> ) >>>>>>>>>> >>>>>>>>>> This servlet is not in use at all at this point of the >>>>>>>>>> request and not after the request as well. So I wonder in >>>>>>>>>> general, why this exception occurs on this servlet. It is >>>>>>>>>> maybe a NetWeaver thing. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> 4. I was trying to implement an equivalent to the >>>>>>>>>> RequestDispatcherProvider, doing things here by code. But >>>>>>>>>> even when this works, I still get the spam from above. >>>>>>>>>> >>>>>>>>> In both cases the outbound CXF JAX-RS interceptor and Http >>>>>>>>> transport need to know the request has been redirected, this >>>>>>>>> can be done by setting an "http.request.redirected" property >>>>>>>>> on the current message, >>>>>>>>> >>>>>>>>> message.put("http.request.redirected", true) >>>>>>>>> >>>>>>>>> But the option 2 is simpler, can you try it and let me know if >>>>>>>>> it works for you ? >>>>>>>>> >>>>>>>>> Thanks, Sergey >>>>>>>>> >>>>>>>>>> >>>>>>>>>> Any help is much appreciated. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Best regards, >>>>>>>>>> >>>>>>>>>> Marko >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>>> >>>>> -- >>>>> Sergey Beryozkin >>>>> >>>>> Talend Community Coders >>>>> http://coders.talend.com/ >>>>> >>>>> Blog: http://sberyozkin.blogspot.com >>>>> >>>> >>> >> >