Spring MVC Rest Controller @RequestBody Parsing
我有一个SpringRestWeb应用程序,它包含一个通用的REST控制器,如下所示。让Jackson将对象序列化为JSON,get方法工作得很好。但是,当我尝试调用save方法时,RequestBody参数将被转换为LinkedHashMap,而不是T泛型类型定义的类型。
1 2 3 4 5 6 7 8 9 10 11 | @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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | { "id":null, "version":null, "name":"Copel", "disabled":false, "type":"P", "labels":[ { "id":null, "version":null, "name":"unidade consumidora" } ] } |
号
我得到以下错误:
HTTP Status 500 - Request processing failed; nested exception is
org.springframework.beans.NotReadablePropertyException: Invalid
property 'version' of bean class [java.util.LinkedHashMap]: Could not
find field for property during fallback access!
号
弹簧配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | @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泛型机制仅在编译时起作用。编译后,泛型类型将被删除并替换为实际类型(在您的情况下为
之所以得到
你用的是哪个版本的杰克逊?我升级到2.7.3,当使用泛型(我有一个基本控制器,具有用于保存、列出等的公共逻辑)时,我遇到了同样的问题。回滚到2.6.5允许我继续使用泛型基类。我还没有研究出这个问题的原因,但回头帮我解决了。