I\'m trying to follow the pattern at Design Patterns web based applications. It all works fine part from when it comes to maping \"root\" URLs.
I\'d like to put all
The /*
URL pattern covers everything, also the forwarded JSP files and static resources like CSS/JS/images. You don't want to have that on a front controller servlet.
Keep your controller servlet on a more specific URL pattern like /pages/*
. You can achieve the functional requirement of getting rid of "/pages" in the URL by grouping the static resources in a common folder like /resources
and creating a Filter
which is mapped on /*
and does the following job in the doFilter()
method:
HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI().substring(req.getContextPath().length());
if (path.startsWith("/resources/")) {
// Just let container's default servlet do its job.
chain.doFilter(request, response);
} else {
// Delegate to your front controller.
request.getRequestDispatcher("/pages" + path).forward(request, response);
}
A forwarded JSP resource will by default not match this filter, so it will properly be picked up by the container's own JspServlet
.
You can extend the DefaultServlet of your web server.The extended servlet will be your front controller. In the doGET or doPOST method forward your static pages to the super class. DefaultServlet is the servlet that is mapped to url "/" by default. I have used it with jetty server but it can be implemented in tomcat as well.
public class FrontController extends DefaultServlet {
@Override
public void init() throws UnavailableException {
super.init();
}
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String uri = request.getRequestURI();
/*
* if request is trying to access inside /static then use the default
* servlet. YOU CAN USE YOUR OWN BUSINESS LOGIC TO FORWARD REQUESTS
* TO DEFAULTSERVLET
*/
if (uri.startsWith("/static/")) {
super.doGet(request, response);
return;
} else {
// else use your custom action handlers
}
}
}
In the above code samples I have forwarded all the requests starting with /static/ to the default servlet to process. In this way you can map the FrontController to "/" level .
<servlet>
<description></description>
<display-name>FrontController</display-name>
<servlet-name>FrontController</servlet-name>
<servlet-class>FrontController</servlet-class>
<servlet-mapping>
<servlet-name>FrontController</servlet-name>
<url-pattern>/</url-pattern>
Why do we need to map each and every URL. In case you need to map all the URL, you might need skip URL in the filter.
<filter>
<display-name>SessionFilter</display-name>
<filter-name>SessionFilter</filter-name>
<filter-class>com.colabcom.goshare.app.base.filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
In Your Filter,
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getServletPath();
boolean allowedRequest = Utility.filterURL(url, avoidUrls);
if(allowedRequest){
chain.doFilter(request, response);
}else{
//Main Filter Code
}
Utility Class to filter your URL:
public static boolean filterURL(String str, List<String> avoidURLList) {
boolean exist = false;
if(avoidURLList == null){
return exist;
}
for (int i = 0; i < avoidURLList.size(); i++) {
if (str.contains(avoidURLList.get(i))) {
exist = true;
break;
}
}
return exist;
}
Else you can map specific URL in your web.xml like
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
the /* url pattern matches all servlets, jsp and static content in your application.
Whay you would need is to define a *.jsp pattern to allow Tomcat use the default jsp servlet:
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>