簡體   English   中英

Spring MVC Rest Controller @RequestBody解析

[英]Spring MVC Rest Controller @RequestBody Parsing

我有一個spring rest網絡應用程序,其中包含一個通用的rest控制器,如下所示。 傑克遜將對象序列化為JSON后,GET方法運行良好。 但是,當我嘗試調用save方法時,RequestBody參數將轉換為LinkedHashMap,而不是T泛型類型定義的類型。

@RestController
public abstract class CrudAPI<T extends Object, ID extends Serializable>{

    @Transactional
    @RequestMapping(method = RequestMethod.POST, consumes = "application/json")
    public ResponseEntity<Void> save(@RequestBody T entity){
        service.save(entity);
        return new ResponseEntity(HttpStatus.CREATED);
    }

}

JSON:

{
   "id":null,
   "version":null,
   "name":"Copel",
   "disabled":false,
   "type":"P",
   "labels":[
      {
         "id":null,
         "version":null,
         "name":"unidade consumidora"
      }
   ]
}

我收到以下錯誤:

HTTP狀態500-請求處理失敗; 嵌套的異常是org.springframework.beans.NotReadablePropertyException:Bean類[java.util.LinkedHashMap]的無效屬性“版本”:在回退訪問期間找不到屬性字段!

Spring配置:

@Configuration
@Import(Application.class)
@EnableWebMvc
@ComponentScan(basePackages = {"br.com.doc2cloud"})
public class WebConfig extends WebMvcConfigurerAdapter implements WebApplicationInitializer {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    private MappingJackson2HttpMessageConverter jacksonConverter() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Hibernate5Module());
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.setDateFormat(new ISO8601DateFormat());
        mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
        mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
        jacksonConverter.setObjectMapper(mapper);

        return jacksonConverter;
    }

 @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(jacksonConverter());
        super.configureMessageConverters(converters);
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.setInitParameter("javax.servlet.jsp.jstl.fmt.localizationContext", "messages");
        EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        FilterRegistration.Dynamic characterEncoding = servletContext.addFilter("characterEncoding", characterEncodingFilter);
        characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
    }
}

我的代碼有什么問題?

我認為您無法實現自己想要的。 Java泛型機制僅在編譯時有效。 編譯后,泛型類型將被擦除,並由實際類型替換(在您的情況下為Object )。 您的控制器無法理解您嘗試解析JSON數據的類型。

之所以獲得LinkedHashMap是因為Jackson默認將其用於“未知”類型。 典型的JSON數據實際上是鍵值映射,而Jackson保留屬性排序-這就是使用鏈接的哈希映射的原因。

您正在使用哪個版本的Jackson? 我升級到2.7.3,並且在使用泛型時(我具有具有保存,列出等通用邏輯的基本控制器)時遇到了相同的問題。 回滾到2.6.5允許我繼續使用通用基類。 我尚未研究問題的原因,但回滾為我解決了該問題。

暫無
暫無

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

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