티스토리 뷰
요청 값 처리에 대한 설정 부분입니다.
요청 문자열에 대한 type converter 설정
Json 관련 설정(json to object, object json)
1. 요청 문자열에 대한 type converter 설정
@Autowired(required = false)
private Converter<?, ?>[] converters;
@Override
public void addFormatters(FormatterRegistry registry) {
if(converters != null) {
for(final Converter<?, ?> converter : converters) {
registry.addConverter(converter);
}
}
NumberStyleFormatter numberFormatter = new NumberStyleFormatter();
numberFormatter.setPattern("#,###,###,###.##");
registry.addFormatter(numberFormatter);
}
이 부분은 이전에 설명했던 부분으로 타입에 따른 Converter 설정 부분입니다.
git에 간단한 converter 몇 가지를 추가했으니 참고하시면 좋을 거 같습니다.
2. Json 관련 설정(json to object, object json)
요청시 request body에 json 형태로 값을 전달하고 객체에 매핑하는 경우 특정 규칙이 필요할 수 있습니다.
RestController에서 결과 객체를 반환할 때 json으로 변환 시 업무적인 특성에 따라 메시지 컨버팅을 해야 하는 경우가 있습니다.
위와 같은 예에서 사용자 정의 컨버터를 통해 구현 할 수 있습니다.
일반적으로 ObjectMapper를 이용해 MappingJackson2HttpMessageConverter를 생성합니다.
ObjectMapper 참고 : https://eblo.tistory.com/62
관련 설정
@Bean
public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
jsonConverter.setObjectMapper(ObjectMapperUtil.getObjectMapper());
return jsonConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(customJackson2HttpMessageConverter());
super.addDefaultHttpMessageConverters(converters);
}
ObjectMapper는 Utility 클래스가 아닌 스프링빈으로도 많이 사용합니다.
아래 유틸 클래스에 objectMapper() 부분을 @Configuration에 @Bean으로 추가하면 됩니다.
그런데 @Bean이 injection 받아서 쓰기는 좋으나 테스트 클래스나 유틸 클래스에서 스프링 Context와 상관없이 쓰고자 할때는 불편합니다. 그래서 일부러 Util에 구현했습니다.
위에 configureMessageConverters() 설정만으로 설정은 끝입니다.
@UtilityClass
public class ObjectMapperUtil {
private static final ObjectMapper objectMapper = objectMapper();
private ObjectMapper objectMapper() {
ObjectMapper om = new ObjectMapper();
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // unknown field 무시
// 매핑시 필드만 사용.
om.setVisibility(om.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
om.setSerializationInclusion(Include.NON_EMPTY); // 빈 값 제거
//om.enable(SerializationFeature.WRAP_ROOT_VALUE); // root를 사용할 때
//om.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); // root로 값을 넘길 때 사용.
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer());
simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer());
simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
simpleModule.addSerializer(Date.class, new DateSerializer());
simpleModule.addDeserializer(Date.class, new DateDeserializer());
simpleModule.addSerializer(Timestamp.class, new TimestampSerializer());
simpleModule.addDeserializer(Timestamp.class, new TimestampDeserializer());
simpleModule.addSerializer(String.class, new StringTrimSerializer());
simpleModule.addDeserializer(String.class, new StringTrimDeserializer());
om.registerModule(simpleModule);
return om;
}
public static ObjectMapper getObjectMapper() {
return objectMapper;
}
public static String getJsonString(Object obj) {
try {
if(obj != null) return objectMapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> T getObject(String jsonStr, Class<T> type) {
try {
return objectMapper.readValue(jsonStr, type);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
public static <T> T getObjectFromFile(String filePath, Class<T> type){
try {
return objectMapper.readValue(new File(filePath), type);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static void saveStringToJsonFile(Object json, String jsonFilePath) {
File file = new File(jsonFilePath);
try(FileOutputStream fileOutputStream = new FileOutputStream(file, false)){
ObjectWriter writer = objectMapper.writer(new DefaultPrettyPrinter());
writer.writeValue(fileOutputStream, json);
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
어떤 경우 유용할까요?
요청 사항
결과값
- 정의된 것이 값이 없더라도 다 나와야 한다.
- null 인경우 "" 값으로 내려와야 한다.
- 모든 값은 쌍따옴표로 감싸야 한다.
- 특정 필드는 Currency 형태로 표현 필요하다.
요청값
- 숫자 필드에 콤마가 들어 갈 수 있으니 제거하고 매핑해야 한다.
위와 같은 경우 타입별 serializer, deserializer 개발하여 추가해 줌으로써 해결 가능합니다.
git에 간단하게 구현한 Serializer, Deserializer 예제 들이 있으니 참고하시면 좋을 거 같습니다.
'study > springboot' 카테고리의 다른 글
017. Logback 설정 (0) | 2022.05.20 |
---|---|
016. 스프링부트 Profile 설정 (0) | 2022.05.19 |
014. Jackson 직렬화 어노테이션 (0) | 2022.05.17 |
013. Content-type, Accept를 통한 요청 및 결과 처리 (0) | 2022.05.16 |
012. Request Parameter에 converter 및 formatter 전체 적용 (0) | 2022.05.14 |
- Total
- Today
- Yesterday
- cache
- UI
- 스프링부트
- Javascript
- mybatis
- ag grid
- 예제
- oracle
- Spring Boot
- mapToList
- 스프링
- 메시지
- thymeleaf
- restful서비스
- SHEETJS
- 그리드
- lombok
- 샘플
- spring
- 엑셀
- 타임리프
- 설정
- sample
- RESTful
- REST
- listToMap
- AG-GRID
- example
- springboot
- java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |