I've come across a problem of using Gson library and generic types(my types and collections). However they have an answer how to solve this problem, I don't think it's appropriate to write a specific message converter for the every type I've already implemented and I'll implement.
What I did is:
Implemented my own message converter:
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; } }
It works well until I try to send a collection like List<String> or some Type<T>.
Gson has the solutions here: http://sites.google.com/site/gson/gson-user-guide
Also I tried the json-lib library yesterday. What I don't like about it is in-depth scanning of all objects which I have in the hierarchy. I tried to change the cycle detection strategy from CycleDetectionStrategy.STRICT to CycleDetectionStrategy.LENIENT, it didn't help at all!
@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)); } Finally, a work-around for the generic collection's problem was found out: changing from ArrayList to simple array helps to do serialization and deserialization. To be more specific you have to do it in a web-service, which you use in an application.
@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); } So this approach is working good.
I failed to found out what a solution for generic type is. I really do hate an idea to write a new converter every time I implement a new generic type.
If you know any possible solution I'd appreciate your help a lot!
I'd be on the cloud nine if anyone could help me :)
L.