Spring mvc——接收對象Json數據,

1、基礎知識1

<context:annotation-config/>
向Spring容器註冊AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor這4個BeanPostProcessor。
註冊這4個BeanPostProcessor的作用,就是爲了你的系統能夠識別相應的註解。
-對於其他沒有在spring容器中註冊的bean,它不能起到註冊bean的作用。


<context:component-scanbase-package=”xx.xx”/>
可以指定package掃描,
可以自動將帶有@Autowired,@component,@service,@Repository等註解的對象註冊到spring容器中的功能
隱式地在內部註冊了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor


-因此當使用<context:component-scan/>後,除非需要使用PersistenceAnnotationBeanPostProcessor和RequiredAnnotationBeanPostProcessor兩個Processor的功能(例如JPA等)否則就可以將<context:annotation-config/>移除了。

雖然大多數文章都是這麼說,但是查看spring4的源代碼如下:

並且在源碼中也發現這個配置也包含了<context:annotation-config/>:

看過傳智播客對於spring的說明也是說<context:component-scan/>包含了<context:annotation-config/>。

<context:component-scanbase-package="com.baobaotao">
<context:include-filtertype="regex" expression="com\.baobaotao\.service\..*"/>
<context:exclude-filtertype="aspectj" expression="com.baobaotao.util..*"/>
</context:component-scan>

<mvc:annotation-driven/>
標籤可簡化springmvc的相關配置,默認情況下其會創建並註冊實例:
DefaultAnnotationHandlerMapping:處理器映射器@Controller(默認註冊)
AnnotationMethodHandlerAdapter-:處理器適配器
StringHttpMessageConverter
ByteArrayHttpMessageConverter
XmlAwareFormHttpMessageConverter
SourceHttpMessageConverter。
FormattingConversionServiceFactoryBean-:ConversionService類型轉換
NumberFormatAnnotationFormatterFactory:@NumberFormat格式化
JodaDateTimeFormatAnnotationFormatterFactory::@DateTimeFormat格式化
LocalValidatorFactoryBean:@Valid數據校驗

參考文章:

點擊打開鏈接


2、基礎知識2

<annotaion-driven/>標籤:
這個標籤對應的實現類是org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
仔細閱讀它的註釋文檔可以很明顯的看到這個類的作用。解析這個文檔:
這個類主要註冊8個類的實例:
1.RequestMappingHandlerMapping
2.BeanNameUrlHandlerMapping
3.RequestMappingHandlerAdapter
4.HttpRequestHandlerAdapter
5.SimpleControllerHandlerAdapter
6.ExceptionHandlerExceptionResolver
7.ResponseStatusExceptionResolver
8.DefaultHandlerExceptionResolver
1是處理@RequestMapping註解的,2.將controller類的名字映射爲請求url。1和2都實現了HandlerMapping接口,用來處理請求映射。
3是處理@Controller註解的控制器類,4是處理繼承HttpRequestHandlerAdapter類的控制器類,5.處理繼承SimpleControllerHandlerAdapter類的控制器。所以這三個是用來處理請求的。具體點說就是確定調用哪個controller的哪個方法來處理當前請求。
6,7,8全部繼承AbstractHandlerExceptionResolver,這個類實現HandlerExceptionResolver,該接口定義:接口實現的對象可以解決處理器映射、執行期間拋出的異常,還有錯誤的視圖。
所以<annotaion-driven/>標籤主要是用來幫助我們處理請求映射,決定是哪個controller的哪個方法來處理當前請求,異常處理。


<context:component-scan/>標籤:
它的實現類是org.springframework.context.annotation.ComponentScanBeanDefinitionParser.
把鼠標放在context:component-scan上就可以知道有什麼作用的,用來掃描該包內被@Repository @Service @Controller的註解類,然後註冊到工廠中。並且context:component-scan激活@ required。@ resource,@ autowired、@PostConstruct @PreDestroy @PersistenceContext @PersistenceUnit。使得在適用該bean的時候用@Autowired就行了。主要用於對實體的註解交給spring管理

參考文章:

點擊打開鏈接

3、正題:spring MVC中json格式數據的發送與接收

在web程序開發中,前端和服務器數據的傳輸方式常用的有兩種,一種是以表單的形式提交,此時可以利用jquery的serialize()方法將表單內容轉爲a=1&b=2&c=3&d=4&e=5這樣的格式傳輸過去,接收端則可以用javabean直接接收。
還有一種方式是以json格式傳輸,接收時若直接用bean接收則接收不到,此時應該用@RequestBody方式,需要注意的是接收的需要是json串,而不是json對象,可以在發送前使用JSON.stringify函數進行處理。(我用的是google的Gson,效果是一樣的)

經過嘗試經常出現:

SpringMVC @RequestBody 自動轉json Http415錯誤

經過一通查,多半的解決方法實說header裏的 Content-Type 一定 application/json
但是問題依然沒有解決。
最後在《Spring in Action》裏找到一個信息
有兩個前提條件:
The request’sContent-Type header must be set toapplication/json.
The JacksonJSON library must be available on the application’s classpath. 
我滿足了第一個,所以在classpath中添加了一個jar。問題解決了。

<dependency>  
    <groupId>org.codehaus.jackson</groupId>  
    <artifactId>jackson-mapper-asl</artifactId>  
    <version>1.9.8</version>  
    <type>jar</type>  
</dependency>  
所以如果大家遇到了同樣的問題,可以先排除一下這兩個因素。
------------------------------
還有一種情況,在以上兩個條件都滿足的情況下,還是報同樣的錯誤。
在springmvc的配置文件中必須有:
<!-- 默認的註解映射的支持 -->  
<mvc:annotation-driven />  
如果沒有這個配置也是會報這個錯的!


最後需要注意的是

1,在xxx-serverlet配置文件中應該寫上,以便可以使用 @ResponseBody和@RequestBody
2,發送時要寫上 contentType:'application/json'
3,數組內容要用[]而不是list,用list會接收到一個map對象,而不是bean

參考文章:

點擊打開鏈接

點擊打開鏈接


如果還是解決不了上述問題,因爲我的spring版本比較新是4.+的,而我發現jackson-mapper的最新版本也只是2013年的,因此,我覺得這個方案可能已經被棄用了,因此我加入了這個包:

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.3.1</version>
</dependency>
測試是通過的。

其實,最開始我用的是google的Gson,也是可以的。但是查了下資料,大多數測試證明jackson的性能要比gson好,因此準備入手jackson。


對於實體對象的Json形式接收就先寫到這裏了,下面會開始研究數組形式的接收。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章