Ошибка в пользовательских сериализаторах / десериализаторах Джексона - PullRequest
2 голосов
/ 08 февраля 2012

для того, чтобы разобраться с проблемами в пользовательских сериализаторах / десериализаторах, я перенес это в другой проект это делает такую ​​ошибку

ОШИБКА / AndroidRuntime (288): java.lang.RuntimeException: невозможно запустить действие. ComponentInfo {com.example / com.example.MyActivity}: java.lang.UnsupportedOperationException: невозможно создать генератор для цели, не основанной на байтах

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

программные файлы:

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() + ")/");
  }
 }    
 }

и когда в My JsonWrapper.java использовать статический вместо 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 делает такую ​​ошибку

ОШИБКА / AndroidRuntime (314): java.lang.RuntimeException: Невозможно запустить действие ComponentInfo {com.example / com.example.MyActivity}: java.lang.UnsupportedOperationException: Невозможно создать генератор для ......

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

строка с ошибкой

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

Ответы [ 2 ]

2 голосов
/ 08 февраля 2012

Как указывалось, SmileFactory поддерживает двоичное кодирование Smile (см. на этой вики-странице ), которое имеет ту же структуру, что и JSON (но гораздо более компактно, быстрее обрабатывается), но не является текстовым и не JSON.Он должен быть записан как байты, а не как символы Java.

РЕДАКТИРОВАТЬ: 2018-06-19 - То же самое верно для всех кодеков двоичного формата - Avro, CBOR, Protobuf (и BSON через bson4jackson), MsgPack через jackson-dataformat-msgpack), а не только Smile.

Так что вместо этого используйте обычный JsonFactory, если вы хотите JSON;или, если вы хотите Smile, укажите цель в байтах: OutputStream является наиболее распространенным выбором (например, ByteArrayOutputStream).

2 голосов
/ 08 февраля 2012

Почему вы используете SmileFactory? Он не поддерживает чтение или запись в небайтные цели (в вашем случае вы пытаетесь читать из строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...