FreeMarker:显示自定义404页面而不重定向

时间:2015-07-02 07:18:56

标签: java servlets freemarker

我有一个带有花哨内容的静态404页面。 如果用户输入了不存在的页面的错误网址,我希望他能看到404页面,但也希望保留网址,以便用户查看他/她输入的错误网址。

输入的页面不存在: http://localhost:10039/my.website/my/halp.html

404页面 http://localhost:10039/my.website/my/notfound.html

简单地说,而不是使用" sendRedirect"在这里,我想"获取内容" pageNotFoundUrl并在网址仍为http://localhost:10039/my.website/my/halp.html

时显示

我没有重定向,也试过"转发"正如卡亚曼建议的那样但在这种情况下,我得到了"无法前进。响应已经提交。"

TestServlet在web.xml中定义,此类扩展了UtilmarkreeServlet,它扩展了FreemarkerServlet。

UtilFreemarkerServlet

public abstract class UtilFreemarkerServlet extends FreemarkerServlet {
    private static final long serialVersionUID = 1L;

    public static final String REQUEST_OBJECT_NAME = "RequestObject";

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void init() throws ServletException {
        logger.info("init started");
        super.init();
        Configuration cfg = getConfiguration();
        cfg.setLocalizedLookup(false);

    }

    @Override
    protected ObjectWrapper createObjectWrapper() {
        return ObjectWrapper.BEANS_WRAPPER;
    }

    @Override
    protected HttpRequestParametersHashModel createRequestParametersHashModel(HttpServletRequest request) {
        request.setAttribute(REQUEST_OBJECT_NAME, request);
        return super.createRequestParametersHashModel(request);
    }   

}

TestServlet

public class TestServlet extends UtilFreemarkerServlet{
    private static final long serialVersionUID = 1L;    
    private String website;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {     
        super.service(req, resp);       
        boolean handleResult = handlerForRequest(req, resp);            
    }

    protected boolean handlerForRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        if (resp.getStatus() == 404) {
            String pageNotFoundUrl = "http://localhost:10039/my.website/my/notfound.html";          
            RequestDispatcher rd = req.getRequestDispatcher(url);
            rd.forward(req, resp);
            // resp.sendRedirect(url);
        }

        return true;
    }

}

2 个答案:

答案 0 :(得分:0)

执行转发而不是重定向到所需资源,并且URL将保持不变。

RequestDispatcher rd = request.getRequestDispatcher("my_404.html");
rd.forward(request, response);

答案 1 :(得分:0)

RequestDispatcher在我的情况下没用,因为响应一直在提交。以下是我最终为Freemarker Servlets提供的解决方案;

我为我的目的重写了一些Freemarker servlet方法,例如service()和requestUrlToTemplatePath()。通过这种方式,我可以在响应提交之前进行干预。

  1. First Override用于服务方法。我的目的是检查请求的网页是否存在。

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {         
        checkIfPageExists(req);
        super.service(req, resp);                       
    }
    
  2. checkIfPageTemplateExists检查页面的模板是否为空。如果为null,则表示它不可用。在这种情况下,我设置了一个请求属性。否则,这意味着它存在。

    protected void checkIfPageExists(HttpServletRequest req)
    throws     ServletException {
    
    String relativeUrl = requestUrlToTemplatePath(req);
    try {
            getConfiguration().getTemplate(relativeUrl); //throws exception if the template cannot be accessed
        } catch (TemplateNotFoundException e) {
            logger.debug("TemplateNotFoundException for " + relativeUrl);
            pageNotFound = "/customNotFoundPage.html";
        } catch (IOException e) {
            logger.debug("IOException for " + relativeUrl);
            pageNotFound = "/customNotFoundPage.html";
        } 
      req.setAttribute(NOT_FOUND_PAGE, pageNotFoundPage);
    }
    
  3. 第1项中所述的最后一行是针对super.service()方法的。这将触发requestUrlToTemplatePath()方法,这实际上是您可以指定要显示的url页面而不更改url的方法。 我只是检查请求是否具有NOT_FOUND_PAGE属性。如果是这样,只需覆盖路径本身并继续执行流程中的下一步。否则,只需使用超类的路径。

    @Override
    protected String requestUrlToTemplatePath(HttpServletRequest request) 
    throws ServletException {
    
        String path = super.requestUrlToTemplatePath(request);
    
        //Check if NOT_FOUND_PAGE is requested
        if(request.getAttribute(NOT_FOUND_PAGE) != null) {
            path =  (String) request.getAttribute(NOT_FOUND_PAGE);      
        }
    
     return path;
     }