java 如何在解组 JSON 数据期间处理解析器异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14853939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle parser exceptions during unmarshalling of JSON data?
提问by Mono Jamoon
I am using Jersey in my Web-application. The data sent to the server is in JSON format, which in turn is unmarshalled at the server-end and the object obtained is used in further processing. The security audit raised some vulnerabilities for this approach.
我在我的 Web 应用程序中使用 Jersey。发送到服务器的数据是JSON格式,然后在服务器端进行解组,得到的对象用于进一步处理。安全审计为这种方法提出了一些漏洞。
My Rest Code:
我的休息代码:
@POST
@Path("/registerManga")
@Produces(MediaType.APPLICATION_JSON)
public Response registerManga(MangaBean mBean){
System.out.println(mBean);
return Response.status(200).build();
}
MangaBean:
漫画豆:
public class MangaBean {
public String title;
public String author;
@Override
public String toString() {
return "MangaBean [title=" + title + ", author=" + author + "]";
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
The data is sent in this format:
数据以这种格式发送:
["title":"Bleach","author":"kubo tite"]
The above data is successfully unmarshalled into an object and I get this as the output:
上述数据已成功解组为一个对象,我将其作为输出:
MangaBean [title=Bleach, author=kubo tite]
But if the data is changed to:
但是如果数据改成:
["title":"<script>alert("123");</script>","author":"kubo tite"]
A 500 internal server error occurs and is displayed to the user:
发生 500 内部服务器错误并显示给用户:
javax.servlet.ServletException: org.codehaus.Hymanson.JsonParseException: Unexpected character ('1' (code 49)): was expecting comma to separate OBJECT entries
at [Source: org.apache.catalina.connector.CoyoteInputStream@19bd1ca; line: 1, column: 28]
com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:420)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
The unexpected occurrence of ""
is causing errors in the parser. As the unmarshalling is done behind the scenes and I have no control over it, I am unable to handle the exception being raised.
的意外发生""
导致解析器出错。由于解组是在幕后完成的,我无法控制它,因此我无法处理引发的异常。
My question is how can I handle this exception and return a proper response to the user instead of a stacktrace. Please advice.
我的问题是如何处理此异常并向用户返回正确的响应而不是堆栈跟踪。请指教。
回答by Perception
Register an exception mapper to handle the JSON parsing exceptions:
注册一个异常映射器来处理 JSON 解析异常:
@Provider
class JSONParseExceptionMapper implements ExceptionMapper< JsonParseException > {
@Override
public Response toResponse(final JsonParseException jpe) {
// Create and return an appropriate response here
return Response.status(Status.BAD_REQUEST)
.entity("Invalid data supplied for request").build();
}
}
回答by max
If this exception mapper isn't being called (as John Ding's comment indicated), make sure you have it registered with your ResourceConfig.
如果未调用此异常映射器(如 John Ding 的评论所示),请确保已将其注册到 ResourceConfig。
Also, take note that when using the HymansonFeature (with Jersey 2.x) it includes an exception mapper for this, but if you register your own it will take precedence.
另外,请注意,当使用 HymansonFeature(与 Jersey 2.x)时,它包含一个异常映射器,但如果您注册自己的,它将优先。
Here is an example of registering it by package. So put JSONParseExceptionMapper in "your.package.here" and it will get picked up.
下面是一个按包注册的例子。因此,将 JSONParseExceptionMapper 放在“your.package.here”中,它将被拾取。
@ApplicationPath("whatever")
public class MyAppResourceConfig extends ResourceConfig
{
public MyAppResourceConfig()
{
packages("your.package.here");
register(HymansonFeature.class);
}
}
For the original question, you'll need to handle JsonMappingExceptionMapper as well.
对于原始问题,您还需要处理 JsonMappingExceptionMapper。
回答by Mordechai
In addition to @Perception's answer, the missing part is that the exceptions get swallowed and not reported. You should pass a validation listener:
除了@Perception 的回答之外,缺少的部分是异常被吞并没有报告。您应该通过验证侦听器:
private static final String[] severity = new String[] {"Warning", "Error", "Fatal Error"};
void beforeUnmarshal(Unmarshaller u, Object parent) throws JAXBException {
u.setEventHandler((evt) -> {
throw new WebApplicationException(severity[evt.getSeverity()]+": Error while parsing request body: " + evt.getMessage(), evt.getLinkedException(), 400);
});
}
Just drop this code in your JAXB bean and your all set.
只需将此代码放入您的 JAXB bean 和所有设置中即可。
回答by Dattatray
The other option could be in the ResourceConfig, register the JsonParseExceptionMapper class.
另一个选项可以在 ResourceConfig 中,注册 JsonParseExceptionMapper 类。
register(JsonParseExceptionMapper.class);
注册(JsonParseExceptionMapper.class);
回答by user
Add the exception handling class in same package(or sub package) mentioned in the web.xml file
在 web.xml 文件中提到的同一个包(或子包)中添加异常处理类
回答by Shashi
Adding full class example of Perception answer
添加感知答案的完整类示例
package com.shashi.service;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;
import org.codehaus.Hymanson.JsonParseException;
import com.sun.jersey.api.client.ClientResponse.Status;
import com.talklingo.service.v1.UserManagementService;
@Provider
public class JSONParseExceptionMapper implements ExceptionMapper< JsonParseException > {
private static Logger logger = Logger
.getLogger(JSONParseExceptionMapper.class);
public Response toResponse(final JsonParseException jpe) {
// Create and return an appropriate response here
return Response.status(Status.BAD_REQUEST)
.entity("Invalid data supplied for request").build();
}
}