![](/img/trans.png)
[英]Spark Java IllegalArgumentException: class org.eclipse.jetty.server.handler.ErrorHandler declares multiple JSON fields named _listeners
[英]How to make jetty ErrorHandler display error in json format in java
我通過下面的示例代碼以這種方式啟動了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(或更新版本),則可以覆蓋ErrorHandler.generateAcceptableResponse(Request baseRequest, HttpServletRequest request, HttpServletResponse response, int code, String message, String mimeType)
方法並相應地處理它。
請參閱: https : //github.com/eclipse/jetty.project/blob/jetty-9.3.11.v20160721/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java#例如L196-L226在其上的使用。
這不是什么大問題。
默認情況下,Jetty使用ErrorPageErrorHandler,您可以檢查Jetty的WebAppContext()構造函數,默認情況下看起來像這樣(jetty 9.4.19.v20190610):
public WebAppContext()
{
this(null,null,null,null,null,new ErrorPageErrorHandler(),SESSIONS|SECURITY);
}
您可以擴展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;
}
}
}
我的GitHub倉庫中的代碼: https : //github.com/xrom888/blog_jetty-display-errors-in-json
自定義ErrorHandler: https : //github.com/xrom888/blog_jetty-display-errors-in-json/blob/master/src/main/java/com/igorkhromov/ErrorHandler.java
MIT許可下的所有代碼,享受))。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.