使用@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的時間類型等綁定問題,當然也可以做更多業務上的需求,大家靈活掌握。