일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- airflow
- docker
- MAC address
- Vision
- JavaScript
- zookeeper
- aws s3
- grafana
- Operating System
- Spring
- Packet
- EC2
- log
- Network
- AWS
- CSV
- CVAT
- kubeadm
- PostgreSQL
- kubectl
- Trino
- ip
- Kafka
- java
- helm
- tcp
- Python
- kubernetes
- OS
- jvm
- Today
- Total
JUST WRITE
MappingJackson2JsonView 본문
MappingJackson2JsonView
MappingJackson2JsonView는 org.springframework.web.servlet.view의 하위 클래스입니다.
View를 Json 타입 View로 변환할 때 사용합니다.
MappingJackson2JsonView 동작
Spring에서는 Request가 들어오면 web.xml에 정의된 DispatcherServlet에서 가장 먼저 처리한다.
몇 가지 가정을 거치고 Handler(Controller)에서 처리한 결과물을 DispatcherServlet에서 받는다.
그럼 그 결과물을 ViewResolver가 View Template에 맞게 렌더링 한다.
processDispatchResult() -> render() -> view.render()
render()
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
//localeResolver를 통하여 locale 설정
Locale locale = this.localeResolver.resolveLocale(request);
response.setLocale(locale);
View view;
if (mv.isReference()) {
// 뷰 설정이 레퍼런스라면(String 이라면, viewResolver를 통한
view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
if (view == null) {
throw new ServletException("Could not resolve view with name '" + mv.getViewName() +
"' in servlet with name '" + getServletName() + "'");
}
} else {
// No need to lookup: the ModelAndView object contains the actual View object.
view = mv.getView();
if (view == null) {
throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
"View object in servlet with name '" + getServletName() + "'");
}
}
// 뷰 (View) 구현체에 위임하여 렌더링을 하도록 한다.
if (logger.isDebugEnabled()) {
logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
}
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
//ViewResolver에서 반환할 View 구현체에 의해 렌더링
view.render(mv.getModelInternal(), request, response);
} catch (Exception ex) {
//예외 처리 생략
}
}
MappingJackson2JsonView render()
MappingJackson2JsonView는 AbstractJackson2View를 상속받아 정의한 Class이다.
AbstractJackson2View Class의 renderMergedOutputModel Method를 실행한다.
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
OutputStream stream = (this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream());
Object value = filterAndWrapModel(model, request);
// Stream에 JSON String 넣기
writeContent(stream, value);
if (this.updateContentLength) {
writeToResponse(response, (ByteArrayOutputStream) stream);
}
}
writeContent Method를 통해 Stream에 JSON String을 생성한다.
protected void writeContent(OutputStream stream, Object object) throws IOException {
JsonGenerator generator = this.objectMapper.getFactory().createGenerator(stream, this.encoding);
writePrefix(generator, object);
Class<?> serializationView = null;
FilterProvider filters = null;
Object value = object;
if (value instanceof MappingJacksonValue) {
MappingJacksonValue container = (MappingJacksonValue) value;
value = container.getValue();
serializationView = container.getSerializationView();
filters = container.getFilters();
}
if (serializationView != null) {
this.objectMapper.writerWithView(serializationView).writeValue(generator, value);
} else if (filters != null) {
this.objectMapper.writer(filters).writeValue(generator, value);
} else {
this.objectMapper.writeValue(generator, value);
}
writeSuffix(generator, object);
generator.flush();
}
wrtieToResponse Method에서 ContentType, ContentLength 2가지 값을 Response Header에 설정한다.
protected void writeToResponse(HttpServletResponse response, ByteArrayOutputStream baos) throws IOException {
// Write content type and also length (determined via byte array).
response.setContentType(getContentType());
response.setContentLength(baos.size());
// Flush byte array to servlet output stream.
ServletOutputStream out = response.getOutputStream();
baos.writeTo(out);
out.flush();
}
MappingJackson2JsonView 사용
Jackson Library
Jackson Libary는 Java Object -> JSON, JSON -> Java Object로 변환하는 데 사용하는 Java Library입니다.
- Stream API => Stream 형식이라 성능 좋음
- Tree Model => Node 형태로 데이터 다룰 수 있어 유연성 좋음
- Data Binding => POJO 기반의 Java 객체들을 JSON 변환
Dependency 추가
Jackson-databind Library를 추가합니다.
Jackson-databind Library는 jackson-core, jackson-annotaion Libarary 의존성을 포함합니다.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
ServletContext에 Bean 등록
ServletContext에 MappingJackson2JsonView객체를 jsonView라는 이름으로 Bean 등록한다.
<bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
<property name="contentType" value="text/html;charset=UTF-8"/>
</bean>
위에서 정의한 'jsonView' 이름의 Bean을 View객체로 사용하기 위해서 BeanNameViewResolver를 정의한다.
<bean id="beanNameResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="0"/>
</bean>
Controller에서 해당 View를 사용하도록 한다.
@Controller
public class JsonDataController {
...
public ModelAndView exec(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
// returnMap이 JSON String으로 변환해서 Response로 보낼 Java Object
return new ModelAndView ("jsonView", returnMap);
}
...
}
[참고사이트]
'Programing > Spring' 카테고리의 다른 글
@Autowired (0) | 2021.10.22 |
---|---|
DispatcherSerlvet (0) | 2021.10.15 |
Singleton Registry (0) | 2021.10.02 |
Bean LifeCycle (0) | 2021.09.29 |
Spring Bean Scopes (0) | 2021.09.28 |