Servlets and JSPs. Simple request?

I already have several Java server pages installed, and I would like to use the Controller / View system by adding a process servlet (which extends HttpServlet).

I just want to basically handle the requested JSPs as usual after the ProcessServlet has added some attributes.

Let's say that all my JSPs are in a directory called / content /, and there is a rule in my web.xml file to map / content / * .jsp to my ProcessServlet

I was unable to find a way to move all my JSPs to another directory (/ content-JSPs /) so that they could be sent without having to go through the ProcessServlet indefinitely.

Is there a way to send # forward () (some other method?) To the requested JSP without going through ProcessServlet again?

It's a little hard to believe that this lack of flexibility exists. Why doesn't the servlet just act like a pass in the JSP?

My goal is to configure everything so that the web server does not have to have a separate directory for all JSPs and another directory for everything else, i.e. CSS, JavaScript and images. I would like to keep the directory structure (and URL structure) as it is.

+4
source share
5 answers

Put them in the /WEB-INF folder. It also effectively hides the JSP from direct access. You only need to change the call to RequestDispatcher#forward() to include /WEB-INF in the path.

 request.getRequestDispatcher("/WEB-INF/content" + request.getPathInfo()).forward(request, response); 

Please note that the URL /content/*.jsp URL pattern is syntactically invalid. This should be /content/* . You may also have really used this. To skip static resources such as images / css / JS, simply do not put them in /content , but, for example, in /resources , /static , etc.

Connected:

+5
source

You can also use the Sevlet filter instead of Servet. This is a good option if your servlet only adds some parameters to the request. And you do not need to manually send your request to the JSP.

+3
source

Why not instead of matching with * .jsp, match something like * .page (or any other), and then your process servlet can do its processing and replace .page with .jsp and instruct RequestDispatcher to forward() on this page.

As long as all the links on the pages you want to go through the ProcessServlet use the name .page, this will probably work.

+1
source

As many of them suggested it is better to use filters in this case.

Put the following snippet in web.xml

Filter definition

 <filter> <filter-name>ProcessFilter</filter-name> <filter-class>my.filter.ProcessFilter</filter-class> </filter> 

Filter display

 <!-- Map all ".jsp" that should go through the filter--> <filter-mapping> <filter-name>ProcessFilter</filter-name> <url-pattern>/content/*.jsp</url-pattern> </filter-mapping> <!-- If you have Any servlets that needs to go through ProcessFilter --> <filter-mapping> <filter-name>ProcessFilter</filter-name> <servlet-name>MyServlet</servlet-name> </filter-mapping> 

OncePerRequestFilter

If you want to execute the filter only after the first time you can save the attribute in the request area, and the next time you can check whether the attribute is set, in this case it is not processed further.

If you use the Spring framework, you can use one of the OncePerRequestFilter subclasses or extend it and just implement doFilterInternal() .

Otherwise, you can refer to OncePerRequestFilter.java : raw and implement / extend your filter.

Here is a simplified version.

  public class ProcessFilter extends Filter { public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { throw new ServletException("OncePerRequestFilter just supports HTTP requests"); } HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String alreadyFilteredAttributeName = "ALREADY_PROCESSED_BY_PROCESS_FILTER"; if (request.getAttribute(alreadyFilteredAttributeName) != null) { // Proceed without invoking this filter... filterChain.doFilter(request, response); } else { // Do invoke this filter... request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE); try { doFilterInternal(httpRequest, httpResponse, filterChain); } finally { // Remove the "already filtered" request attribute for this request. request.removeAttribute(alreadyFilteredAttributeName); } } } protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { throws ServletException, IOException /* * * * Put your processing logic here * * */ } } 
+1
source

According to me, you should try using <filter> in your web.xml so that some of your requests go around the servlet.

0
source

Source: https://habr.com/ru/post/1380494/


All Articles