我已经编写了一个SpringBoot应用程序,该应用程序使用了一个REST API并提出了一个REST API。我的模型pojo具有camelCase命名的属性。应用程序使用的json具有under_score属性名称。应用程序生成的json具有under_score属性名称。我想使用一个PropertyNamingStrategy,它将在编组/解组期间自动在Java和json名称之间进行转换。
我有Java配置,试图设置可以处理此问题的命名策略。
/** * Configuration for Rest api. * <p> * Created by emurphy on 2/25/16. */ @Configuration public class RestConfig { /** * Bean to make jackson automatically convert from * camelCase (java) to under_scores (json) in property names * * @return ObjectMapper that maps from Java camelCase to json under_score names */ @Bean public ObjectMapper jacksonObjectMapper() { return new ObjectMapper().setPropertyNamingStrategy(new UpperCaseUnderscoreStrategy()); } /** * Property naming strategy that converts both ways between camelCase and under_score * property names. */ public static class UpperCaseUnderscoreStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase { /** * Converts camelCase to under_score and * visa versa. The idea is that this * name strategy can be used for both * marshalling and unmarshaling. * * For example, "userName" would be converted to * "user_name" and conversely "user_name" would * be converted to "userName". * * @param input formatted as camelCase or under_score string * @return input converted to opposite format */ @Override public String translate(String input) { if (input == null || input.length() == 0) { return input; // garbage in, garbage out } // // we always take the first character; // this preserves initial underscore // StringBuilder sb = new StringBuilder(); final int length = input.length(); int i = 0; // // skip initial underscores // while ((i < length) && ('_' == input.charAt(i))) { sb.append(input.charAt(i)); i += 1; } while (i < length) { // // find underscores, remove and capitalize next letter // while ((i < length) && ('_' != input.charAt(i)) && !Character.isUpperCase(input.charAt(i))) { sb.append(input.charAt(i)); i += 1; } if(i < length) { if('_' == input.charAt(i)) { // underscore to uppercase // // skip underscores // while ((i < length) && ('_' == input.charAt(i))) { // skip underscores i += 1; } // // capitalize // if (i < length) { sb.append(Character.toUpperCase(input.charAt(i))); i += 1; } } else // uppercase to unscore + lowercase { sb.append('_'); sb.append(Character.toLowerCase(input.charAt(i))); i += 1; } } } return sb.toString(); } }
我可以看到当我的rest服务将Java pojos转换为json作为响应时,将调用命名策略的translation方法。但是,当我通过RestTemplate使用rest api时,看不到调用此方法,并且无法从传入的json正确初始化我生成的pojo;名称需要翻译的所有属性均为null。这迫使我在大多数属性上使用@JsonProperty。我有很多特性和很多pojos- 这是SpringBoot应该提供的非常优雅的样板解决方案。有没有办法设置RestTemplate将用来将传入的json名称从under_score转换为camelCase的PropertyNamingStrategy?
谢谢你的帮助。
创建时,RestTemplate您需要将设置objectMapper为。另外,您应该将自定义ObjectMapper声明为a,@Bean以便由Spring将其构造为单例并为您管理。对进行相同的操作PropertyNamingStrategy,而不是对其进行“更新”并声明该类为静态类。
RestTemplate
objectMapper
@Bean
PropertyNamingStrategy
public class RestConfig { /** * Bean to make jackson automatically convert from * camelCase (java) to under_scores (json) in property names * * @return ObjectMapper that maps from Java camelCase to json under_score names */ @Bean public ObjectMapper jacksonObjectMapper() { return new ObjectMapper().setPropertyNamingStrategy(propertyNamingStrategy()); } @Bean public PropertyNamingStrategy propertyNamingStrategy() { return new UpperCaseUnderscoreStrategy(); } @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); List<HttpMessageConverter<?>> messageConverters = new ArrayList<>(); MappingJackson2HttpMessageConverter jsonMessageConverter = new MappingJackson2HttpMessageConverter(); jsonMessageConverter.setObjectMapper(jacksonObjectMapper()); messageConverters.add(jsonMessageConverter); restTemplate.setMessageConverters(messageConverters); return restTemplate; } }
您的课程在单独的文件中吗?它不需要是静态的。
/** * Property naming strategy that converts both ways between camelCase and under_score * property names. */ public static class UpperCaseUnderscoreStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase { /** * Converts camelCase to under_score and * visa versa. The idea is that this * name strategy can be used for both * marshalling and unmarshaling. * * For example, "userName" would be converted to * "user_name" and conversely "user_name" would * be converted to "userName". * * @param input formatted as camelCase or under_score string * @return input converted to opposite format */ @Override public String translate(String input) { if (input == null || input.length() == 0) { return input; // garbage in, garbage out } // // we always take the first character; // this preserves initial underscore // StringBuilder sb = new StringBuilder(); final int length = input.length(); int i = 0; // // skip initial underscores // while ((i < length) && ('_' == input.charAt(i))) { sb.append(input.charAt(i)); i += 1; } while (i < length) { // // find underscores, remove and capitalize next letter // while ((i < length) && ('_' != input.charAt(i)) && !Character.isUpperCase(input.charAt(i))) { sb.append(input.charAt(i)); i += 1; } if(i < length) { if('_' == input.charAt(i)) { // underscore to uppercase // // skip underscores // while ((i < length) && ('_' == input.charAt(i))) { // skip underscores i += 1; } // // capitalize // if (i < length) { sb.append(Character.toUpperCase(input.charAt(i))); i += 1; } } else // uppercase to unscore + lowercase { sb.append('_'); sb.append(Character.toLowerCase(input.charAt(i))); i += 1; } } } return sb.toString(); } }