簡體   English   中英

當您在rest調用中公開接口RequestBody時,如何將json反序列化為java對象?

[英]How to deserialize json to java object, when you expose interface RequestBody in rest call?

我有以下項目結構作為Maven項目:

Project 1 -> Core-part(having interface) :

interface Foo{

  public String getStr1();
  public setStr1(String str1);

  public List<? extends Bar> getBarList();
  public setBarList(List<? extends Bar> barList);
}

interface Bar{
   public String getStr2();
   public setStr2(String str2);
}

項目2-> Impl-part(已實現)

Public class FooImpl implements Foo{
  private String str1;
  private List<? extends Bar> barList;

  public String getStr1(){
      return str1;
  }
  public setStr1(String str1){
    this.str1= str1;
  }
  public List<? extends Bar> getBarList(){
    return barList;
  }
  public setBarList(List<? extends Bar> barList){
    this.barList= barList;
  }

}

Public class BarImpl implements Bar{
  private String str2;

  public String getStr2(){
      return str2;
  }
  public setStr2(String str2){
    this.str2= str2;
  }
}

項目3->休息部分(有休息電話)

@RestController
public class BaseDataController {

  @RequestMapping(method=RequestMethod.POST,value="/save")
  public Foo saveFoo(@RequestBody Foo foo) {
        return foo;

  }
}

核心部分JA​​R包含在impl-part中,而impl-part JAR包含在Rest-part中,並且我部署Rest-part WAR文件。

我在rest調用中返回相同的對象,但是在調用此函數時會出錯。 我試圖通過以下代碼為Foo接口注冊反序列化器:

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
  @Bean
  @Primary
  public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter jsonConverter = new  MappingJackson2HttpMessageConverter();
    ObjectMapper objectMapper = new ObjectMapper();

    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addDeserializer(Demo.class, new FooDeserializer());
    simpleModule.addDeserializer(Demo.class, new BarDeserializer());
    objectMapper.registerModule(simpleModule);
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    jsonConverter.setObjectMapper(objectMapper);
    return jsonConverter;
  }

FooDeserializer如下:

public class FooDeserializer extends JsonDeserializer<Foo> {

  @Override
  public Foo deserialize(JsonParser jp, DeserializationContext    context) throws IOException {
       ObjectMapper mapper = (ObjectMapper) jp.getCodec();
       ObjectNode root = mapper.readTree(jp);
       return mapper.readValue(root.toString(),  FooImpl.class);
  }
}

public class BarDeserializer extends JsonDeserializer<Bar> {

  @Override
  public Bar deserialize(JsonParser jp, DeserializationContext    context) throws IOException {
       ObjectMapper mapper = (ObjectMapper) jp.getCodec();
       ObjectNode root = mapper.readTree(jp);
       return mapper.readValue(root.toString(),  BarImpl.class);
  }
}

這段代碼無法解決我的問題,並且在將json轉換為對象時引發錯誤。 我應該怎么做才能解決這個問題。

如果我將接口作為另一個接口的成員,該如何解決。 當我嘗試在其余層項目中注冊此解串器時。

我為此發布的請求:

POST /save HTTP/1.1
Host: XXX
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: XXX

{  
   "str1":"aaa",
   "barList":[  
  {  
     "str2":"bbb"
  }
  ]
}

我只是最小化了這個細節,實際數據會增加。

我得到的錯誤是:

abstract types either need to be mapped to concrete types, have custom  deserializer, or contain additional type information\n at [Source:   java.io.PushbackInputStream@32e11e31; line: 6, column: 7]

首先,它是@RestController 然后,您缺少注釋:

@RestController
public class BaseDataController {

  @RequestMapping(method=RequestMethod.POST,value="/save")
  public Demo saveDemo(@RequestBody DemoImpl demo) {
        return demo;

  }
}

從以下位置更改JSON:

{
    "Demo":"aaa" 
}

{
    "demo":"aaa" 
}

您的請求應如下所示:

POST /save HTTP/1.1
Host: XXX
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: XXX

{  
   "demo":"aaa"
}

您必須完全通過預期的實現。 Demo更改為DemoImpl

 @RestController
public class BaseDataController {

  @RequestMapping(method=RequestMethod.POST,value="/save")
  public DemoImpl saveDemo(@RequestBody DemoImpl demo) {
        return demo;

  }
}

根據聊天中的討論,問題在於存在不同的Demo實現。 可能的解決方案可能是:

 @RestController
public class BaseDataController {

  @RequestMapping(method=RequestMethod.POST,value="/save/impl1")
  public DemoImpl1 saveDemo(@RequestBody DemoImpl1 demo) {
        return demo;

  }

  @RequestMapping(method=RequestMethod.POST,value="/save/impl2")
  public DemoImpl2 saveDemo(@RequestBody DemoImpl2 demo) {
        return demo;

  }
}

暫無
暫無

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

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