Я столкнулся с проблемой использования библиотеки 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.