How to Generate an ELContext without an active FacesContext? - java

I need to get access to EL functionality in a Servlet Filter, but... that means I am not within the FacesServlet lifecycle.
Thus, I need to instantiate an ELContext. I do not want to go down the road of instantiating a FacesContext, since that may cause issues when the application does forward to FacesServlet.
Suggestions? Thanks!

Better use a PhaseListener instead of a Filter.

Since I am writing a web-framework, there is no way to use a PhaseListener, this must be done inside the Servlet Filter.
However, I did find the solution in the Seam Solder (WeldX) CDI module - this only works when running on CDI.
http://docs.jboss.org/weld/extensions/reference/latest/en-US/html/elextensions.html

I'm not sure it makes sense to do this. Within a JSP context, you would be able to resolve JSP artefacts; within a JSF context, you would be able to resolve JSF artefacts. In a Filter, these artefacts are not going to be available to you.
If you just want to resolve expressions against objects you define, it is possible to create your own context (you may need to know the platform's ExpressionFactory class if you also want to create expressions).
There is probably a better way to achieve whatever it is you are doing, such as BalusC's suggestion of a PhaseListener.

Related

FileServlet + call bean function

I'm using BalusC's FileServlet example:
http://balusc.blogspot.com/2007/07/fileservlet.html
I'm able to get it to work, however, I would like to call a bean function before the download takes place. Is there a way to make that work? I tried with a4j:support and I also tried with h:commandLink and neither worked. Any help is appreciated!
You could do the file download job in bean's action method instead. For some concrete examples, see this answer: How to provide a file download from a JSF backing bean?
You only need to make sure that the request isn't made by Ajax, because the JavaScript language, who is responsible for handling the Ajax request, does not have any facilities to force a Save As dialogue for security reasons. So, use a plain <h:commandLink> or <h:commandButton> for this.

Routing sub-paths with Guice servlets

I'm using Guice to route requests in my web app, and I'd like to modularize the routing of some of the URL patterns I'll be handling. Ideally, I'd like to be able to do something like this in my ServletModule:
delegate("/foo/bar/*").to(SomeOtherServletModule.class);
// in SomeOtherServletModule.configureServlets:
serve("/foo/bar/quux").with(Quux.class);
Or even better:
delegatePrefix("/foo/bar/").to(SomeOtherServletModule.class);
// in SomeOtherServletModule.configureServlets:
serve("/quux").with(Quux.class); // prefix removed
Is this possible in Guice? It seems that Guice tries really hard to make the bindings installed by ServletModules a singleton, which is in turn stored who-knows-where by GuiceServletContextListener to be used by GuiceFilter, but I'd like to un-singleton this so I can delegate like this, instead of having everything tightly bound in a single function.
I am the creator of Guice Servlet. This is basically not allowed as you are describing, as we felt it would be confusing for modules that are not intended to be used this way.
For example, many modules contribute filters that register at "/*" to provide some interception functionality (such as transactions). These could accidentally stop working if you auto-prefixed them. Given that servlet modules can be transitively installed, this is not as simple as being vigilant about one piece of code. Also, with regex bindings (example: /\.html$/), how does one handle prefixes? Do we support them (difficult problem)? Or do we simply register regex bindings normally and make a surprising exception for them?
Considering that what you're asking for is trivially achieved with a constructor in SomeOtherServletModule("/myprefix") that knows how to map itself correctly, we decided not to provide this functionality.

It is possible to call a servlet from a Java class?

I'm using IBM WebSphere as my servlet container. My application has several servlets and Java classes. My intent is to call one of those servlets directly from a Java class. Doing some research I figured out that is possible to use the RequestDispatcher interface to achieve this. But it is necessary to pass the objects ServletRequest and ServletResponse as arguments to the method forward(). There is some way to bypass this safely and "nicely"? By "nicely" I meant to say preserving good programming and design patterns.
The only way to do this nicely is to decouple the desired logic from the servlets. This requirement is a sign that the servlets are too tight coupled with business/domain code logic which apparently needs to be used as well outside the webapplication context.
Refactor the original servlet code into reuseable Java class(es) and method(s) (which in turn does not use anything from the javax.servlet package) so that you can finally import and invoke it from both the servlet class and the "plain vanilla" Java class.
It would help to get some more background as to why you are trying to do this. I am assuming you want to invoke some piece of business logic in the servlet. This is a sign that the application is poorly designed.
Are you familiar with MVC architecture? If your "model" code was loosely coupled, you would be able to call it directly.
You could write a filter that stores the current request and response in static ThreadLocal, so that you can use them later from within the same request. You can then implement your own static method forward that uses them and dispatch to another page.
This is somehow the approach taken in JSF where FacesContext.getCurrentInstance can be accessed anytime.
But I wouldn't qualify that as an elegant design. Rather try to follow #BalusC advice and refactor your logic.

Get the HttpServletRequest (request) object from Java code

I need to get hold of the request object in Java code. I can't pass this object down to my code for certain reasons. Is there any way I can say something like: getCurrentHTTPServletRequest?
It is safe for me to assume that I am in a Servlet Context.
Well you should pass it down if you need it. Anything else you do is going to be ugly, basically.
You could use a ThreadLocal variable - basically set the context for that particular thread when you get the request, and then fetch it later on. That will work so long as you only need to get at the request within the thread that's processing it - and so long as you don't do any funky asynchronous request handling. It's brittle though, for precisely those reasons.
However, I would strongly advise you to be explicit about your dependencies instead. Either pass the servlet request down, or just the bits that you need.
Assuming you're not able to pass the request object down the call stack, then some kind of sharing mechanism becomes necessary, which is not ideal, but sometimes necessary.
Spring provides the RequestContextFilter for just this purpose. It uses ThreadLocal, and allows the code to fetch the current request via RequestContextHolder. Note that this filter does not require you to use any other part of Spring:
Servlet 2.3 Filter that exposes the
request to the current thread, through
both LocaleContextHolder and
RequestContextHolder. To be registered
as filter in web.xml.
This filter is mainly for use with
third-party servlets, e.g. the JSF
FacesServlet. Within Spring's own web
support, DispatcherServlet's
processing is perfectly sufficient.
If you're going to use ThreadLocal, then better to use an existing, working solution, rather than risk bugs creeping in, which ThreadLocal code is prone to.
Jon Skeet said practically everything, but one clarification to his advice "just the bits that you need" - if you need your request parameters passed down, but you don't need a dependency on HttpServletRequest, pass request.getParameterMap().
And extending a bit on the ThreadLocal option - you can have a Filter which handles all incoming requests, and sets the request in a
public final static ThreadLocal<HttpServletRequest> httpServletRequestTL =
new ThreadLocal<HttpServletRequest>();
Because you are setting it on each request (careful with the filter mapping), you won't have to worry about the servlet-container thread pool - you will always have the current request.
P.S. this is the logic behind the spring utility proposed by skaffman - I join him recommending the stable component, rather than making your own.
There is no servlet API to do this. However, Tomcat does provide an API call to do this,
HttpServletRequest request = (HttpServletRequest)org.apache.catalina.core.ApplicationFilterChain.getLastServicedRequest();
This will get the last request passed to a servlet for servicing from the current thread.
For this to work, the Tomcat must be in "Strict Servlet Compliance" mode. If not, you need to enable it by adding this JVM parameter:
org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true
Assuming the top-level servlet really is taboo for some crazy business-related reason, there is still the option of defining a ServletFilter to pre-view the request and stuff it into a ThreadLocal. Assuming that the web.xml is not also sacrosanct.
But I agree with Jon Skeet in that this would be very ugly. I'd code this up and then try to find a different job. :)
Actually, given the fact that a filter can totally wrest away control from the receiving servlet, you could use this technique to divert the code to a servlet of your own, do whatever you want, and THEN run the other, "official" servlet... or anything else along those lines. Some of those solutions would even allow you to deal correctly and robustly with your request data.

In what case would a programmer get the webApplicationContext out of DispatchServlet?

I notice that there is getWebApplicationContext in org.springframework.web.servlet.mvc.AbstractController. This means that spring programmers can use getWebApplicationContext to access beans in the spring IoC container.
However, I never see people use this way to get beans in all the spring MVC tutorials. So here comes my question, in that case would a programmer want to get the WebApplicationContext?
That's an odd question... are you asking why a method is in the API if none of the tutorials use it? Do you expect every API method to be in the tutorials?
The getWebApplicationContext() method is rarely used by application code, but it is used internally by Spring for some tasks.
In some cases when you implement org.springframework.web.servlet.View a call to getWebApplicationContext can be useful to get access to Spring beans that can not (or should not) be passed along in the Model object.
You also might need it when implementing custom JSP tags to access Spring Beans e.g. But this is usually a method you try to avoid from application code.

Categories