如何使jetty ErrorHandler在java中以json格式显示错误

如何使jetty ErrorHandler在java中以json格式显示错误,java,rest,jersey,embedded-jetty,Java,Rest,Jersey,Embedded Jetty,我通过下面的示例代码以这种方式启动了jetty服务器,我在这里编写了自己的errorHandler类。通过一些研究,我得到了一些信息,但似乎还不足以满足我的需求。我设置由服务器调用的类的名称是HandleClient 因此,如果发生错误404,它将显示{“message”:“HTTP error 404”}。程序运行正常,但响应为文本/普通格式 我的问题是:如何配置该类以在MIME MediaType:application/json中格式化和显示错误 我在这件事上已经睡不着觉了。我将非常感谢所

我通过下面的示例代码以这种方式启动了jetty服务器,我在这里编写了自己的errorHandler类。通过一些研究,我得到了一些信息,但似乎还不足以满足我的需求。我设置由服务器调用的类的名称是HandleClient

因此,如果发生错误404,它将显示
{“message”:“HTTP error 404”}
。程序运行正常,但响应为文本/普通格式

我的问题是:如何配置该类以在MIME MediaType:application/json中格式化和显示错误

我在这件事上已经睡不着觉了。我将非常感谢所有的帮助

    public class MVCPattern{

    public MVCPattern(){
    }

    public static void main(String args[]) throws JSONException, IOException{
        MVCPattern mvcPattern = new MVCPattern();


        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");

        Server jettyServer = new Server(9000);
        jettyServer.setHandler(context);
        context.setErrorHandler(new ErrorHandler());
        // default error handler for resources out of "context" scope
        jettyServer.addBean(new ErrorHandler());

        ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
        jerseyServlet.setInitOrder(0);

        // Tells the Jersey Servlet which REST service/class to load.
        jerseyServlet.setInitParameter("jersey.config.server.provider.classnames",
                HandleClient.class.getCanonicalName() );

        try {
            jettyServer.start();            
            jettyServer.join();

        } catch (Exception ex) {
            Logger.getLogger(HandleClient.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            jettyServer.destroy();
        }
    }
    /**
     * Dummy error handler that disables any error pages or jetty related messages and returns our
     * ERROR status JSON with plain HTTP status instead. All original error messages (from our code) are preserved
     * as they are not handled by this code.
     */
    static class ErrorHandler extends ErrorPageErrorHandler {
        @Override
        public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
            response.getWriter()
            .append("{\"message\":\"HTTP error ")
            .append(String.valueOf(response.getStatus()))
            .append("\"}");
        }
    }

}

您应该检查
HttpServletRequest.getHeader(“Accept”)
中的
Accept
头,首先查看客户端是否可以接受该类型

然后使用
HttpServletResponse.setContentType(“text/json”)
设置响应的内容类型

或者,如果您使用的是Jetty 9.3.11.v20160721(或更新版本),则可以重写该方法并相应地进行处理


请参阅:例如关于它的使用。

这不是什么大问题

默认情况下,Jetty使用ErrorPageErrorHandler,您可以检查Jetty的WebAppContext()构造函数,默认构造函数如下所示(Jetty 9.4.19.v20190610):

您可以扩展ErrorPageErrorHandler并在JSON中写入响应错误

例如:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.igorkhromov.dto.Errors;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;


public class ErrorHandler extends ErrorPageErrorHandler {

    /*
        Messages to error made based on:
        Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
        https://tools.ietf.org/html/rfc7231
    */

    private static final String ERROR_404_MESSAGE = "Target resource not found";

    private static final String ERROR_501_MESSAGE = "Server functionality to process request is not implemented";

    private static final String ERROR_502_MESSAGE = "Server cannot proxy request";

    private static final String ERROR_503_MESSAGE = "Server is currently unable to handle the request";

    private static final String ERROR_504_MESSAGE = "Server did not receive a timely response from an upstream server";

    private static final String ERROR_UNEXPECTED_MESSAGE = "Unexpected error occurs";

    private static final ObjectMapper MAPPER = new ObjectMapper();

    @Override
    protected void generateAcceptableResponse(Request baseRequest, HttpServletRequest request, HttpServletResponse response, int code, String message, String mimeType)
            throws IOException
    {

            baseRequest.setHandled(true);
            Writer writer = getAcceptableWriter(baseRequest, request, response);
            if (null != writer) {
                response.setContentType(MimeTypes.Type.APPLICATION_JSON.asString());
                response.setStatus(code);
                handleErrorPage(request, writer, code, message);
            }

    }

    @Override
    protected Writer getAcceptableWriter(Request baseRequest, HttpServletRequest request, HttpServletResponse response)
            throws IOException
    {

            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            return response.getWriter();
    }

    @Override
    protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
            throws IOException
    {

            try {
                writer.write(MAPPER.writeValueAsString(new Errors(getMessage(code))));
            }
            catch (Exception e) {
                // Log if needed
            }
    }

    private boolean isRestRequest(HttpServletRequest request) {
        return request.getServletPath().startsWith("/api/");
    }

    private String getMessage(int code) {
        switch (code) {
            case 404 : return ERROR_404_MESSAGE;
            case 501 : return ERROR_501_MESSAGE;
            case 502 : return ERROR_502_MESSAGE;
            case 503 : return ERROR_503_MESSAGE;
            case 504 : return ERROR_504_MESSAGE;
            default  : return ERROR_UNEXPECTED_MESSAGE;
        }
    }
}
my GitHub repo中的代码:

自定义错误处理程序:


MIT许可下的所有代码,请欣赏。)

根据您链接的域/URL与您的用户名相同或包含您的用户名,您似乎已链接到自己的内容。如果你这样做了,你需要披露这是你的。如果你不透露这是你自己的内容,它通常被认为是垃圾邮件。请看:还有。谢谢,把回购标为我的。添加了注释,代码可以免费使用(MIT许可证)。
import com.fasterxml.jackson.databind.ObjectMapper;
import com.igorkhromov.dto.Errors;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;


public class ErrorHandler extends ErrorPageErrorHandler {

    /*
        Messages to error made based on:
        Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
        https://tools.ietf.org/html/rfc7231
    */

    private static final String ERROR_404_MESSAGE = "Target resource not found";

    private static final String ERROR_501_MESSAGE = "Server functionality to process request is not implemented";

    private static final String ERROR_502_MESSAGE = "Server cannot proxy request";

    private static final String ERROR_503_MESSAGE = "Server is currently unable to handle the request";

    private static final String ERROR_504_MESSAGE = "Server did not receive a timely response from an upstream server";

    private static final String ERROR_UNEXPECTED_MESSAGE = "Unexpected error occurs";

    private static final ObjectMapper MAPPER = new ObjectMapper();

    @Override
    protected void generateAcceptableResponse(Request baseRequest, HttpServletRequest request, HttpServletResponse response, int code, String message, String mimeType)
            throws IOException
    {

            baseRequest.setHandled(true);
            Writer writer = getAcceptableWriter(baseRequest, request, response);
            if (null != writer) {
                response.setContentType(MimeTypes.Type.APPLICATION_JSON.asString());
                response.setStatus(code);
                handleErrorPage(request, writer, code, message);
            }

    }

    @Override
    protected Writer getAcceptableWriter(Request baseRequest, HttpServletRequest request, HttpServletResponse response)
            throws IOException
    {

            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            return response.getWriter();
    }

    @Override
    protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
            throws IOException
    {

            try {
                writer.write(MAPPER.writeValueAsString(new Errors(getMessage(code))));
            }
            catch (Exception e) {
                // Log if needed
            }
    }

    private boolean isRestRequest(HttpServletRequest request) {
        return request.getServletPath().startsWith("/api/");
    }

    private String getMessage(int code) {
        switch (code) {
            case 404 : return ERROR_404_MESSAGE;
            case 501 : return ERROR_501_MESSAGE;
            case 502 : return ERROR_502_MESSAGE;
            case 503 : return ERROR_503_MESSAGE;
            case 504 : return ERROR_504_MESSAGE;
            default  : return ERROR_UNEXPECTED_MESSAGE;
        }
    }
}