How to link a servlet as a directory+servlet Web.xml? - servlets

Basically I have a servlet say: gubis.
To be precise: I need my gubis servlet be accessed as servs/gubis
The goal I want to reach is that if I made the request as localhost:8080/EclipsePro/servs/gubis the request should be redirected to localhost:8080/EclipsePro/gubis
I tried:
<servlet>
<servlet-name>servs/gubis</servlet-name>
<servlet-class>duck.reg.pack.gubis</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servs/gubis</servlet-name>
<url-pattern>/gubis</url-pattern>
</servlet-mapping>
But it didn't worked

If you need gubis servlet be accessed as servs/gubis
<servlet>
<servlet-name>gubis</servlet-name>
<servlet-class>duck.reg.pack.gubis</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gubis</servlet-name>
<url-pattern>servs/gubis</url-pattern>
</servlet-mapping>
The goal I want to reach is that if I made the request as localhost:8080/EclipsePro/servs/gubis the request should be redirected to localhost:8080/EclipsePro/gubis
You can use url-rewriting to achieve the above.

Related

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.

Map ServletRequestListener to Special Servlet

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.

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.

Spring MVC entry point

I want my project to use more than one controller. My question is, how do I navigate from one controller to another and what should I do about having a standard home page for my users to land on? Should this be a separate "homeController"? I don't understand how this should work. The "Spring in Action" book doesn't go into enough details to explain this.
Thanks
You can use different Controllers (Java classes) with the #Controller annotation, depending on what you want to do is the URL associated with the method defined in the Controller, for example:
#Controller
public class HomeController {
#RequestMapping(value = "/home", method = RequestMethod.GET)
public ModelAndView home() {
//code to process for the /home url
}
// More code
}
In servlet-context.xml check
<context:component-scan base-package="com.domain.package.controller" />
And use
#Controller
In class you want to be controller.
You can use a dispatcher servlet to delegate to different controllers.
<servlet>
<servlet-name>your-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>your-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Now depending on your #RequestMapping bindings in your controllers, the DispatcherServlet will decide where to route requests.
Also please check the spring mvc showcase on github. https://github.com/SpringSource/spring-mvc-showcase
If your web is needs a common landing page like login.jsp you can do it like following way.
Configure you dispatcher servlet in web.xml as follows.
<servlet>
<servlet-name>public</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>public</servlet-name>
<url-pattern>/pub/*</url-pattern>
</servlet-mapping>
Then you should have a dispatcher servelt call public-servelt.xml where you handle the login requests for all users.It should contains configs like this.
<context:component-scan base-package="com.mycompany.web.controller.secure" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/pub/"
p:suffix=".jsp" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
p:synchronizeOnSession="true" />
And then in your index.jsp where the common landing place of web app, put a jsp forward to hit above dispatcher servelt as follows.
<jsp:forward page="/pub/login" />
note : In your controller you need to have /login mapping in a get method as follows.
#RequestMapping(method = {GET, HEAD}, value = "/login")
public String loginHandler(.......){}
This is how normally achieve a common landing page through a spring controller.

Disabling PUT TRACE DELETE request in Apache Tomcat 6.0

I need to disable PUT, DELETE & TRACE HTTP requests on my Application Server, Apache Tomcat 6.0.
All other sources, i have searched till now, have directed me towards the limit parameter in httpd.conf, Hence I'd put it before-hand that I am not using Apache Web Server, and requests are directly being handled by Tomcat, and so there is no httpd.conf in picture.
Please suggest how should I do it on Tomcat?
Inside your WEBINF, add you can add a security constraint:
<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/blah/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>empty_role</role-name>
</auth-constraint>
</security-constraint>
Alternatively, you can do these two things:
In server.xml, edit the <connector> element, add an attribute: allowTrace="false". Then edit the DefaultServlet: $CATALINA_HOME/conf/web.xml
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>
org.apache.catalina.servlets.DefaultServlet
</servlet-class>
<!-- blah blah blah -->
<init-param>
<param-name>readonly</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
The answer lies in the servlet specification. In looking at the API for the servlet: http://java.sun.com/products/servlet/2.5/docs/servlet-2_5-mr2/javax/servlet/http/HttpServlet.html you'll see that different methods handle different kind of HTTP requests. Also, there is a great feature called filters that can be used to wrap some code around servlets and filters.
So the solutions are:
Modify the servlet to only support do and get; or
Create a filter to clear those other kind of requests.

Resources