iT邦幫忙

DAY 13
0

無痛學習SpringMVC與Spring Security系列 第 13

[Controller/View]資料直接輸出JSON以及XML格式(II, @ResponseBody/HttpMessageConverter/@RestController)

今天繼續介紹透過@ResponseBody及HttpMessageConverter,來直接輸出JSON/XML格式,在dispatchservletcontext.xml中已有宣告<mvc: annotation-driven>,故自Spring 3.1開始@RequestMapping底下新增兩個classes, RequestMappingHandlerMapping以及RequestMappingHandlerAdapter,支援更多handler method,其中包含@RequestBody來存取HTTP request body的資訊,同時也有對應之@ResponseBody來輸出HTTP body資訊,RequestMappingHandlerAdapter預設支援許多HttpMessageConverter,包含今日的主角:

對於上述兩種Converters,且無需特別在宣告bean或是其他設定,僅需在pom.xml加入Jackson相關的depnency

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>${jackson.json.version}</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.4.0</version>
</dependency>

 <properties>
 	<jackson.json.version>2.4.3</jackson.json.version>
  </properties>

Jackson的library基本上都提供ObjectMapper以及XmlMapper,讓開發者省去很多功夫來使Domain Object轉換成JSON或是XML

接著新增@ResponseBody code到Controller,@RequestMapping中有個參數"produces",用來指定HTTP Content-type,如application/json或是application/xml,新增的code如下:

@Controller
@RequestMapping("/dcn")
public class DCNController {
	
	@Autowired
	private DCNRepository dcnRepository;
	
	......
	
	@RequestMapping(value="/jsonformat", produces="application/json")
	public @ResponseBody List<DCN> restDCNListJson(Model model){
		return dcnRepository.findAll();
	}
	@RequestMapping(value="/xmlformat", produces="application/xml")
	public @ResponseBody List<DCN> restDCNListXml(Model model){
		return dcnRepository.findAll();
	}
}

啟動Sever,JSON部分擷取畫面如下:

Console log,如下:

21:25:35 [http-nio-8080-exec-8] DispatcherServlet - DispatcherServlet with name 'dispatcher' processing GET request for [/SpringMVC/dcn/jsonformat]
21:25:35 [http-nio-8080-exec-8] RequestMappingHandlerMapping - Looking up handler method for path /dcn/jsonformat
21:25:35 [http-nio-8080-exec-8] RequestMappingHandlerMapping - Returning handler method [public java.util.List<tw.blogger.springtech.springmvc.model.DCN> tw.blogger.springtech.springmvc.controller.DCNController.restDCNListJson(org.springframework.ui.Model)]
21:25:35 [http-nio-8080-exec-8] DispatcherServlet - Last-Modified value for [/SpringMVC/dcn/jsonformat] is: -1
Hibernate: select dcn0_.prikey as prikey1_0_, dcn0_.category as category2_0_, dcn0_.completedDate as complete3_0_, dcn0_.issuedDate as issuedDa4_0_, dcn0_.no as no5_0_, dcn0_.rev as rev6_0_, dcn0_.trackNumber as trackNum7_0_ from DCN dcn0_
21:25:36 [http-nio-8080-exec-8] ResponseBodyAdviceChain - Invoking ResponseBodyAdvice chain for body=[tw.blogger.springtech.springmvc.model.DCN@1823e868, tw.blogger.springtech.springmvc.model.DCN@409a120d, tw.blogger.springtech.springmvc.model.DCN@24154162]
21:25:36 [http-nio-8080-exec-8] ResponseBodyAdviceChain - After ResponseBodyAdvice chain body=[tw.blogger.springtech.springmvc.model.DCN@1823e868, tw.blogger.springtech.springmvc.model.DCN@409a120d, tw.blogger.springtech.springmvc.model.DCN@24154162]
21:25:36 [http-nio-8080-exec-8] RequestResponseBodyMethodProcessor - Written [[tw.blogger.springtech.springmvc.model.DCN@1823e868, tw.blogger.springtech.springmvc.model.DCN@409a120d, tw.blogger.springtech.springmvc.model.DCN@24154162]] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@c52170c]
21:25:36 [http-nio-8080-exec-8] DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
21:25:36 [http-nio-8080-exec-8] DispatcherServlet - Successfully completed request

XML部分畫面擷取如下:

Console log如下:

21:26:47 [http-nio-8080-exec-4] DispatcherServlet - DispatcherServlet with name 'dispatcher' processing GET request for [/SpringMVC/dcn/xmlformat]
21:26:47 [http-nio-8080-exec-4] RequestMappingHandlerMapping - Looking up handler method for path /dcn/xmlformat
21:26:47 [http-nio-8080-exec-4] RequestMappingHandlerMapping - Returning handler method [public java.util.List<tw.blogger.springtech.springmvc.model.DCN> tw.blogger.springtech.springmvc.controller.DCNController.restDCNListXml(org.springframework.ui.Model)]
21:26:47 [http-nio-8080-exec-4] DispatcherServlet - Last-Modified value for [/SpringMVC/dcn/xmlformat] is: -1
Hibernate: select dcn0_.prikey as prikey1_0_, dcn0_.category as category2_0_, dcn0_.completedDate as complete3_0_, dcn0_.issuedDate as issuedDa4_0_, dcn0_.no as no5_0_, dcn0_.rev as rev6_0_, dcn0_.trackNumber as trackNum7_0_ from DCN dcn0_
21:26:47 [http-nio-8080-exec-4] ResponseBodyAdviceChain - Invoking ResponseBodyAdvice chain for body=[tw.blogger.springtech.springmvc.model.DCN@5fcb7e73, tw.blogger.springtech.springmvc.model.DCN@14317e8c, tw.blogger.springtech.springmvc.model.DCN@6968d7da]
21:26:47 [http-nio-8080-exec-4] ResponseBodyAdviceChain - After ResponseBodyAdvice chain body=[tw.blogger.springtech.springmvc.model.DCN@5fcb7e73, tw.blogger.springtech.springmvc.model.DCN@14317e8c, tw.blogger.springtech.springmvc.model.DCN@6968d7da]
21:26:47 [http-nio-8080-exec-4] RequestResponseBodyMethodProcessor - Written [[tw.blogger.springtech.springmvc.model.DCN@5fcb7e73, tw.blogger.springtech.springmvc.model.DCN@14317e8c, tw.blogger.springtech.springmvc.model.DCN@6968d7da]] as "application/xml" using [org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter@7403a366]
21:26:47 [http-nio-8080-exec-4] DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
21:26:47 [http-nio-8080-exec-4] DispatcherServlet - Successfully completed request

另外在Spring 4.0以後新增@RestController,簡單說就是@Controller與@ResponseBody的結合,以下兩者code是等同的

@Controller
@ResponseBody
@RequestMapping("/dcn")
public class DCNController {
}

@RestController
@RequestMapping("/dcn"){
}

新增一個class RestDCNController,把DCNController中的@ResponseBody拿到,其餘code不便,URL mapping換一下來測試看看

@RestController
@RequestMapping("/rest")
public class RestDCNController {
	
        @Autowired
	private DCNRepository dcnRepository;
	
	
	@RequestMapping(value="/json", produces="application/json")
	public List<DCN> restDCNListJson(Model model){
		return dcnRepository.findAll();
	}
	@RequestMapping(value="/xml", produces="application/xml")
	public List<DCN> restDCNListXml(Model model){
		return dcnRepository.findAll();
	}
}

啟動Server,JSON畫面如下

console log:

21:27:29 [http-nio-8080-exec-6] DispatcherServlet - DispatcherServlet with name 'dispatcher' processing GET request for [/SpringMVC/rest/json]
21:27:29 [http-nio-8080-exec-6] RequestMappingHandlerMapping - Looking up handler method for path /rest/json
21:27:29 [http-nio-8080-exec-6] RequestMappingHandlerMapping - Returning handler method [public java.util.List<tw.blogger.springtech.springmvc.model.DCN> tw.blogger.springtech.springmvc.controller.RestDCNController.restDCNListJson(org.springframework.ui.Model)]
21:27:29 [http-nio-8080-exec-6] DispatcherServlet - Last-Modified value for [/SpringMVC/rest/json] is: -1
Hibernate: select dcn0_.prikey as prikey1_0_, dcn0_.category as category2_0_, dcn0_.completedDate as complete3_0_, dcn0_.issuedDate as issuedDa4_0_, dcn0_.no as no5_0_, dcn0_.rev as rev6_0_, dcn0_.trackNumber as trackNum7_0_ from DCN dcn0_
21:27:29 [http-nio-8080-exec-6] ResponseBodyAdviceChain - Invoking ResponseBodyAdvice chain for body=[tw.blogger.springtech.springmvc.model.DCN@186f644, tw.blogger.springtech.springmvc.model.DCN@6b5a008f, tw.blogger.springtech.springmvc.model.DCN@1f2d7726]
21:27:29 [http-nio-8080-exec-6] ResponseBodyAdviceChain - After ResponseBodyAdvice chain body=[tw.blogger.springtech.springmvc.model.DCN@186f644, tw.blogger.springtech.springmvc.model.DCN@6b5a008f, tw.blogger.springtech.springmvc.model.DCN@1f2d7726]
21:27:29 [http-nio-8080-exec-6] RequestResponseBodyMethodProcessor - Written [[tw.blogger.springtech.springmvc.model.DCN@186f644, tw.blogger.springtech.springmvc.model.DCN@6b5a008f, tw.blogger.springtech.springmvc.model.DCN@1f2d7726]] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@c52170c]
21:27:29 [http-nio-8080-exec-6] DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
21:27:29 [http-nio-8080-exec-6] DispatcherServlet - Successfully completed request

XML部分​畫面如下

Console log:

21:28:18 [http-nio-8080-exec-7] DispatcherServlet - DispatcherServlet with name 'dispatcher' processing GET request for [/SpringMVC/rest/xml]
21:28:18 [http-nio-8080-exec-7] RequestMappingHandlerMapping - Looking up handler method for path /rest/xml
21:28:18 [http-nio-8080-exec-7] RequestMappingHandlerMapping - Returning handler method [public java.util.List<tw.blogger.springtech.springmvc.model.DCN> tw.blogger.springtech.springmvc.controller.RestDCNController.restDCNListXml(org.springframework.ui.Model)]
21:28:18 [http-nio-8080-exec-7] DispatcherServlet - Last-Modified value for [/SpringMVC/rest/xml] is: -1
Hibernate: select dcn0_.prikey as prikey1_0_, dcn0_.category as category2_0_, dcn0_.completedDate as complete3_0_, dcn0_.issuedDate as issuedDa4_0_, dcn0_.no as no5_0_, dcn0_.rev as rev6_0_, dcn0_.trackNumber as trackNum7_0_ from DCN dcn0_
21:28:18 [http-nio-8080-exec-7] ResponseBodyAdviceChain - Invoking ResponseBodyAdvice chain for body=[tw.blogger.springtech.springmvc.model.DCN@7c8517df, tw.blogger.springtech.springmvc.model.DCN@750cc881, tw.blogger.springtech.springmvc.model.DCN@2d2d4035]
21:28:18 [http-nio-8080-exec-7] ResponseBodyAdviceChain - After ResponseBodyAdvice chain body=[tw.blogger.springtech.springmvc.model.DCN@7c8517df, tw.blogger.springtech.springmvc.model.DCN@750cc881, tw.blogger.springtech.springmvc.model.DCN@2d2d4035]
21:28:18 [http-nio-8080-exec-7] RequestResponseBodyMethodProcessor - Written [[tw.blogger.springtech.springmvc.model.DCN@7c8517df, tw.blogger.springtech.springmvc.model.DCN@750cc881, tw.blogger.springtech.springmvc.model.DCN@2d2d4035]] as "application/xml" using [org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter@7403a366]
21:28:18 [http-nio-8080-exec-7] DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
21:28:18 [http-nio-8080-exec-7] DispatcherServlet - Successfully completed request

使用@ResonseBody或是@RestController真的是相當方便

明天接著繼續介紹....


上一篇
[Controller/View]資料直接輸出JSON以及XML格式(I, ContentNegotiatingViewResolver)
下一篇
[Controller]使用@PathVariable以及@RequestParam存取網頁特定網址
系列文
無痛學習SpringMVC與Spring Security31

尚未有邦友留言

立即登入留言