在Spring MVC中,如何處理JSON對象,並對Spring MVC框架中的數據轉換與數據格式化進行介紹(SSMchapter12)

使用@ResponseBody實現數據輸出,進行Aajx異步驗證

    @RequestMapping(value="/ucexist.html")
    @ResponseBody
    public Object userCodeIsExit(@RequestParam String userCode){
        logger.debug("userCodeIsExit userCode===================== "+userCode);
        HashMap<String, String> resultMap = new HashMap<String, String>();
        if(StringUtils.isNullOrEmpty(userCode)){
            resultMap.put("userCode", "exist");
        }else{
            User user = userService.selectUserCodeExist(userCode);
            if(null != user)
                resultMap.put("userCode", "exist");
            else
                resultMap.put("userCode", "noexist");
        }
        //將其轉換爲JSON對象,進行返回輸出
        return JSONArray.toJSONString(resultMap);
    }
在上述代碼中,控制器的處理方法userCodelsExit(),通過前臺傳遞過來的userCode進行入參,最後返回Object。在方法體內,調用後臺的userService.selectUserCodeExist(userCode)進行同名驗證,並返回結果user對象。對於驗證結果,我們把他放在HashMap裏,最後通過調用JSONArray.toJSONString(resultMap)方法,將其轉化爲JSON對象,進行返回輸出。
這裏的@ResponseBody註解的作用是將標註該註解的處理方法的返回結果直接寫入HTTP  ResponseBody(Response對象的body數據區)中。一般的情況下,@ResponseBody都會在異步獲取數據時使用,被其標註的處理方法返回的數據將輸出的響應流中,客戶端獲取並顯示數據。
    /*
     * 驗證
     * 失焦\獲焦
     * jquery的方法傳遞
     */
    userCode.bind("blur",function(){
        //ajax後臺驗證--userCode是否已存在
        $.ajax({
            type:"GET",//請求類型
            url:path+"/user/ucexist.html",//請求的url
            data:{userCode:userCode.val()},//請求參數
            dataType:"json",//ajax接口(請求url)返回的數據類型
            success:function(data){//data:返回數據(json對象)
                if(data.userCode == "exist"){//賬號已存在,錯誤提示
                    validateTip(userCode.next(),{"color":"red"},imgNo+ " 該用戶賬號已存在",false);
                }else{//賬號可用,正確提示
                    validateTip(userCode.next(),{"color":"green"},imgYes+" 該賬號可以使用",true);
                }
            },
            error:function(data){//當訪問時候,404,500 等非200的錯誤狀態碼
                validateTip(userCode.next(),{"color":"red"},imgNo+" 您訪問的頁面不存在",false);
            }
        });
    }).bind("focus",function(){
        //顯示友情提示
        validateTip(userCode.next(),{"color":"#666666"},"* 用戶編碼是您登錄系統的賬號",false);
    }).focus();
在上述代碼中,當用戶在新增用戶頁面完成用戶編碼(userCode)的輸入之後,即用戶編碼輸入框中鼠標失焦時,進行Aajx異步驗證,請求URL"/user/ucexist.html",請求參數爲用戶輸入的userCode的值。異步調用請求之後,返回的數據類型爲JSON類型,若成功,則根據返回的JSON對象,對其進行相應的信息提示。

解決JSON數據傳遞的中文亂碼問題

在Spring MVC中,控制器的處理方法使用@ResponseBody註解向前臺頁面以JSON格式進行數據傳遞的時候,若返回值是中文字符串,則回出現亂碼。原因是消息轉換器(org.springframework.http.converter.StringHttpMessageConverter)中固定了轉換字符編碼,即"ISO-8859-1".
下面介紹兩種解決方案:
1.在控制器處理方法上的@RequestMapping註解中配置produces.
produces:指定返回的內容類型。produces={"application/json;charset=UTF-8"}:表示該處理方法將產生JSON格式的數據,此時會根據請求報文頭中的Accept進行匹配,若請求報文頭"Accept:application/json"時即可匹配,並且字符串的轉換編碼爲"UTF-8"。如下例代碼所示:

    @RequestMapping(value="/view ",
                    method=RequestMethod.GET,
                    produces={"application/json;charset=UTF-8"})
    public String view(@PathVariable String id,Model model){
        logger.debug("view id===================== "+id);
        User user = userService.getUserById(id);
        model.addAttribute(user);
        return "userview";
    }
這裏要注意,請求報文頭的Accept:application/json是否與響應報文頭中的Content-Type:text/html,類型是否一致。
2.裝配消息轉換器StringHttpMessageConverter,設置字符編碼爲UTF-8.
修改配置文件springmvc-servlet.xml,關鍵代碼如下:
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

解決JSON數據傳遞的日期格式問題

簡介:
Spring MVC框架中時間數據無法自動綁定,當form表單中出現時間字段需要跟POJO對象中的成員變量進行綁定時,便會出現BinExceptionyi異常。這是Spring MVC框架的問題,若不解決此問題,頁面傳遞回來的時間類型的數據就無法再Controller中接收,也就無法完成新增用戶的功能。解決的方式多種,下面簡單的介紹三種解決方式。

方式一 在POJO中,時間類型的屬性上標註格式化註解@DateTimeFormat
    @DateTimeFormat(pattern="yyyy-MM-dd") 
    private Date birthday;  //出生日期
 在上述代碼中,@DateTimeFormat(pattern="yyyy-MM-dd") 可以將形如1996-12-01的字符串轉換爲java.util.Date類型。              
<mvc:annotation-driven />
注意的是需要在 在springmvc-servlet.xml配置<mvc:annotation-driver/>標籤,此標籤是Spring MVC的簡化配置。默認情況下,他會創建並註冊一個默認的DefaultAnnotationHandlerMapping和一個AnnotationMethodHandlerAdapter實例,並且還會註冊一個默認的ConversionService實例:FormattingConversionServiceFactoryBean,那麼Spring MVC對處理方法的入參綁定就可以支持註解驅動的功能,以滿足大部分類型的轉換需要。
方式二 編寫自定義轉換器
    Spring在org.springframework.core.convert.converter包中定義了最簡單的Converter轉換接口,它僅包括一個接口方法,Converter<S, T>。Converter的作用就是將一種類型裝換成另一種類型的對象。例如,用戶輸入的日期可能有多種形式,如“2018-07-18”、“18-07-2018”等,這些都表示同一個日期。若希望Spring在將輸入的日期字符串綁定到Date時,使用不同的日期格式,則需要編寫一個Converter,才能將字符串裝換成日期。具體實現也很簡單:首先需要創建一個實現org.springframework.core.convert.converter.Converter接口的Java類,然後將實現了Converter接口的自定義轉換器註冊到ConversionServiceFactoryBean中即可。
1)創建StringToDateConverter.java
定義一個負責將字符串轉換成指定格式的時間對象Date的自定義轉換器,關鍵示例代碼如下:
package cn.smbms.tools;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
public class StringToDateConverter implements Converter<String, Date> {
    private String datePattern;
    public StringToDateConverter(String datePattern){
        System.out.println("StringToDateConverter convert: "+datePattern);
        this.datePattern=datePattern;
    } 
    @Override
    public Date convert(String s) {
        // TODO Auto-generated method stub
        Date date=null;
            try {
                date=new SimpleDateFormat(datePattern).parse(s);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        return date;
    }
}
在上述代碼中,StringToDateConverter需要實現Converter接口的convert()方法,在方法體內完成字符串到java.util.Date類型指定格式的轉換。
2)裝配自定義的ConversionService
修改springmvc-servlet.xml,關鍵示例代碼如下:
           <mvc:annotation-driven conversion-service="myConversionService">
               <!-- 中間配置代碼省略 -->
           </mvc:annotation-driven>
            <!-- 裝配自定義的ConversionService -->
    <bean id="myConversionService" class="org.springframework.context.support.ConversionServiceFactory           Bean">
        <property name="converters">
            <list>
                <bean class="cn.smbms.tools.StringToDateConverter">
                    <constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
                </bean>
            </list>
        </property>
    </bean>
在前面,我們提到過<mvc:annotation-driven/>標籤會自動註冊一個默認的ConversionService,現在由於我們需要註冊一個自定義的SpringToDateConverter,因此需要顯式定義一個ConversionService來覆蓋<mvc:annotation-driven/>中的默認實現,通過配置<mvc:annotation-driven/>標籤的conversion-service屬性(本示例中Bean的名稱爲myConversionService)來完成。
裝配完成StringToDateConverter之後,就可以在任何控制器的處理方法中使用這種轉換器了,並且不需要在POJO中的時間屬性上進行格式化註解的標註,註釋掉@DateTimeFormat(pattern="yyyy-MM-dd")即可。
3)運行測試
 最後,部署運行測試,增加用戶信息時,正常保存,此處不再贅述。
方式三 使用@InitBinder裝配自定義編輯器
對於數據裝換,其實還有一種更加靈活的方式,就是通過自定義的編輯器去實現數據的裝換和格式化處理。下面我們就通過@InitBinder添加自定義的編輯器,來解決Spring MVC日期類型無法綁定的問題。具體實現步驟如下。
(1)創建BaseController.java,並標註@InitBinder。
在Controller中抽象出一個父類對象BaseController.java,每個Controller都繼承BaseController,而這個父類使用@InitBinder。關鍵示例代碼如下:
package cn.smbms.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
public class BaseController {
    /**
     * 使用@InitBinder解決SpringMVC日期類型無法綁定問題
     * @param dataBinder
     */
    @InitBinder
    public void initBinder(WebDataBinder dataBinder){
        System.out.println("initBender=================================");
        dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
    }
}
標註了@InitBinder註解的方法會在控制器初始化時調用。在initBinder()方法體內,通過dateBinder的registerCustomEditor()方法註冊一個自定義編輯器:第一個參數表示編輯器爲日期類型(Date.class);第二個參數表示使用自定義的日期編輯器(CustomDateEditor),時間格式爲yyyy-mm-dd,true表示允許爲空(該參數表示是否允許爲空)。
(2)修改UserController.java,繼承BaseController,關鍵示例代碼如下:
@Controller
@RequestMapping("/user")
public class UserController extends BaseController{\
//......中間代碼省略
}
(3)部署運行測試,增加用戶信息時,正常保存,此處不再贅述。

總結

在Spring   MVC中,Bean中定義了Date、double等類型,如果沒有做任何處理,日期、double都無法自動綁定。那麼上述的後兩種方案都可以解決SpringMVC的時間類型等綁定問題,當然也可以做更多業務上的需求,大家靈活掌握。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章