📜  实现异常处理-找不到404资源(1)

📅  最后修改于: 2023-12-03 15:09:27.367000             🧑  作者: Mango

实现异常处理 - 找不到404资源

在Web开发中,经常会遇到找不到资源的情况,比如用户请求一个不存在的页面或资源。此时,服务器通常会返回404错误码,告诉用户请求的资源不存在。对于程序员而言,我们应该在代码中对这种情况进行处理,以便更好地提示用户或者记录日志。

下面介绍两种常见的处理方式:

方式一:自定义404页面

一种常见的方式是自定义404页面,在服务器找不到请求的资源时,将默认返回我们定义的404页面。这样用户就能够看到一个友好的提示页面,而不是看到一堆错误信息。

以下是通过Java Servlet实现自定义404页面的示例代码:

@WebServlet(name = "ErrorServlet", urlPatterns = {"/ErrorServlet"})
public class ErrorServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processError(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processError(request, response);
    }

    private void processError(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 根据请求头中的Accept-Language,设置响应的语言头
        response.setHeader("Content-Language", "en");

        int statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        String message = (String) request.getAttribute("javax.servlet.error.message");
        String uri = (String) request.getAttribute("javax.servlet.error.request_uri");

        // 将异常信息显示在错误页面上
        request.setAttribute("statusCode", statusCode);
        request.setAttribute("message", message);
        request.setAttribute("uri", uri);

        // 请求转发到自定义的404页面
        request.getRequestDispatcher("/WEB-INF/errors/404.jsp").forward(request, response);
    }
}

在上述代码中,我们定义了一个名为ErrorServlet的Servlet,它用来处理404错误。当服务器遇到找不到资源的情况时,会将请求转发到此Servlet中,然后我们将请求中的一些信息(比如错误码、错误信息等)保存到request中,并请求转发到一个自定义的404页面。此页面可以放到WEB-INF目录下,以确保它不会被外部访问到,从而增加安全性。

以下是示例404页面的JSP代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>404 Not Found</title>
</head>
<body>
<h1>${statusCode} ${message}</h1>
<p>The requested resource ${uri} is not available.</p>
</body>
</html>

在上述代码中,我们使用EL表达式来显示request中保存的信息,以便将错误信息传递给用户。

方式二:记录日志

另一种常见的方式是记录日志。当服务器遇到找不到资源的情况时,我们可以在代码中记录下此事件的信息,以便我们在以后的调试或者分析中查看。记录日志的代码通常会使用一个日志库(比如log4j或者java.util.logging),以下代码示例使用了java.util.logging:

public class NotFoundExceptionHandler implements HandlerExceptionResolver {
    private static final Logger logger = Logger.getLogger(NotFoundExceptionHandler.class.getName());

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        if (ex instanceof NoHandlerFoundException) {
            NoHandlerFoundException nfex = (NoHandlerFoundException) ex;
            String message = nfex.getMessage();
            String requestUri = nfex.getRequestURL();

            // 记录日志信息
            logger.log(Level.WARNING, "404 not found: {0} -> {1}", new Object[]{requestUri, message});

            response.setStatus(HttpStatus.NOT_FOUND.value());

            // 返回一个空的ModelAndView对象,以更新响应
            return new ModelAndView();
        }

        // 如果不是404错误,返回null以让其他的处理器处理
        return null;
    }
}

在上述代码中,我们定义了一个名为NotFoundExceptionHandler的异常处理器,它用来处理找不到资源的情况。当服务器遇到这种情况时,会将请求转发到此异常处理器中,然后我们将相关信息记录到日志中。在上述代码中,我们假设404错误的异常类型为NoHandlerFoundException,使用了java.util.logging进行日志记录。

另外,由于我们不需要在页面上显示任何内容,因此我们在最后返回一个空的ModelAndView对象即可。

以上两种方式都可以有效地处理找不到资源的情况。在实际应用中,我们可以选择其中的一种或者结合使用。无论怎样,我们都应该做好异常处理,以便更好地响应用户请求。