簡體   English   中英

GSON和通用類型

[英]GSON and Generic types

我遇到了使用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.STRICTCycleDetectionStrategy.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更改為簡單數組有助於進行序列化和反序列化。 更具體地說,您必須在應用程序中使用的Web服務中進行操作。

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

有一些方法可以傳遞java.lang.reflect.Type 如果指定的對象是泛型類型,則這些方法很有用,例如:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM