Map ServletRequestListener to Special Servlet - servlets

I have a several servlets and in my case I need to implement ServletRequestListener. But, I don't want the listener to react on every request in any servlet. I would like to know if there any possibility to map a specific ServletRequestListener to a specific certain servlet. My web.xml looks like:
<servlet>
<servlet-name>CommonsServlet</servlet-name>
<servlet-class>
com.promptlink.dslib.gwt.common.server.rpc.CommonsServletImpl</servlet-class>
</servlet>
...
<listener>
<listener-class>
com.promptlink.dslib.gwt.common.server.httpListeners.ServletRequestListenerImpl
</listener-class>
</listener>

That's not possible with a ServletRequestListener. A servlet request listener listens on every servlet request. Just create a Filter instead which you can simply map directly to servlet name (no, not to its URL pattern, that's maintenance unfriendly).
<filter>
<filter-name>CommonFilter</filter-name>
<filter-class>com.example.CommonFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CommonFilter</filter-name>
<servlet-name>CommonsServlet</servlet-name>
</filter-mapping>
See also:
Our servlet filters wiki page
Why do we need a servlet name?

If you only want to react on the requests of a specific servlet then the servlet itself would be the ideal place to do this.
If you don't control the servlet code you can write a Filter and give it the same URL pattern as the servlet or directly refer to the servlet in the filter mapping.

Related

How to bypass certain url patterns not invoking dispatcher servelet in spring MVC

I declared below url pattern within servelet definition for handler mapping.
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Now i have some specific url with above '/' pattern (ex: /demo/), but i dont want to allow this request to get handled by dispatcher servlet (since i dont have any handler mapping in controller for this request).
Is there any similar prototype like mvc:resources ?
It would be very thankful if someone tells how to find out whether the declared resources are invoked properly or not?
I declared like this:
<mvc:resources mapping="/resources/**" location="/resources/MainTemplate/"/>
In jsp:
<link rel="stylesheet" href="/resources/css/components.css">
<script type="text/javascript" src="/resources/js/jquery-1.8.3.min.js"></script>
You can write an interceptor for the pattern you want and handle it there. Configure your interceptor as shown below for specific patterns. You can also exclude the url patterns you want from entering into the interceptor.
<mvc:interceptor>
<mapping path="/url_pattern/**"/>
<exclude-mapping path="/exclude/**"/>
..
</mvc:interceptor>

Spring mvc, why my controller not mapped

I defined my Dispatcher servlet's url mapping in web.xml like this:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/data/*</url-pattern>
</servlet-mapping>
my controller's method is annotated with:
#RequestMapping(value="/data/sys/CodeCatalogs")
when I request the url in browser I got 404 error, if I change the mapping to this:
#RequestMapping(value="/sys/CodeCatalogs")
the full url:
http://localhost:8080/cwe/data/sys/CodeCatalogs
it works, why? I am new to spring mvc, please help.
I tested url that contain no wildcard:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/data/*</url-pattern>
url-pattern>/test/foo</url-pattern>
</servlet-mapping>
then this request mapping will works:
#RequestMapping(value="/test/foo")
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/data/*</url-pattern>
</servlet-mapping>
In the preceding example, all requests starting with /data and anything which ends with *.do will be handled by the DispatcherServlet instance named dispatcher.
So for controller's method is annotated with:
#RequestMapping(value="/data/sys/CodeCatalogs")
http://localhost:8080/cwe/data/sys/CodeCatalogs - Does not match
http://localhost:8080/cwe/data/data/sys/CodeCatalogs - Does matches
URL passes from browser will be first matched against URL pattern specified and
then the URL specified in #RequestMapping.
For controller's method is annotated with :
#RequestMapping(value="/test/foo")
http://localhost:8080/cwe/test/foo - Matches since URL matches the exact pattern which is allowed as per Servlet Specification.
http://localhost:8080/cwe/data/test/foo - This will also match because of pattern /data/*
For an incoming request of the form /data/sys/CodeCatalogs, your servlet container will consume the /data/ portion before passing the pattern to your Spring servlet. So the controller will receive /sys/CodeCatalogs and hence this is why your second #RequestMapping works and the first does not.

Spring MVC behavior while co-existing with traditional web app servlets

We have an existing application not using Spring MVC. We decided to keep existing features as is and add Spring MVC in for any other new features through a url like "/admin/*.
so here is the web.xml mapping:
<servlet>
<servlet-name>springRouted</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc-config.xml</param-value>
</init-param>
<load-on-startup>4</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springRouted</servlet-name>
<url-pattern>/admin/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ExistingServlet</servlet-name>
<url-pattern>existing.do</url-pattern>
</servlet-mapping>
Here in the ExistingServlet, there is a call to request.getRequestDispatcher().forward("/admin/...jsp"), somehow Spring will detect this fowarding and report an error that not able to find mapping for "/admin/...jsp". It seems calling request.getRequestDispatcher().forward("/admin/...jsp") will make servlet container to recheck the web.xml and reroute through Spring's DispatchServlet. is it true? I thought this kind of internal forward won't be intercepted by Spring's DispatchServlet
A RequestDispatcher will be resolved against the mappings you have in your deployment descriptor (web.xml) or other Servlet configuration, basically all servlet mappings.
When you do
request.getRequestDispatcher("/admin/...jsp");
The Servlet container finds the Servlet (or other resource) meant to handle that path and wraps it in a RequestDispatcher object. When you then perform RequestDispatcher#forward(..) on the returned object, you are executing the service() method of the Servlet that was previously found.
In your example, that would be the DispatcherServlet. If your DispatcherServlet is configured to handle a request to /admin/...jsp, then it will do so. If not, it will throw its own custom exception, responding to the HTTP request with a 404.
Here are some more details on how getRequestDispatcher() works.

HTTP 405 error when connecting to spring-security auto-generated log-in page

I cannot connect to the auto generated spring security log-in page. According to the documentation, including the following lines in your security-context.xml will have Spring generate an html log-in form and redirect the user to it when trying to connect to the specific URL:
<http auto-config="true" >
<intercept-url pattern="/management-console" access="ROLE_ADMIN"/>
</http>
<authentication-manager ... />
Here is the rest of my configuration. Web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/context/applicationContext.xml <!-- I am importing my security-context.xml in here -->
<param-value>
</context-param>
<!-- Security Configuration -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/management-console</url-pattern>
</filter-mapping>
I have tried importing the security-context.xml directly in the web.xml, but I still see the error.
After deploying my application, I can connect to each my specified urls without issue. However, when I try to go to localhost:{port}/{appName}/management-console, the filter chain redirects me to /spring_security_login (as expected). However, I see an "HTTP Status 405 - Request method 'GET' not supported" error once I am forwarded and the following comes up on the console (spring-mvc is the name I gave to my servlet):
org.springframework.web.servlet.PageNotFound | No mapping found for HTTP request with URI [/InternalManagementViewer/spring_security_login] in DispatcherServlet with name 'spring-mvc' |
I have seen this error before when I miss declaring a POST/GET mapping in the controller. According to the documentation, I should not have to include such a method in my controller to handle the /spring_security_login mapping. From what I have read, spring is supposed to know to return the auto-generated log-in html page.
Just to see what happens, I declared a method in my controller to handle the /spring_security_login mapping. Since the function returns void (because I do not know the local view name of the generated html log-in page), it looks for the resource named "spring_security_login.jsp", which is not explicitly created in my project, and thus I get an "HTTP resource not found" error.
I'm stumped on this one and could really use a hand. Thanks a lot for taking a look.
Apply springSecurityFilterChain filter to all URLs:
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
springSecurityFilterChain is an entry point for all Spring Security features. So if this filter is not applied to some URL then you will not be able use Spring Security there (in this case handle /spring_security_login URL).

How to intercept all the requests for all the controller without HandlerInterceptor in Spring?

I have a requirement to intercept all the request in spring 2.5. I don't want to use HandlerInterceptor to intercept the request because it requires to configure it with every SimpleUrlHandlerMapping bean in the context files. Is there another way to intercept all the request without using HandlerInterceptor?
You could implement a filter and map it to the DispatcherServlet in web.xml. Then you should be able to intercept all request made to Spring MVC.
In short:
Create an implementation of javax.servlet.Filter
Add the filter to web.xml
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>mypackage.MyFilter</filter-class>
</filter>
and then map it to the DispatcherServlet (servlet-name should be the same that is defined for the Spring Dispatcher servlet.
<filter-mapping>
<filter-name>MyFilter</filter-name>
<servlet-name>DispatcherServlet</servlet-name>
</filter-mapping>
If you need access to the Spring ApplicationContext in the filter, use the static method
org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext()

Resources