【问题标题】:Spring - Problem converting a pojo to a JSON (No converter found error)Spring - 将 pojo 转换为 JSON 时出现问题(未找到转换器错误)
【发布时间】:2018-09-16 11:38:51
【问题描述】:

春季 4.3.3

我正在尝试将 Pojo 转换为 JSON,将 Controller 标记为
@RestController,问题在于某些元素的首字母小写而不是大写,

Ex:
"Id": 1, //This is ok  
"customerId": "1234", //Instead of CustomerId, this has customerId
...

控制器

@RestController
...
public class CustomerController{
    ...
    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public CustomerResponse postCustomerRequest(final HttpServletRequest request) { 

我希望它是大写的。 pojo 基本上是一个从 xsd 生成的 xjc 类,它包含,

@XmlElement(name = "Id")
protected int id;
@XmlElement(name = "CustomerId")
protected String customerId;
...
    public int getId() {
        return id;
    }
    public void setId(int value) {
        this.id = value;
    }
    public String getCustomerId() {
        return customerId;
    }
    public void setCustomerId(String value) {
        this.customerId = value;
    }

这对每个属性都有关联的setter、getter。在控制器中,我也将 ObjectMapper 不区分大小写设置为 true,

mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); 

我也试过,将Controller标记为@Controller而不是@RestController,在方法之前提供@ResponseBody,

控制器

@Controller
...
public class CustomerController {
...
    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    @ResponseBody
    public String postCustomerRequest(HttpServletRequest request) {
        ...

//Used PropertyNamingStrategy with the ObjectMapper, converted the first character to an upper case, 
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
            ...
            CustomerResponse response=createCustomer(document,objectFactory);
            mapperObj.setPropertyNamingStrategy(new CustomerJsonNameStrategy());
            String jsonOutput = mapperObj.writeValueAsString(response);
            return jsonOutput;

如果我在 Eclipse 中调试期间看到 jsonOutput 的值,它会以正确的大小写输出 json 元素,但对其余客户端的响应如下:

{"errors": [{
   "message": "No converter found for return value of type: class java.lang.String",
   "type": "IllegalArgumentError"
}]}

看起来杰克逊序列化器正在干扰响应并引发上述错误。

解决办法是什么?

【问题讨论】:

    标签: java spring hybris


    【解决方案1】:

    Spring 使用 Jackson 将 POJO 转换为 json。默认情况下,Jackson 使字段名称的第一个字母变小。如果您想要自定义名称,请添加以下杰克逊注释。

    @JsonProperty("CustomerId")
    private String customerId; 
    

    【讨论】:

      【解决方案2】:

      @Consumes 在这种情况下对您没有多大帮助。它应该用于指定输入的格式。检查这篇文章: http://www.javainterviewpoint.com/jax-rs-rest-consumes-example/

      如果您在调试期间可以看到 jsonOutput,则您的问题可能与您的客户端期望输出的方式有关:您的客户端可能期望 JSON 而不是 String 对象。 解决方案:返回 CustomerResponse 而不是 String。

      @RestController
      ...
      public class CustomerController {
        ...
        public CustomerResponse postCustomerRequest(final HttpServletRequest request) 
      {
      

      如果您想更改默认命名,则 CustomerResponse 的字段应使用 @JsonProperty 注释。

      @JsonProperty(name = "Id")
      protected int id;
      
      @JsonProperty(name = "CustomerId")
      protected String customerId;
      

      【讨论】:

        【解决方案3】:

        我将使用您的自定义属性命名策略配置MappingJackson2HttpMessageConverter,在恕我直言,与在每个控制器方法中序列化为 json 相比,这是更清洁的解决方案

        <mvc:annotation-driven>
            <mvc:message-converters>
                ...
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper" ref="objectMapper"/>
                </bean>
                ...
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
        
        <bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
            <property name="propertyNamingStrategy" ref="customNamingStrategy" />
        </bean
        

        或者,如果您确实想要或需要控制响应正文,请确保 StringHttpMessageConverter 在您的 spring MVC 配置中注册为转换器

        <mvc:annotation-driven>
             <mvc:message-converters>
                    ...
                    <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
                    ...
           </mvc:message-converters>
        </mvc:annotation-driven>
        

        【讨论】:

          【解决方案4】:

          我通过移动到没有杰克逊设置的扩展使其工作。 PS:这是在 SAP Hybris 和 它包含多个扩展/项目。

          我用@Controller标记了Controller,添加了@Produces({MediaType.APPLICATION_JSON}),删除了@ResponseBody,将方法返回类型设置为ResponseEntity, 使用 PropertyNamingStrategy 将首字母转换为大写。

          public ResponseEntity<String> postCustomerRequest(final HttpServletRequest request) {
              ...
              final org.codehaus.jackson.map.ObjectMapper mapperObj = new org.codehaus.jackson.map.ObjectMapper();
              CustomerResponse response=createCustomer(document,objectFactory);
              mapperObj.setPropertyNamingStrategy(new CustomerJsonNameStrategy());
          
              final HttpHeaders httpHeaders= new HttpHeaders();
              httpHeaders.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
              return new ResponseEntity<String>(mapperObj.writeValueAsString(response), httpHeaders, HttpStatus.OK);
          
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-04-17
            • 2021-05-03
            • 1970-01-01
            • 2019-07-06
            • 1970-01-01
            • 1970-01-01
            • 2015-12-25
            • 2016-12-18
            相关资源
            最近更新 更多