Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用Jackson反序列化JSONP_Java_Jsonp_Jackson - Fatal编程技术网

Java 用Jackson反序列化JSONP

Java 用Jackson反序列化JSONP,java,jsonp,jackson,Java,Jsonp,Jackson,由于某种原因,Jackson 2.3.0无法解析JSONP响应 com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'my_json_callback': 我已经让反序列化过程在没有回调的情况下工作 我尝试过使用Jackson JAX-RS包,该包包含一个@JSONP注释,但这似乎只在序列化时使用。最后,我能够删除JSONP响应的回调部分 com.fasterxml.jackson.core.JsonParseEx

由于某种原因,Jackson 2.3.0无法解析JSONP响应

com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'my_json_callback':
我已经让反序列化过程在没有回调的情况下工作


我尝试过使用Jackson JAX-RS包,该包包含一个
@JSONP
注释,但这似乎只在序列化时使用。

最后,我能够删除JSONP响应的回调部分

com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'my_json_callback':
首先,Jackson能够解析JSON,即使它以括号结尾。因此,只需从响应中删除
myjson\u回调(
)就足够了

由于我使用的是Apache的HTTP客户端,因此解决了以下问题:

String callback = "my_json_callback(";
InputStreamReader r = new InputStreamReader(response.getEntity().getContent());
r.skip(callback.length());
return mapper.readValue(r, MyObject.class);
其思想是不必将读取器转换为字符串,然后在删除回调部分后解析该字符串

对于给定的JSONP字符串,我还可以使用
json.org
库中的
JSONTokener
获得相同的结果:

JSONTokener t = new JSONTokener(json);
t.nextValue(); // skip the callback
return mapper.readValue(t.nextValue().toString(), MyObject.class);

下面是我使用
ReaderInterceptor
提出的解决方案的空间版本。我将Jersey 2.x与Jackson结合使用,与只输出JSONP的web服务交互

public class CallbackStripInterceptor implements ReaderInterceptor {

    private final static byte[] callbackBytes = "callback(".getBytes();

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {

    int howMany = callbackBytes.length;

    InputStream x = context.getInputStream();

    if( !(x.available() >= howMany) ) {
        return context.proceed();
    }

    x.mark( howMany );
    byte[] preamble = new byte[ howMany ];
    x.read( preamble );

    // In case the first part of our entity doesn't have the callback String, reset the stream so downstream exploiters get the full entity.
    if( !Arrays.equals( preamble, callbackBytes ) ) {
        x.reset();
    } 

    return context.proceed();
}
像这样使用:

Client c = ClientBuilder.newBuilder()
    .register( new CallbackStripInterceptor() )
    .build();

使用此客户端,所有带有实体的响应都将通过此拦截器(Jersey不会对没有实体实体的响应运行拦截器)。

我尝试使用自定义反序列化器,但在调用反序列化方法之前引发异常。