GSON и универсальные типы - PullRequest
2 голосов
/ 02 марта 2011

Я столкнулся с проблемой использования библиотеки Gson и универсальных типов (мои типы и коллекции).Однако у них есть ответ, как решить эту проблему, я не думаю, что было бы целесообразно написать конкретный конвертер сообщений для каждого типа, который я уже реализовал, и я буду реализовывать.

Что я сделал:

Реализовал свой собственный конвертер сообщений:

public class SuperHttpMessageConverter extends AbstractHttpMessageConverter<Object> {

private final Charset charset;
private final Gson gson;

public CostomHttpMC_1(MediaType mediaType, String charset) {
    super(mediaType);
    this.charset = Charset.forName(charset);
    gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
}

@Override
protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException {
    String jsonString = FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
    return gson.fromJson(jsonString, clazz);
}

@Override
protected Long getContentLength(Object obj, MediaType contentType) {
    try {
        String jsonString = gson.toJson(obj);
        return (long) jsonString.getBytes(charset.name()).length;
    } catch (UnsupportedEncodingException ex) {
        throw new InternalError(ex.getMessage());
    }
}

@Override
protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException {
    String jsonString = gson.toJson(obj);
    FileCopyUtils.copy(jsonString, new OutputStreamWriter(outputMessage.getBody(), charset));
}

@Override
public boolean supports(Class<?> clazz) {
    return true;
}

}

Работает хорошо, пока я не попытаюсь отправить коллекцию какList<String> или some Type<T>.

Здесь у Gson есть решения: http://sites.google.com/site/gson/gson-user-guide

Также я вчера попробовал библиотеку json-lib.Что мне не нравится в этом, так это глубокое сканирование всех объектов, которые у меня есть в иерархии.Я попытался изменить стратегию обнаружения циклов с CycleDetectionStrategy.STRICT на CycleDetectionStrategy.LENIENT, это не помогло вообще!

    @Override
protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException {
    JsonConfig jsonConfig = new JsonConfig();  
    jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
    String jsonString = JSONObject.fromObject( obj ).toString();
    FileCopyUtils.copy(jsonString, new OutputStreamWriter(outputMessage.getBody(), charset));
}

Наконец, был найден обходной путь для проблемы универсального набора: изменениеот ArrayList до простого массива помогает выполнять сериализацию и десериализацию.Чтобы быть более конкретным, вы должны сделать это в веб-сервисе, который вы используете в приложении.

   @RequestMapping(value = "/country/info/{code}")
public void info(@PathVariable("code") String code, Model model) {

//list
    StuffImpl[] stuffList= new StuffImpl[0]; <-- this is the array I used!
stuffList= restTemplate.getForObject("http://localhost:8084/yourApp/restService/stuff", stuffList.getClass());
model.addAttribute("stuffList", stuffList);
}

Так что этот подход работает хорошо.

Мне не удалось выяснить, чторешение для универсального типа есть.Я действительно ненавижу идею писать новый конвертер каждый раз, когда я реализую новый универсальный тип.

Если вы знаете какое-либо возможное решение, я был бы очень признателен за вашу помощь!

Я был бы в облаке девять, если бы кто-нибудь мог мне помочь:)

L.

1 Ответ

1 голос
/ 02 марта 2011

Есть несколько методов, где вы можете передать java.lang.reflect.Type. Эти методы полезны, если указанный объект является универсальным типом, например ::10000

Gson gson = new GsonBuilder().create();

List<String> names = new ArrayList<String>();
names.add("Foo");
names.add("Bar");

// marshal
String jsonLiteral = gson.toJson(names);
System.out.println(jsonLiteral);

// unmarshal
List<String> names2;
Type type = new TypeToken<List<String>>() {
}.getType();
names2 = gson.fromJson(jsonLiteral, type);
System.out.println(names2.get(0));
System.out.println(names2.get(1));

Будет выведено:

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