Springmvc知識五------處理JSON&國際化&文件上傳

處理JSON

對於JSON的處理一般都是基於Ajax前端技術來實現的,可以實現頁面的局部刷新數據顯示。
在Springmvc處理JSON是非常簡單的。
分爲三步走:
一、前臺提交請求Ajax
二、後臺處理請求@ResponseBody
三、前臺接收返回的JSON數據 dataType

<!-- 前臺提交請求 一般都是利用ajax -->
<a href="testJson" id="testjson">Test JSON</a>
$(function(){
    $("#testjson").click(function(){
        var url= this.href;
        var args= {};
        $.ajax({
            url:url,  
            type:'post', 
            dataType:'json',
            success:function(data){ 
                for(var i=0;i<data.length;i++){
                    var id= data[i].id;
                    var lastName=data[i].lastName;
                    alert(id+":"+lastName);
                    //$("#two").append(data);
                    }
                }
        }); 
        return false;
    });
})


<!-- 後臺處理 -->

// 測試JSON  注意返回的數據
    @ResponseBody
    @RequestMapping("/testJson")
    public Collection<Employee> testJson(){
        System.out.println("test JSON");
        return employeeDAO.getAll();
    }

注意:進行ajax數據提交的時候,在後臺我們的數據不能再存放在Map集合中了,這是因爲,存放Map集合中 的數據需要進行頁面刷新或者頁面跳轉才能顯示數據,而我們利用的Ajax異步傳輸。
注意:我們返回的值,直接是我們前臺所需要的數據。而不再需要進行視圖渲染,所以我們也是添加了註解@ResponseBody

Jackson簡介

JackSon框架類似於json-lib框架(struts2提供了集成json-lib的插件),都是講Java對象與JSON對象之間的轉換。但是相比json-lib框架,Jackson所依賴的jar包較少。

Jackson可以輕鬆的將Java對象轉換成json對象和xml文檔,同樣也可以將json、xml轉換成Java對象。
對於Jackson來講,只需要導入三個jar包就可以實現JSON的轉換【jackson-databind-2.4.0】【jackson-core-2.4.0】【jackson-annotations-2.4.0】,所以在我們編寫上面代碼時,不要忘記進行jar包的導入。
jackson 框架提供了JsonGenerator ,ObjectMapper兩個類通過這兩個類提供的方法可以將java 對象轉化爲json 對象,json 數組格式,也可以將json對象、數組格式轉化爲java對象。

HttpMessageConverter基礎概念

爲什麼能夠處理JSON ,對於Spring3.0 ,新增了一個接口HttpMessageConverter[T],這個接口負責將請求轉化爲一個對象(類型爲T),將對象(類型爲T)輸出爲響應信息。
HttpMessageConverter[T]接口中定義了一些方法(在代碼中可以搜索HttpMessageConverter進行查看):
boolean canRead(Class[ ? ] clazz, MediaType mediaType)】:指定轉換器可以讀取的對象類型,即轉換器是否可以將請求信息轉化爲Clazz類型的對象,同時指定支持MIEI類型(text/html,application/json等)。

boolean canWrite(Class[ ? ] clazz, MediaType mediaType)】:指定轉換器是否可以將Clazz類型的對象寫入到響應流中,響應流支持的媒體類型在MediaType中定義。

List[MediaType] getSupportedMediaTypes()】:該轉換支持的媒體類型。

T read(Class[? extends T] clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException 】:將請求信息流轉化爲T類型的對象。

void write(T t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException】:將T類型的對象寫到響應流中,同時指定相信的媒體類型爲contentType

HttpMessageConverter工作原理流程 查看【HttpInputMessage】和【HttpOutputMessage】
這裏寫圖片描述

HttpMessageConverter接口的實現類
這裏寫圖片描述

查看Springmvc裝配了那些實現類。
在我們測試的testJSON方法中打上斷點,debug之後,我們可以向前找到dispatchServlet,然後變量域中找到【this】【handlerAdapters】【elementData中的RequestMappingHandlerAdapter】【MessageConverters】
這裏寫圖片描述

HttpMessageConverter使用方式

使用HttpMessageConverter[T]能做些什麼呢? 使用這個我們可以將請求信息轉化並綁定到處理方法的入參中,或者,響應結果轉化爲對應類型的響應信息注意是請求信息的處理和轉化爲對應的類型的響應信息,spring 提供了兩種路徑:
使用【@ResponseBody】和【@RequestBody】對處理方法進行標註
使用【HttpEntity[T]】和【ResponseEntity[T]】作爲處理方法的入參和返回值。
當控制器處理的方法使用到上述四個註解時,Spring 首先根據請求頭和響應頭的Accept屬性(HTTP協議)選擇匹配的HttpMessageConverter(上面的默認實現類),進而根據參數類型或者泛型類型的過濾得到匹配的HttpMessageConverter,如果找不到可用的如果找不到可用的將報錯。
【@ResponseBody】和【@RequestBody】【HttpEntity[T]】和【ResponseEntity[T]】不需要成對出現。

@RequestBody 將HTTP請求正文轉換爲適合的HttpMessageConverter對象。
@ResponseBody 將內容或對象作爲 HTTP 響應正文返回,並調用適合HttpMessageConverter的Adapter轉換對象,寫入輸出流。

實例一 讀取文件內容。類似於上傳效果的使用:

<!--前臺提交數據 -->
<form action="testHttpMessageConverter" method="post" enctype="multipart/form-data">
        File:<input type="file" name="file"/><br>
        Desc:<input type="text" name="desc"/>
        <input type="submit" value="submit">
    </form>
<!-- 後臺進行處理 -->

 // 類似於上傳工作 
//此時利用的是StringHttpMessageConverter 將請求信息轉換爲字符串
    @RequestMapping("/testHttpMessageConverter")
    public String testHttpMessageConverter(@RequestBody String body){
        System.out.println(body);
        return "Hello HttpMessage"+new Date();
    }

實例二 實現文件下載

<!-- 前臺數據連接 -->
<a href="TestResponseEntity">TestResponseEntity</a>

<!-- 後臺數據處理下載 -->

@RequestMapping("/TestResponseEntity")  //  類似於下載
    public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException{
        byte []body=null;
        ServletContext context = session.getServletContext();
        InputStream in = context.getResourceAsStream("/files/abc.txt");
        body = new byte[in.available()];

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment;filename=abc.txt");
        // 設置響應頭 爲下載
        HttpStatus stateCode = HttpStatus.OK;

        ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body,headers,stateCode);
        return response;    
    }

國際化

默認情況下,Springmvc會根據請求中的Accept-Language參數判斷客戶端的本地化類型(HTTP協議)。當接受到請求時Springmvc會在上下文找一個本地化解析器(LocalResolver),找到後使用他獲取請求所對應的本地化類型信息。Springmvc還允許裝配一個動態更改本地化類型的攔截器。這也是我們所在springmvc.xml中所配置的文件,這樣就通過指定一個請求參數就可以控制單個請求的本地化類型。

本地化解析器和本地化攔截器

【AcceptHeaderLocaleResolver】:根據http請求頭的Accept-Language確定本地化類型,Springmvc使用該解析器。
【CookieLocaleResolver】:指定的cookie值確定本地化類型。
【SessionLocalResolver】:根據session中特定的屬性確定本地化類型。
【LocaleChangeInterceptor】:從請求參數中獲取本次請求對應的本地化類型。
他們在配置文件中進行使用。

關於國際化

作用:
1、在頁面上能夠根據瀏覽器語言設置的情況對文本(不是內容),時間,數值進行本地化處理
2、 可以在bean中獲取國際化資源文件,Locale 對應的消息(使用時注意配置文件要關閉)
3、 可以通過超鏈接切換Locale (切換語言) 而不用瀏覽器的語言設置情況

解決
1、 使用JSTL 的fmt 標籤,對國際化字段進行顯示。
2、 在bean中注入ResourceBundleMessageSource的實例,使用其對應的getMessage方法即可
3、 配置SessionLocaleResource 和LocaleChangeInterceptor
注意上述的作用和解決方案一一對應

        <!-- spring.xml配置文件 -->

        <!-- 配置國際化資源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n"></property>
</bean>

        <!-- 配置 SessionLocaleResolver -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
    </bean>


        <!-- 配置攔截器   LocaleChangeInterceptor-->
    <mvc:interceptors>
        <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        </bean>
    </mvc:interceptors>


<!--直接跳轉到頁面,不經過Controller  -->
<!-- <mvc:view-controller path="/i18n" view-name="i18n" />  獲取資源時,利用Controller 所以屏蔽  -->
<mvc:view-controller path="/i18n2" view-name="i18n2" />




        <!-- 前臺鏈接一 -->

<a href="i18n"> I18N Page </a> //  第一頁面 index.jsp 跳轉第二頁面

        <!-- 前臺鏈接二 -->                  //  第二頁面 i18n.jsp 注意上面的直接跳轉配置
<fmt:message key="i18n.username"></fmt:message> // 國際化顯示

<a href="i18n2"> I18N2 Page </a>
<br>

<a href="i18n?locale=zh_CN"> 中文 </a>
<br>
<a href="i18n?locale=en_US"> English</a>
<br>


        <!-- 前臺鏈接三 -->                  //  第三頁面 i18n2.jsp 

<fmt:message key="i18n.password"></fmt:message>
<a href="i18n"> I18N Page </a>


        <!-- 後臺處理代碼 --> 

    @Autowired
    private ResourceBundleMessageSource messageSource;
    @RequestMapping("/i18n")
    public String Testi18n(Locale locale){  // Locale 入參
        String val = messageSource.getMessage("i18n.username", null, locale);
        System.out.println(val);
        return "i18n";
    }

這裏寫圖片描述

文件上傳

對於文件上傳Springmvc提供了直接的支持!這種支持是通過即插即用的MultipartResolver,Springmvc用Jakarta Commons FileUpload技術實現了一個【MultipartResolver】實現類:【CommonsMultipartResolver】。

Springmvc 上下文中默認沒有裝配【MultipartResolver】因此,默認情況下事不能處理文件的上傳工作。如果想使用Springmvc的文件上傳功能,需要在上下文進行配置【MultipartResolver】。

分爲四步走:

第一步:加入jar包
第二步:配置文件
第三步:前臺文件提交
第四步:後臺數據處理

第一步:加入jar包
由於我們使用Jakarta Commons FileUpload技術,所以我們要加入需要的jar包【commons-fileupload-1.2.1】【commons-io-2.0.1】注意fileupload依賴io所以也要進行加入

第二步:配置文件:


    <!--文件的上傳  -->

    <!-- 配置  CommonsMultipartResolver 具體的屬性配置去源碼中查看,注意編碼的問題  -->    
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"></property>
        <property name="maxUploadSize" value="1024000000000"></property>
    </bean>

可配置屬性
這裏寫圖片描述

第三步:前臺文件提交

<p>FileUpload</p>
    <form action="TestFileUpload" method="post" enctype="multipart/form-data">
        File:<input type="file" name="file01"/><br>
        Desc:<input type="text" name="desc01"/>
        <input type="submit" value="submit">
    </form>

第四步:後臺數據處理
利用入參MultipartFile 類型用來接收文件的相關信息

@RequestMapping("/TestFileUpload")
    public String TestFileUpload(@RequestParam(value="desc01",required=false) String desc,
                                    @RequestParam("file01") MultipartFile file ) throws Exception{
        //參數MultipartFile 用來傳遞文件的相關信息
        System.out.println("desc:"+desc);
        System.out.println("OriginalFilename"+file.getOriginalFilename());
        System.out.println("getInputStream"+file.getInputStream());
        InputStream inputStream = file.getInputStream();

        if(file.isEmpty()){
            file.transferTo(new File("d:\\"+file.getOriginalFilename()));
            //  文件寫入地點
        } 
        return "success";
    }

注意的是HttpMessageConverter是不能做文件上傳的,但是他能分辨出那個是文件

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