简体   繁体   中英

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

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

program files:

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

package com.example;

import java.util.Date;

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

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

 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 ......

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

line with the error

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

Why are you using 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. It must be written as bytes, and not as Java characters.

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.

So use regular JsonFactory instead if you want JSON; or, if you do want Smile, provide byte target: OutputStream is the most common choice (like ByteArrayOutputStream ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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