Лучший способ сделать JSON красивым на Java - PullRequest
0 голосов
/ 12 марта 2019

У меня есть список объектов, возвращаемых в следующем формате (не очень).

{"data":[{"id":1,"firstName":"Bill","lastName":"Johnson"}]

Я бы хотел, чтобы это выглядело так (довольно).

{
    "data":[{
        "id":1,"
        firstName":"Bill",
        "lastName":"Johnson"
        }]
}

Это моя подпись метода, а также мой вызов службы для запроса БД и возвратаэто выводит JSON на экран.

public @ResponseBody ResponseEntity<ResponseData<List<NameSearchDTO>>> getInfo(@PathVariable String code, @PathVariable String idType)

ResponseData<List<NameSearchDTO>> response = new ResponseData<>();

List<NameSearchDTO> results = officeService.getByCode(code, idType); 
if (!results.isEmpty()) {
            response.setData(results);
            response.setStatus(Enum.SUCCESS.getDescription());
            response.setMessage(Enum.STATUS_SUCCESS.getDescription());
return new ResponseEntity<>(response, HttpStatus.OK);
}

Класс ResponseData реализует Serializable.Означает ли это, что это «настоящий» JSON, поскольку я не использую Джексона или любую другую библиотеку JSON?

Как передать ответ в приведенный ниже ObjectMapper, чтобы сделать его красивым?

ObjectMapper jacksonMapper = new ObjectMapper();
jacksonMapper.configure(SerializationFeature.INDENT_OUTPUT, true);

Или мне нужно создать какой-то класс JSONHelper?

Класс ResponseData

public class ResponseData <E> implements Serializable{


    private E data;
    private String status;
    private String message;
    private boolean hasValidationError = false;

    public E getData() {
        return data;
    }

    public void setData(E data) {
        this.data = data;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public boolean getHasValidationError(){
        return hasValidationError;
    }

    public void setHasValidationError(boolean hasValidationError){
        this.hasValidationError = hasValidationError;
    }
}

Ответы [ 6 ]

2 голосов
/ 12 марта 2019

Вы можете определить

  • a MappingJacksonHttpMessageConverter (для Spring Boot не требуется)
  • a Jackson2ObjectMapperBuilder Боб
  • простой ObjectMapper Боб, помеченный @Primary
  • свойство конфигурации (Spring Boot - , перейдите к этому для простейшего ).

Для первого решения вам необходимо реализовать интерфейс WebMvcConfigurer
(пропустите его, если вы используете Spring Boot)

@Configuration
class CustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
        final ObjectMapper mapper =
                new Jackson2ObjectMapperBuilder()
                        .indentOutput(true)
                        .build();

        // Or build ObjectMapper without the Spring builder, it's the same thing
        converters.add(new MappingJackson2HttpMessageConverter(mapper));
    }
}

Ключ этой строки

indentOutput(true)

Что фактически управляет базовой ObjectMapper конфигурацией

public Jackson2ObjectMapperBuilder indentOutput(boolean indentOutput) {
    this.features.put(SerializationFeature.INDENT_OUTPUT, indentOutput);
    return this;
}

Второй немного проще

@Bean
Jackson2ObjectMapperBuilder jackson() {
   return new Jackson2ObjectMapperBuilder().indentOutput(true);
}

Третий еще проще, просто

@Bean
@Primary
ObjectMapper objectMapper() {
   final ObjectMapper mapper = new ObjectMapper();
   mapper.enable(SerializationFeature.INDENT_OUTPUT);  
   return mapper;
}

Четвертый способ заключается только в использовании свойства конфигурации

spring.jackson.serialization.indent_output=true
1 голос
/ 13 марта 2019

Нет необходимости импортировать кучу новых вещей. Только на какую систему можно пожаловаться (если есть). Но если вы уже используете Джексона и хотите использовать маппер -> просто используйте «readValue» или «writeValue», верно?

Эта ссылка объясняет множество способов сделать это: Примеры Джексона

Удалите присвоение результатов и используйте прямое преобразование с Mapper

ObjectMapper jacksonMapper = new ObjectMapper();
jacksonMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
List<NameSearchDTO> mappedResults = mapper.readValue(officeService.getByCode(code, idType) ,new TypeReference<List<NameSearchDTO>>() {} );

затем добавьте это к вашему возвращаемому результату. (кажется немного неуклюжим с этим добавленным контейнерным классом, но я не претендую на то, что знаю ваши требования).

if (!mappedResults.isEmpty()) {
            response.setData(mappedResults);
            response.setStatus(Enum.SUCCESS.getDescription());
            response.setMessage(Enum.STATUS_SUCCESS.getDescription());
return new ResponseEntity<>(response, HttpStatus.OK);
1 голос
/ 12 марта 2019

Я думаю, что лучший способ украсить строку json, используя Джексона:

import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(yourObject)
1 голос
/ 12 марта 2019

Я полагаю, вы ищете красивую функциональность печати Gson.Поскольку вы отметили свой вопрос с помощью gson, я предполагаю, что все в порядке, если вы используете библиотеку.У Mkyong есть отличный учебник по красивой печати Здесь .

Основная строка из учебника:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
1 голос
/ 12 марта 2019

Вы отметили gson, чтобы вы могли использовать эту библиотеку для отображения .json файла:

import org.json.JSONObject

val json = "{\"data\":[{\"id\":1,\"firstName\":\"Bill\",\"lastName\":\"Johnson\"}]\n"

val jsonObject = JSONObject(json)

println(jsonObject.toString(4))

https://github.com/google/gson

0 голосов
/ 12 марта 2019

Вы можете использовать toString (int indentFactor) из JSONObject

...