归纳能力不好,不知怎么写一个简洁的标题。。。
平台:Java, Jersey, Jackson
当restful api接收的json数据格式不对的时候,通常我们会返回异常信息,这些信息很有利于定位究竟是哪段json数据出了错。
我们也可以修改返回的信息。由于这些错误信息是框架给出的,所以可以通过重载相应的exception来定制返回的信息。
这么做有什么意义?要求比较严格的情况下,会不想让客户看到具体的信息,比如用到的包的信息(下面的错误信息中就包括包信息);这些信息会被利用,进而分析是用什么实现的,进而利用这种实现潜在的漏洞进行攻击。
这么复杂的东西,对我来说不知道怎么实现,还好,可以参考这里:
http://javareferencegv.blogspot.com/2015/07/handle-invalid-json-request-by.html
我呢,用了一下,没问题;把整个方案记录一下:
假定一个restful pai,对应的输入参数的POJO是:
-
class mydata{
-
String name;
-
String[] days;
-
Map price;
-
}
正常的输入应该是:
-
{"name":"TOM","days":["20161223"],"things":{"apple":"11","orange:"12"}}
但是如果给的json数据是非法的,那么会抛出如下错误:
case 1:
输入:
-
{"name":"TOM","days":["20161223"],abcdefg,"things":{"apple":"11","orange:"12"}}
得到返回的错误信息:
-
Unexpected character ('a' (code 97)): was expecting double-quote to start field name at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@7483; line: 1, column: 35]
case 2:
输入:
-
{"name":"TOM","days":"what","things":{"apple":"11","orange:"12"}}
得到返回的错误信息:
-
Can not deserialize instance of java.lang.String[] out of VALUE_STRING token at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@983232; line: 1, column: 22] (through reference chain: xxx.yyy.mydata["days"])
case 3:
输入:
-
{"name":"TOM","days":["20161223"],"things":{"apple"}}
得到返回的错误信息:
-
Unexpected character ('}' (code 125)): was expecting a colon to separate field name and value at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@7632323; line: 1, column: 51] at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@2432432; line: 1, column: 55] (through reference chain: xxx.yyy.mydata["price"])
如果说不想给出这样详细的信息,而只是想提示一下有问题,那么可以通过重载相应的exception来做到。具体修改如下:
"web.xml"
-
<servlet>
-
<servlet-name>myServlet</servlet-name>
-
<servlet-class>
-
org.glassfish.jersey.servlet.ServletContainer
-
</servlet-class>
-
<init-param>
-
<param-name>javax.ws.rs.Application</param-name>
-
<param-value>xxx.yyy.register</param-value>
-
</init-param>
-
<init-param>
-
<param-name>
-
com.sun.jersey.api.json.POJOMappingFeature
-
</param-name>
-
<param-value>true</param-value>
-
</init-param>
-
<load-on-startup>1</load-on-startup>
-
</servlet>
"xxx.yyy.register.java"
-
package xxx.yyy;
-
import java.io.File;
-
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
-
import org.glassfish.jersey.server.ResourceConfig;
-
import com.fasterxml.jackson.annotation.JsonInclude;
-
import com.fasterxml.jackson.annotation.JsonInclude.Include;
-
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
-
import javax.ws.rs.ext.MessageBodyReader;
-
import javax.ws.rs.ext.MessageBodyWriter;
-
public class register extends ResourceConfig {
-
public register() {
-
packages("xxx.yyy");
-
register(YourJsonProvider.class);
-
register(MyJsonParseExceptionMapper.class);
-
register(MyJsonMappingExceptionMapper.class);
-
}
-
}
"MyJsonParseExceptionMapper.java"
-
package xxx.yyy;
-
import com.fasterxml.jackson.core.JsonParseException;
-
import javax.ws.rs.core.MediaType;
-
import javax.ws.rs.core.Response;
-
import javax.ws.rs.ext.ExceptionMapper;
-
import javax.ws.rs.ext.Provider;
-
@Provider
-
public class MyJsonParseExceptionMapper implements ExceptionMapper{
-
@Override
-
public Response toResponse(JsonParseException exception)
-
{
-
String info = "{\"Error\":\"It is an error, invalid JSON format.\"}";
-
return Response
-
.status(Response.Status.BAD_REQUEST)
-
.entity(info)
-
.type( MediaType.APPLICATION_JSON)
-
.build();
-
}
-
-
}
"MyJsonMappingExceptionMapper.java"
-
package xxx.yyy;
-
import com.fasterxml.jackson.databind.JsonMappingException;
-
import javax.ws.rs.core.MediaType;
-
import javax.ws.rs.core.Response;
-
import javax.ws.rs.ext.ExceptionMapper;
-
import javax.ws.rs.ext.Provider;
-
@Provider
-
public class MyJsonMappingExceptionMapper implements ExceptionMapper{
-
@Override
-
public Response toResponse(JsonMappingException exception)
-
{
-
String info = "{\"Error\":\"JSON format is OK, but some part's type is wrong.\"}";
-
return Response
-
.status(Response.Status.BAD_REQUEST)
-
.entity(info)
-
.type( MediaType.TEXT_PLAIN)
-
.build();
-
}
-
}
此时,再执行前面那几个错误的输入,可以得到如下输出:
case 1:
输入:
-
{"name":"TOM","days":["20161223"],abcdefg,"things":{"apple":"11","orange:"12"}}
输出:
-
{"Error":"It is an error, invalid JSON format."}
case 2:
输入:
-
{"name":"TOM","days":"what","things":{"apple":"11","orange:"12"}}
输出:
-
{"Error":"It is an error, invalid JSON format."}
case 3:
输入:
-
{"name":"TOM","days":["20161223"],"things":{"apple"}}
输出:
-
{"Error":"It is an error, invalid JSON format."}
用到的一些jar (其实不需要这么多):
jackson-annotations-2.8.4.jar
jackson-databind-2.8.4.jar
jackson-jaxrs-json-provider-2.8.4.jar
jackson-xc-1.9.2.jar
jackson-core-2.8.4.jar
jackson-jaxrs-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
jackson-core-asl-1.9.2.jar
jackson-jaxrs-base-2.8.4.jar
jackson-module-jaxb-annotations-2.8.4.jar
javax.ws.rs-api-2.0.1.jar
jersey-client-2.25.jar
jersey-container-servlet-core-2.25.jar
jersey-guava-2.25.jar
jersey-media-json-jackson-2.25.jar
jersey-common-2.25.jar
jersey-core-1.19.3.jar
jersey-json-1.19.3.jar
jersey-server-2.25.jar
jersey-container-servlet-2.25.jar
jersey-entity-filtering-2.25.jar
jersey-media-jaxb-2.25.jar
jsr305-3.0.0.jar
阅读(16399) | 评论(0) | 转发(0) |