I'm using Stripes 1.5 and I was using a interceptor (based on this example) to prevent unauthorized access to *.action pages.
Now I want to use the same interceptor to prevent access to a servlet.
I've added this this to web.xml (DisplayChart is the servlet I want to protect):
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<servlet-name>DisplayChart</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
But it doesn't work, the interceptor intercept method doesn't execute when accesing the DisplayChart servlet path (even if I #Intercepts all the LifeCycleStage).
Is there a way to a interceptor to execute when another servlet is accesed? Or Stripes filters are not intended to be used that way (and I'll have to use a plain Filter)?
I don't know if you can apply a Stripes interceptor to a non-Stripes servlet.
But i am pretty sure you shouldn't.
The Stripes interceptors are specific to Stripes, and Stripes's request lifecycle. A request to a plain servlet is not a Stripes request, and does not go through this lifecycle, even if it goes through the Stripes filter. Such a request should not use a Stripes interceptor, even if this is possible.
I suggest you factor out the authorization code from your Stripes interceptor into a Stripes-agnostic service class, then write a standard filter which uses that class. Your Stripes interceptor and your filter are then very small bits of code which hand off to the service.
The Stripes filter can't be used like that, as the Stripes filter is actually the Stripes front controller that dispatches only to action beans and possible an Stripes interceptor before that.
So as you already assumed, you need a regular servlet filter.
Related
Does anyone has an idea, how to handle filters correctly within an Jersey-2.x application when using RequestDispatcher.forward()?
RequestDispatcher dispatcher=pCtx.getRequestDispatcher("/app2");
dispatcher.forward(request, response);
When I do a forward between two webapps, both using Jersey-2.5+, the webapp that is being redirected to, contains request filters. They should be invoked when doing the forward (like when requesting the app directly) but are not.
Several post do outline to use the <filter-mapping> element with the <dispatcher> tag in the web.xml, like here. But this looks to me like javax servlet filters and I am not sure how to include this, if ever possible.
Is there a way to achieve the same with Jersey-2.x filters?
UPDATE:
My ContainerRequestFilters are post-matching filters, as they are not annotated with #PreMatching
As I found out, the RequestFilters are actually invoked. I didn't recognise that by mistake. What really is not invoked, is tomcat container authentication like a realm. But this is clear to me, as we already passed tomcat layer when the request is processed by any application.
I'm investigating a Spring Boot project generated by JHipster and found out that its request mappings aren't done via web.xml nor via Spring's #RequestMapping but like so:
ServletRegistration.Dynamic someServlet =
servletContext.addServlet("someServlet", new SomeServlet());
someServlet.addMapping("/someUrl");
someServlet.setAsyncSupported(true);
My questions are:
Are there any reasonable advantages of dynamic registration instead of classic mapping?
Is it spring-boot's standard of registering mappings or it's just a will of jhipster's owner?
Is someServlet.setAsyncSupported(true) just another way of making response.setHeader("Access-Control-Allow-Origin", "*")?
Is there any reasonable advantages of dynamic registration instead of classic mapping?
Dynamic servlet registration Servlet 3+ way of registering servlets. In Servlets 3 you can avoid creating web.xml and configure application in pure Java. It gives you some advantages like compile time check if everything is fine there and what's more important since you do it in Java code, you can do some additional checks or conditions - for example register particular servlet only if environment property is set or class is available on the classpath.
It's not a replacement for #RequestMapping. In case of Spring Boot you will use it most probably when you want to register some 3rd party servlet - like Dropwizard Metrics servlet in case of JHipster.
Is it spring-boot's standard of registering mappings or it's just a will of jhipster's owner?
There are at least 2 ways of registering additional servlets in Spring Boot. See answers here: How can I register a secondary servlet with Spring Boot?.
Your own controllers you map as usual with #RequestMapping.
Is someServlet.setAsyncSupported(true) just another way of making response.setHeader("Access-Control-Allow-Origin", "*")?
Nope. For setting this header you use usually CORSFilter (read more: Enabling Cross Origin Requests for a RESTful Web Service). asyncSupported flag is used to make servlet able to process request asynchronously.
I want to know basically what a Jersey filter is and how is it related to a servlet filter? Are they the same? What are the main patterns of using a Jersey Filter?
Technically, a Jersey filter is not a servlet filter. However, you can use a Jersey filter for many of the same things that you would use a servlet filter for - cross-cutting concerns that affect all (or some, or most) the services that Jersey exposes.
As the previous answer states, Jersey comes with two filters, but you can usefully implement the Jersey interfaces ContainerRequestFilter or/and ContainerResponseFilter if you don't want to extend them. You're not limited to these two.
Another Jersey interface to keep in mind is ResourceFilter - this interface can be implemented for a filter that affects only some of the services.
The first part of your question may be answered in the Jersey documentation. A Jersey filter is not the same as a servlet filter.
There are two filters included in Jersey, a filter for logging requests and one for compression (GZip).
Another use case for a custom filter would be authentication or authorization.
I am using eclipse axis2 to create web service client from wsdl.
My impl method is:
public Output[] startProcess(Message[] Messages){
MyApplicationBean managementBean = (MyApplicationBean) FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get("myapp");
...
}
However when I execute:
http://localhost:8080/MyProject/services/portStartProcessService with method startProcess
I see in tomcat debug that it reaches my method, however the FacesContext.getCurrentInstance() returns null.
My web.xml (part of it)
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
How can I use JSF beans (like application scope) in web services call?
I know you do not want to hear this just yet, but you got the architecture wrong. JSF application context is useless with web service calls, because the whole idea of JSF is that GUI is built of stateful components stored:
in user session, or:
in a hidden form field.
Since neither session nor forms are available to web service calls, JSF does not apply here. You might as well ask how to make a web service that presses a JButton or inserts a CD into your CD-ROM.
I understand that you do not need the JSF components, but rather need some application logic that resides inside one of the managed beans, right?
Well, The easiest solution is to get a time machine, go back in time to when the project was planned and tell the architect that YOU NEVER PUT APPLICATION LOGIC INTO MANAGED BEANS. One of the reason is that they are unavailable to web service calls. Your application logic should reside in the service layer, provided by Spring or EJB.
Both Spring beans and EJBs are easy to reach from Axis services and from managed beans, and so you never need to access JSF managed beans from any place else than JSF front-end. If you do not like Spring and can't use EJB for some reason, build your service layer from POJOs, set it up in ApplicationContextListener and register in the application scope.
If such clean solution is unavailable and refactoring is impossible, you have two choices:
if the managed beans you try to reach are application scoped and eager, then they can be accessed in a JSP way, from the application context, using the venerable getAttribute method (you can access application context through the servlet context, which afaik you access through the message context, which in turn you access by the static MessageContext.getCurrentMessageContext method in Axis).
if the managed beans you want to use are request scoped and require some JSF plumbing (so you can not instantiate them by yourself) then you can pretend to be a FacesServlet and create the faces context by yourself; it is tricky but doable, a good and quite famous description is here: http://www.thoughtsabout.net/blog/archives/000033.html. You need will need servletrequest and servletresponse (from MessageContext). You can probably skip the parts required to pass the FacesContext on, because you will not require it to process any views.
Disclaimer: I never tried the last solution - it seems to work, although it is pretty dirty (and actually causes your web services to depend on JSF, which is bizzare).
We've got some Pure Servlets (pure Java classes following the Servlet API, no framework) that we'd like to include in a project that relies heavily on the Spring Framework.
What's the best way of including these servlets in the project, when all the new code we're writing is making heavy use of Spring 3 features?
your servlet container can run multiple servlets, spring is just one of them. why not just include your servlets in the web.xml and see if it works? it should work. spring is not that intrusive, yet (but obviously it already intruded the minds of many developers)
If you declare servlets in the web.xml, alongside the Spring front controller, it most certainly will work.
You just have to be careful when you declare which URLs map to the servlets. If you send "/*" to the Spring front controller, none of your requests will reach your other servlets. Be specific about what you need to send to each one.
As you might know, servlets cannot be configured as Spring beans. If your question is about colloborating with spring beans from a servlet, do refer this thread and also this
Spring provides a couple of classes to make this bridging easier.
ServletForwardingController
Spring Controller implementation that
forwards to a named servlet, i.e. the
"servlet-name" in web.xml rather than
a URL path mapping. A target servlet
doesn't even need a "servlet-mapping"
in web.xml in the first place: A
"servlet" declaration is sufficient.
Useful to invoke an existing servlet
via Spring's dispatching
infrastructure, for example to apply
Spring HandlerInterceptors to its
requests.
ServletWrappingController
Spring Controller implementation that
wraps a servlet instance which it
manages internally. Such a wrapped
servlet is not known outside of this
controller; its entire lifecycle is
covered here (in contrast to
ServletForwardingController).