我有一个带有花哨内容的静态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;
}
}
答案 0 :(得分:0)
执行转发而不是重定向到所需资源,并且URL将保持不变。
RequestDispatcher rd = request.getRequestDispatcher("my_404.html");
rd.forward(request, response);
答案 1 :(得分:0)
RequestDispatcher在我的情况下没用,因为响应一直在提交。以下是我最终为Freemarker Servlets提供的解决方案;
我为我的目的重写了一些Freemarker servlet方法,例如service()和requestUrlToTemplatePath()。通过这种方式,我可以在响应提交之前进行干预。
First Override用于服务方法。我的目的是检查请求的网页是否存在。
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
checkIfPageExists(req);
super.service(req, resp);
}
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);
}
第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;
}