简体   繁体   English

Jackson自定义序列化器/反序列化器中的错误

[英]Error in Jackson custom Serializers/Deserializers

in order to sort out the problems in the custom Serializers/Deserializers I carried out it to another project it make such a mistake 为了解决自定义序列化程序/反序列化程序中的问题,我将其执行到另一个项目中,导致出现这样的错误

ERROR/AndroidRuntime(288): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MyActivity}: java.lang.UnsupportedOperationException: Can not create generator for non-byte-based target 错误/ AndroidRuntime(288):java.lang.RuntimeException:无法启动活动ComponentInfo {com.example / com.example.MyActivity}:java.lang.UnsupportedOperationException:无法为基于非字节的目标创建生成器

http://i.imgur.com/hOFYI.jpg http://i.imgur.com/hOFYI.jpg

program files: 程序文件:

MyActivity.java MyActivity.java

package com.example;

import android.app.Activity;
import android.os.Bundle;
import com.example.JacksonObject;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.JsonGenerationException;
import java.io.IOException;

public class MyActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

String jacksonString = "{\"DateField\":\"/Date(61283424600000)/\",\"StringField\":\"STRING_string\",\"DoubleField\":\"87.12345\",\"IntegerField\":\"387\"}";
try {
    MyJsonWrapper sss = new MyJsonWrapper();

    JacksonObject[] mailItems2 = sss.getMyJson().readValue(jacksonString, JacksonObject[].class);
    int a2 = 3;  //это просто так, что бы поставить точки!!!
    int  b = a2; //это просто так, что бы поставить точки!!!

}   catch (JsonGenerationException e) {

    e.printStackTrace();

} catch (JsonMappingException e) {

    e.printStackTrace();

} catch (IOException e) {

    e.printStackTrace();

}
int a = 3; //это просто так, что бы поставить точки!!!
int s = 10; //это просто так, что бы поставить точки!!!
s = s + a; //это просто так, что бы поставить точки!!!
}
}

JacksonObject.java JacksonObject.java

package com.example;

import java.util.Date;

public class JacksonObject
{
public Date DateField;
public String StringField;
public Double DoubleField;
public int IntegerField;
}

MyJsonWrapper.java MyJsonWrapper.java

package com.example;

import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.map.module.SimpleModule;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.smile.*;
import org.codehaus.jackson.*;
import org.codehaus.jackson.map.ser.*;
import org.codehaus.jackson.map.ser.std.NullSerializer;
import org.codehaus.jackson.map.deser.*;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Date;

public class MyJsonWrapper
{

public ObjectMapper getMyJson()
{
ObjectMapper mapper = new ObjectMapper(new SmileFactory());        
SimpleModule module = new SimpleModule("MyModule", new Version(1, 0, 0, null));

module.addSerializer(Date.class, new JsonDateSerializer());
module.addDeserializer(Date.class, new JsonDateDeserializer());

mapper.registerModule(module);

return mapper;
}

public class JsonDateDeserializer extends JsonDeserializer<Date>
{

public Date deserialize(JsonParser jp, DeserializationContext context) throws IOException, JsonProcessingException
{
    try {

    String s = jp.getText().replace("/Date(", "").replace(")/", "");

    if (s.equals("")) return null;

    boolean isDateBefore1970 = false;

    ............................................

    if (isDateBefore1970)
        return new Date(-Long.valueOf(s) - offset * 60 * 1000);
    else
        return new Date(Long.valueOf(s) + offset * 60 * 1000);

    }catch (JsonMappingException e){
        // If a JSON Mapping occurs, simply returning null instead of blocking things
        return null;
    }

  }
  }

  public class JsonDateSerializer extends JsonSerializer<Date>
 {
   public void serialize(Date date, JsonGenerator jgen, SerializerProvider provider)   throws IOException, JsonProcessingException
  {            
    jgen.writeString("/Date(" + date.getTime() + ")/");
  }
 }    
 }

and when in My JsonWrapper.java use static instead of public 在My JsonWrapper.java中使用static而不是public时

 public class MyJsonWrapper
{
 public static ObjectMapper getMyJson()
{        
ObjectMapper mapper = new ObjectMapper(new SmileFactory());        
SimpleModule module = new SimpleModule("MyModule", new Version(1, 0, 0, null));

module.addSerializer(Date.class, new JsonDateSerializer());
module.addDeserializer(Date.class, new JsonDateDeserializer());

mapper.registerModule(module);

return mapper;
}

static class JsonDateDeserializer extends JsonDeserializer<Date>
{

public Date deserialize(JsonParser jp, DeserializationContext context) throws IOException, JsonProcessingException
{
    try {

tnen it makes such a mistake 可能会犯这样的错误

ERROR/AndroidRuntime(314): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MyActivity}: java.lang.UnsupportedOperationException: Can not create generator for ...... 错误/ AndroidRuntime(314):java.lang.RuntimeException:无法启动活动ComponentInfo {com.example / com.example.MyActivity}:java.lang.UnsupportedOperationException:无法为......创建生成器

http://i.imgur.com/dohnz.jpg http://i.imgur.com/dohnz.jpg

line with the error 符合错误

JacksonObject[] mailItems2 = sss.getMyJson().readValue(jacksonString, JacksonObject[].class);

Why are you using SmileFactory ? 为什么要使用SmileFactory It doesn't support reading from or writing to non-byte targets (in your case you're trying to read from a string). 它不支持读取或写入非字节目标(在您的情况下,您尝试从字符串读取)。

As pointed out, SmileFactory supports binary Smile encoding (see this wiki page ), which has same structure as JSON (but much more compact, faster to process), but is not textual and not JSON. 如前所述,SmileFactory支持二进制Smile编码(请参阅此wiki页 ),它具有与JSON相同的结构(但更紧凑,处理速度更快),但不是文本格式,也不是JSON。 It must be written as bytes, and not as Java characters. 它必须写为字节,而不是Java字符。

EDIT: 2018-06-19 -- Same is true for all binary format codecs -- Avro, CBOR, Protobuf (and BSON via bson4jackson , MsgPack via jackson-dataformat-msgpack ), not just Smile. 编辑:2018-06-19-所有二进制格式编解码器都是如此-Avro,CBOR,Protobuf(以及通过bson4jackson BSON,通过jackson-dataformat-msgpack ),而不仅仅是Smile。

So use regular JsonFactory instead if you want JSON; 因此,如果需要JSON,请改用常规的JsonFactory; or, if you do want Smile, provide byte target: OutputStream is the most common choice (like ByteArrayOutputStream ). 或者,如果您确实想要Smile,请提供字节目标: OutputStream是最常见的选择(例如ByteArrayOutputStream )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM