-
1. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
asookazian Nov 15, 2009 5:55 AM (in response to luxspes)Good question, but I have a feeling you must use the Servlet API...
-
2. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
nickarls Nov 15, 2009 7:42 AM (in response to luxspes)@Produces HttpServletRequest getRequest() { return FacesContext....
-
3. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
gavin.king Nov 15, 2009 8:09 AM (in response to luxspes)Write a servlet filter that binds these objects to the current thread, at the beginning of the request, and cleans them up at the end of the request.
Are you seriously using, in 2009, a web framework that makes it good practice to access these objects directly??
-
4. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
nickarls Nov 15, 2009 10:30 AM (in response to luxspes)OK, that it of course more clean but sometimes I can live with myself if I do a quick and dirty look at some request header by accessing it directly ;-)
-
5. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
luxspes Nov 15, 2009 2:57 PM (in response to luxspes)
Nicklas Karlsson wrote on Nov 15, 2009 07:42:@Produces HttpServletRequest getRequest() { return FacesContext....
Thanks, but remember, no JSF for me ( in the weekend ;-) )...
-
6. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
luxspes Nov 15, 2009 3:06 PM (in response to luxspes)
Gavin King wrote on Nov 15, 2009 08:09:
Write a servlet filter that binds these objects to the current thread, at the beginning of the request, and cleans them up at the end of the request.Yes, that is what I thought, but I was hoping that your would tell me that Weld already had such a filter included... or that I could use a @Produces inside the filter to expose this... or I don't know, some kind of
Weldish
solution for this... ;-)
Are you seriously using, in 2009, a web framework that makes it good practice to access these objects directly??I am trying to port Numberguess to JSP using only what is available in: Weld+Tomcat6(Servlets/JSP)+JSTL+Scala I guess I am trying to create a very basic equivalent
of Spring-MVC... but hopefully more elegant because it will be Weld based ;-) -
7. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
gavin.king Nov 15, 2009 4:55 PM (in response to luxspes)We're trying to discourage direct access to these objects from beans. We think it's better if your web framework acts as an intermediating layer here. But, of course, it's easy to write a servlet filter and a producer method (or portable extension) that makes these objects available for injection.
But, I personally would keep direct access to HttpServletRequest and friends inside the servlet. Remember that with CDI, you won't be needing to get and set request, session and application attributes directly, except in special circumstances.
-
8. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
luxspes Nov 15, 2009 5:29 PM (in response to luxspes)Mmmm.... but, imagen you were given the restriction of using Weld+Tomcat6(Servlets/JSP)+JSTL, and no scriptlet code in you JSPs and you want to process the values of a form submit... the only way to reach the values that were submitted in the from is with direct access to HttpServletRequest...
I mean, I basically I need to reinvent something like the @RequestParam annotation of Seam, and there is no way I can do that without direct access to HttpServletRequest... -
9. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
gavin.king Nov 15, 2009 6:18 PM (in response to luxspes)Well, if you're coding directly to the servlet API, you have access to the HttpServletRequest in the HttpServlet.doXxxx() methods. Do you really want to propagate the dependency to that very technical interface deeper into your business logic? It's something that I would personally try to avoid.
Look, what I'm really trying to say is that this is a line-drawing problem between what is provided built-in to the spec, and what is provided by portable extensions. Right now, no portable extensions exist. In a couple of months I will be able to point you to an easily downloadable jar which has this and plenty more.
Now, perhaps we got the line sightly wrong first time around - people are already yelling at me for not supporting injection of FacesContext out-of-the-box - and if so, we can fix it by adding a couple more objects to the list in section 3.6 of the spec. But I did not want to bloat out the spec in the very first release.
-
10. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
luxspes Nov 15, 2009 6:46 PM (in response to luxspes)
Gavin King wrote on Nov 15, 2009 18:18:
Well, if you're coding directly to the servlet API, you have access to the HttpServletRequest in the HttpServlet.doXxxx() methods. Do you really want to propagate the dependency to that very technical interface deeper into your business logic? It's something that I would personally try to avoid.I agree, but remember, I am not writing only business logic, I creating a mini
Weld-MVC
... Maybe what I should do is bind HttpServletRequest to a thread local variable in filter (as you suggested) and then write a @Produces method that exposes the form values as a java.util.Map to my org.jboss.weld.examples.numberguess.Game component?
Look, what I'm really trying to say is that this is a line-drawing problem between what is provided built-in to the spec, and what is provided by portable extensions.Guess I am writing a mini-portable extensions inside my NumberGuessJPS to to try and
hide
this details from Game (but in order to hide those details from Game I need to work with them somewhere else)
Right now, no portable extensions exist.So I am the first creating one? Whoooa! :-)
In a couple of months I will be able to point you to an easily downloadable jar which has this and plenty more.Or maybe I will be able to point you to mine ;-)
Now, perhaps we got the line sightly wrong first time around - people are already yelling at me for not supporting injection of FacesContext out-of-the-box - and if so, we can fix it by adding a couple more objects to the list in section 3.6 of the spec.No no, I think the less Weld does, and the more is left to external plugins the better. One thing I did not like about Seam was precisely that for non experts like me it was really hard to draw the line between
Core Seam
andSeam-Everything-Else
. But since Weld has some minorexternal contamination
(for example the ConversationScope source has a comment in source saying it only works for JSF) I was afraid of creating an extension to reach the form values from my component only to find out later that one was already included inside Weld.
But I did not want to bloat out the spec in the very first release.Please do not bloat it ever, remember:
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
. The more specific and to the core is the spec, the better. -
11. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
luxspes Nov 15, 2009 6:55 PM (in response to luxspes)As a first step, I tried writing a @Produces method that produces a ServletRequest:
@RequestScoped class ServletContexts extends Serializable{ @Produces @Request def getServletRequest()={ ServletContexts.getServletRequest() } @Produces @Response def getServletResponse()={ ServletContexts.getServletResponse() } } object ServletContexts { private var threadLocalRequest = new ThreadLocal[ServletRequest](); private var threadLocalResponse = new ThreadLocal[ServletResponse](); def getServletRequest()={ threadLocalRequest.get() } def setServletRequest(request:ServletRequest) { if (request == null) { threadLocalRequest.remove(); } threadLocalRequest.set(request); } def getServletResponse()={ threadLocalResponse.get() } def setServletResponse(response:ServletResponse) { if (response == null) { threadLocalResponse.remove(); } threadLocalResponse.set(response); } }
and then inject that at my Game class:
private var request:HttpServletRequest=null; @Inject def setRequest(@Request newRequest:ServletRequest){ request=newRequest.asInstanceOf[HttpServletRequest]; }
but I got this error:
WELD-000055 Producers cannot produce non-serializable instances for injection into parameters of initializers of beans declaring passivating scope.\\n\\nBean\: org.jboss.weld.bean-flat-ProducerMethod-org.jboss.weld.examples.common.ServletContexts.getServletRequest()\\nInjection Point\: parameter 0 of method public void org.jboss.weld.examples.numberguess.Game.setRequest(javax.servlet.ServletRequest)
Apparently I can not inject ServletRequest in to Game because Game is SessionScoped and that is a passivating scope. What should I be doing then?
-
12. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
gavin.king Nov 15, 2009 7:05 PM (in response to luxspes)Try:
class ServletContexts { @Produces @RequestScoped @Request def getServletRequest()={ ServletContexts.getServletRequest() } @Produces @RequestScoped @Response def getServletResponse()={ ServletContexts.getServletResponse() } }
You see why you need to do that, right?
-
13. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
luxspes Nov 15, 2009 7:24 PM (in response to luxspes)Mmm, but it is:
@RequestScoped class ServletContexts { }
if I already have @RequestScoped for all the ServletContexts class, why do I need to add it to the @Produces methods...
-
14. Re: How to reach HttpServletRequest and HttpServletResponse from bean?
luxspes Nov 15, 2009 7:56 PM (in response to luxspes)Well, it did make a difference, I guess I need @Produces @RequestScoped @Response to indicate that what is being returned by getServletResponse() will be RequestScoped... no more WELD-000055 error for me... but maybe I have hit a Weld/Scala incompatibility?:
java.lang.RuntimeException: by java.lang.NoClassDefFoundError: javassist/util/proxy/ProxyObject javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:344) javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:314) javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:273) org.jboss.weld.util.Proxies.createProxyClass(Proxies.java:153) org.jboss.weld.util.Proxies.createProxy(Proxies.java:136) org.jboss.weld.bean.proxy.ClientProxyProvider.createClientProxy(ClientProxyProvider.java:81) org.jboss.weld.bean.proxy.ClientProxyProvider.access$000(ClientProxyProvider.java:45) org.jboss.weld.bean.proxy.ClientProxyProvider$1.call(ClientProxyProvider.java:114) java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) java.util.concurrent.FutureTask.run(FutureTask.java:138) org.jboss.weld.util.collections.ConcurrentCache.putIfAbsent(ConcurrentCache.java:125) org.jboss.weld.bean.proxy.ClientProxyProvider.getClientProxy(ClientProxyProvider.java:104) org.jboss.weld.BeanManagerImpl.getReference(BeanManagerImpl.java:949) org.jboss.weld.BeanManagerImpl.getReference(BeanManagerImpl.java:1019) org.jboss.weld.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:1041) org.jboss.weld.injection.ParameterInjectionPoint.getValueToInject(ParameterInjectionPoint.java:93) org.jboss.weld.injection.MethodInjectionPoint.getParameterValues(MethodInjectionPoint.java:268) org.jboss.weld.injection.MethodInjectionPoint.invoke(MethodInjectionPoint.java:105) org.jboss.weld.util.Beans.callInitializers(Beans.java:753) org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:740) org.jboss.weld.bean.ManagedBean$1$1.proceed(ManagedBean.java:219) org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:51) org.jboss.weld.bean.ManagedBean$1.inject(ManagedBean.java:213) org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:141) org.jboss.weld.context.AbstractMapContext.get(AbstractMapContext.java:108) org.jboss.weld.bean.proxy.ClientProxyMethodHandler.getProxiedInstance(ClientProxyMethodHandler.java:143) org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:101) org.jboss.weld.examples.numberguess.Game_$$_javassist_0.getMessage(Game_$$_javassist_0.java) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) javax.el.BeanELResolver.getValue(BeanELResolver.java:62) javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53) org.apache.el.parser.AstValue.getValue(AstValue.java:118) org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:925) org.apache.jsp.home_jsp._jspx_meth_c_005fout_005f0(home_jsp.java:136) org.apache.jsp.home_jsp._jspService(home_jsp.java:83) org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) javax.servlet.http.HttpServlet.service(HttpServlet.java:717) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267) javax.servlet.http.HttpServlet.service(HttpServlet.java:717) org.jboss.weld.examples.common.WeldFilter.doFilter(WeldFilter.scala:25)
I mean, the javassist/util/proxy/ProxyObject is obviusly there, inside weld-servlet.jar...
This is what I have in my WEB-INF\lib dir:
15/11/2009 12:30 p.m. <DIR> . 15/11/2009 12:30 p.m. <DIR> .. 13/11/2009 06:58 a.m. 20,682 jstl.jar 13/11/2009 11:42 p.m. 269,699 scala-dbc.jar 13/11/2009 11:42 p.m. 3,789,991 scala-library.jar 13/11/2009 11:42 p.m. 623,359 scala-swing.jar 13/11/2009 06:58 a.m. 393,259 standard.jar 11/11/2009 10:24 p.m. 4,479 weld-api.jar 11/11/2009 10:24 p.m. 551,470 weld-core.jar 11/11/2009 10:24 p.m. 3,915 weld-logger.jar 11/11/2009 10:24 p.m. 20,700 weld-se.jar 11/11/2009 10:24 p.m. 28,712 weld-servlet-int.jar 11/11/2009 10:24 p.m. 2,052,123 weld-servlet.jar 11/11/2009 10:24 p.m. 50,674 weld-spi.jar 11/11/2009 10:24 p.m. 10,156 weld-tomcat-support.jar