Spring - проблема преобразования pojo в JSON (ошибка не найдена) - PullRequest
0 голосов
/ 16 сентября 2018

весна 4.3.3

Я пытаюсь преобразовать Pojo в JSON, помечая контроллер как
@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 - это, в основном, класс, сгенерированный xjc из xsd, и он содержит

@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;
    }

Это связано с сеттером, геттером для каждого атрибута.В Контроллере я получил значение ObjectMapper без учета регистра также равным true,

mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); 

Я также попытался, пометив Контроллер как @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;

Если я вижу значение jsonOutput во время отладки в Eclipse, он выводит элементы json в правильном случае, но ответ остальному клиенту приходит как,

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

Похоже, сериализатор Джексона вмешивается в ответ и выдает вышеуказанную ошибку.

Какое решение для этого?

Ответы [ 4 ]

0 голосов
/ 17 сентября 2018

Я заставил его работать, перейдя на расширение, которое не имеет настройки Джексона. PS: это в SAP Hybris и он содержит несколько расширений / проектов.

Я пометил Контроллер @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);

}
0 голосов
/ 16 сентября 2018

@ Потребление не очень вам поможет в этом случае. Он должен использоваться для указания формата ввода. Проверьте эту статью: 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;
0 голосов
/ 17 сентября 2018

Я бы настроил 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 зарегистрирован как конвертер в вашей весенней конфигурации MVC, если вы действительно хотите или должны контролировать тело ответа

<mvc:annotation-driven>
     <mvc:message-converters>
            ...
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            ...
   </mvc:message-converters>
</mvc:annotation-driven>
0 голосов
/ 16 сентября 2018

Spring использует Джексона для преобразования POJO в JSON.Джексон по умолчанию делает первую букву названия поля маленькой.Если вам нужны нестандартные имена, добавьте следующую аннотацию Джексона.

@JsonProperty("CustomerId")
private String customerId; 
...