springmvc教程--注解开发基础详解
springmvc教程系列
springmvc史上最好教程(2)
springmvc史上最好教程(1)
一、 注解開發(fā)-基礎(chǔ)
1.1?需求
使用springmvc+mybatis架構(gòu)實現(xiàn)商品信息維護。
1.2?商品修改
1.2.1?dao
使用逆向工程自動生成的代碼:
ItemsMapper.java
ItemsMapper.xml
1.2.2?service
//根據(jù)id查詢商品信息public Items findItemById(int id) throws Exception;//修改商品信息public void saveItem(Items items)throws Exception;1.2.3?controller
修改商品信息顯示頁面:
@RequestMapping(value="/editItem")public String editItem(Model model, Integer id) throws Exception{//調(diào)用service查詢商品信息Items item = itemService.findItemById(id);model.addAttribute("item", item);return "item/editItem";}修改商品信息提交:
//商品修改提交@RequestMapping("/editItemSubmit")public String editItemSubmit(Items items)throws Exception{System.out.println(items);itemService.saveItem(items);return "success";}?
1.2.4?頁面
/WEB-INF/jsp/item/itemsList.jsp
/WEB-INF/jsp/item/editItem.jsp
1.3 @RequestMapping
通過RequestMapping注解可以定義不同的處理器映射規(guī)則。
1.3.1?URL路徑映射
@RequestMapping(value="/item")或@RequestMapping("/item)
value的值是數(shù)組,可以將多個url映射到同一個方法
1.3.2?窄化請求映射
在class上添加@RequestMapping(url)指定通用請求前綴, 限制此類下的所有方法請求url必須以請求前綴開頭,通過此方法對url進行分類管理。
如下:
@RequestMapping放在類名上邊,設(shè)置請求前綴?
@Controller
@RequestMapping("/item")
?
方法名上邊設(shè)置請求映射url:
@RequestMapping放在方法名上邊,如下:
@RequestMapping("/queryItem ")
訪問地址為:/item/queryItem
1.3.3?請求方法限定
1、限定GET方法
@RequestMapping(method = RequestMethod.GET)
?
如果通過Post訪問則報錯:
HTTP Status 405 - Request method 'POST' not supported
?
例如:
@RequestMapping(value="/editItem",method=RequestMethod.GET)
2、 限定POST方法
?
@RequestMapping(method = RequestMethod.POST)
如果通過Post訪問則報錯:
HTTP Status 405 - Request method 'GET' not supported
3、GET和POST都可以
@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
1.4?controller方法返回值
1.4.1?返回ModelAndView
controller方法中定義ModelAndView對象并返回,對象中可添加model數(shù)據(jù)、指定view。
1.4.2?返回void
在controller方法形參上可以定義request和response,使用request或response指定響應(yīng)結(jié)果:
使用request轉(zhuǎn)向頁面,如下:
request.getRequestDispatcher("頁面路徑").forward(request, response);
通過response頁面重定向:
response.sendRedirect("url")
通過response指定響應(yīng)結(jié)果,例如響應(yīng)json數(shù)據(jù)如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
1.4.3?返回字符串
1.4.3.1?邏輯視圖名
controller方法返回字符串可以指定邏輯視圖名,通過視圖解析器解析為物理視圖地址。
//指定邏輯視圖名,經(jīng)過視圖解析器解析為jsp物理路徑:/WEB-INF/jsp/item/editItem.jspreturn "item/editItem";1.4.3.2?Redirect重定向
Contrller方法返回結(jié)果重定向到一個url地址,如下商品修改提交后重定向到商品查詢方法,參數(shù)無法帶到商品查詢方法中。
//重定向到queryItem.action地址,request無法帶過去 return "redirect:queryItem.action";redirect方式相當(dāng)于“response.sendRedirect()”,轉(zhuǎn)發(fā)后瀏覽器的地址欄變?yōu)檗D(zhuǎn)發(fā)后的地址,因為轉(zhuǎn)發(fā)即執(zhí)行了一個新的request和response。
由于新發(fā)起一個request原來的參數(shù)在轉(zhuǎn)發(fā)時就不能傳遞到下一個url,如果要傳參數(shù)可以/item/queryItem.action后邊加參數(shù),如下:
/item/queryItem?...&…..
1.4.3.3?forward轉(zhuǎn)發(fā)
controller方法執(zhí)行后繼續(xù)執(zhí)行另一個controller方法,如下商品修改提交后轉(zhuǎn)向到商品修改頁面,修改商品的id參數(shù)可以帶到商品修改方法中。
//結(jié)果轉(zhuǎn)發(fā)到editItem.action,request可以帶過去return "forward:editItem.action";forward方式相當(dāng)于“request.getRequestDispatcher().forward(request,response)”,轉(zhuǎn)發(fā)后瀏覽器地址欄還是原來的地址。轉(zhuǎn)發(fā)并沒有執(zhí)行新的request和response,而是和轉(zhuǎn)發(fā)前的請求共用一個request和response。所以轉(zhuǎn)發(fā)前請求的參數(shù)在轉(zhuǎn)發(fā)后仍然可以讀取到。
1.5?參數(shù)綁定
1.5.1?默認(rèn)支持的參數(shù)類型
處理器形參中添加如下類型的參數(shù)處理適配器會默認(rèn)識別并進行賦值。
1.5.1.1?HttpServletRequest
通過request對象獲取請求信息
1.5.1.2?HttpServletResponse
通過response處理響應(yīng)信息
1.5.1.3?HttpSession
通過session對象得到session中存放的對象
1.5.1.4?Model
通過model向頁面?zhèn)鬟f數(shù)據(jù),如下:
//調(diào)用service查詢商品信息 Items item = itemService.findItemById(id); model.addAttribute("item", item);頁面通過${item.XXXX}獲取item對象的屬性值。
1.5.2?參數(shù)綁定介紹
注解適配器對RequestMapping標(biāo)記的方法進行適配,對方法中的形參會進行參數(shù)綁定,早期springmvc采用PropertyEditor(屬性編輯器)進行參數(shù)綁定將request請求的參數(shù)綁定到方法形參上,3.X之后springmvc就開始使用Converter進行參數(shù)綁定。
1.5.3?@RequestParam
@RequestParam用于綁定單個請求參數(shù)。
value:參數(shù)名字,即入?yún)⒌恼埱髤?shù)名字,如value=“item_id”表示請求的參數(shù)區(qū)中的名字為item_id的參數(shù)的值將傳入;
required:是否必須,默認(rèn)是true,表示請求中一定要有相應(yīng)的參數(shù),否則將報;
TTP Status 400 - Required Integer parameter 'XXXX' is not present
?
defaultValue:默認(rèn)值,表示如果請求中沒有同名參數(shù)時的默認(rèn)值
定義如下:
public String editItem(@RequestParam(value="item_id",required=true) String id) {}形參名稱為id,但是這里使用value="?item_id"限定請求的參數(shù)名為item_id,所以頁面?zhèn)鬟f參數(shù)的名必須為item_id。
注意:如果請求參數(shù)中沒有item_id將跑出異常:
HTTP Status 500 - Required Integer parameter 'item_id' is not present
這里通過required=true限定item_id參數(shù)為必需傳遞,如果不傳遞則報400錯誤,可以使用defaultvalue設(shè)置默認(rèn)值,即使required=true也可以不傳item_id參數(shù)值
1.5.4?簡單類型
當(dāng)請求的參數(shù)名稱和處理器形參名稱一致時會將請求參數(shù)與形參進行綁定。
1.5.4.1?整型
public String editItem(Model model,Integer id) throws Exception{
}
1.5.4.2?字符串
例子略
1.5.4.3?單精度/雙精度
例子略
1.5.4.4?布爾型
處理器方法:
public String editItem(Model model,Integer id,Boolean status) throws Exception
請求url:
http://localhost:8080/springmvc_mybatis/item/editItem.action?id=2&status=false
說明:對于布爾類型的參數(shù),請求的參數(shù)值為true或false。
1.5.5?自定義參數(shù)綁定
1.5.5.1?需求
根據(jù)業(yè)務(wù)需求自定義日期格式進行參數(shù)綁定。
1.5.5.2?propertyEditor
1.5.5.2.1?使用WebDataBinder?
在controller方法中通過@InitBinder標(biāo)識方法為參數(shù)綁定方法,通過WebDataBinder注冊屬性編輯器,問題是此方法只能在單個controller類中注冊。
/*** 注冊屬性編輯器(字符串轉(zhuǎn)換為日期)*/@InitBinderpublic void initBinder(WebDataBinder binder) throws Exception {binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));}1.5.5.2.2 使用WebDataBinder?
在controller方法中通過@InitBinder標(biāo)識方法為參數(shù)綁定方法,通過WebDataBinder注冊屬性編輯器,問題是此方法只能在單個controller類中注冊。
如下:
編寫CustomPropertyEditor:
public class CustomPropertyEditor implements PropertyEditorRegistrar {@Overridepublic void registerCustomEditors(PropertyEditorRegistry registry) {registry.registerCustomEditor(Date.class, new CustomDateEditor(newSimpleDateFormat("yyyy-MM-dd HH-mm-ss"),true));}}配置如下:
<!-- 注冊屬性編輯器 --><bean id="customPropertyEditor" class="com.sihai.ssm.propertyeditor.CustomPropertyEditor"></bean> <!-- 自定義webBinder --><bean id="customBinder"class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"><property name="propertyEditorRegistrars"><list><ref bean="customPropertyEditor"/></list></property></bean><!--注解適配器 --><beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="webBindingInitializer" ref="customBinder"></property> </bean>1.5.5.3?Converter
1.5.5.3.1?自定義Converter
public class CustomDateConverter implements Converter<String, Date> {@Overridepublic Date convert(String source) {try {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");return simpleDateFormat.parse(source);} catch (Exception e) {e.printStackTrace();}return null;}}1.5.5.3.2?配置方式1
<!--注解適配器 --><beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="webBindingInitializer" ref="customBinder"></property> </bean><!-- 自定義webBinder --><bean id="customBinder"class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"><property name="conversionService" ref="conversionService" /></bean><!-- conversionService --><bean id="conversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><!-- 轉(zhuǎn)換器 --><property name="converters"><list><bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/></list></property></bean>1.5.5.3.3?配置方式2
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven><!-- conversionService --><bean id="conversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><!-- 轉(zhuǎn)換器 --><property name="converters"><list><bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/></list></property></bean>1.5.6?pojo
1.5.6.1?簡單pojo
將pojo對象中的屬性名于傳遞進來的屬性名對應(yīng),如果傳進來的參數(shù)名稱和對象中的屬性名稱一致則將參數(shù)值設(shè)置在pojo對象中
頁面定義如下;
<input type="text" name="name"/>
<input type="text" name="price"/>
Contrller方法定義如下:
@RequestMapping("/editItemSubmit")public String editItemSubmit(Items items)throws Exception{System.out.println(items);請求的參數(shù)名稱和pojo的屬性名稱一致,會自動將請求參數(shù)賦值給pojo的屬性。
1.5.6.2?包裝pojo
如果采用類似struts中對象.屬性的方式命名,需要將pojo對象作為一個包裝對象的屬性,action中以該包裝對象作為形參。
包裝對象定義如下:
Public class QueryVo {private Items items;}頁面定義:
<input type="text" name="items.name" />
<input type="text" name="items.price" />
Controller方法定義如下:
public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{System.out.println(queryVo.getItems());1.5.6.3 ModelAttribute
@ModelAttribute作用如下:
1、綁定請求參數(shù)到pojo并且暴露為模型數(shù)據(jù)傳到視圖頁面
此方法可實現(xiàn)數(shù)據(jù)回顯效果。
// 商品修改提交@RequestMapping("/editItemSubmit")public String editItemSubmit(@ModelAttribute("item") Items items,Model model)頁面:
<tr><td>商品名稱</td><td><input type="text" name="name" value="${item.name }"/></td></tr><tr><td>商品價格</td><td><input type="text" name="price" value="${item.price }"/></td></tr>?
?
如果不用@ModelAttribute可以使用model.addAttribute("item", items)完成數(shù)據(jù)回顯。
2、將方法返回值暴露為模型數(shù)據(jù)傳到視圖頁面
//商品分類@ModelAttribute("itemtypes")public Map<String, String> getItemTypes(){Map<String, String> itemTypes = new HashMap<String,String>();itemTypes.put("101", "數(shù)碼");itemTypes.put("102", "母嬰");return itemTypes;}頁面:
商品類型:
<select name="itemtype"><c:forEach items="${itemtypes }" var="itemtype"><option value="${itemtype.key }">${itemtype.value }</option></c:forEach></select>1.5.7?集合類
1.5.7.1?字符串?dāng)?shù)組
頁面定義如下:
頁面選中多個checkbox向controller方法傳遞
<input type="checkbox" name="item_id" value="001"/><input type="checkbox" name="item_id" value="002"/><input type="checkbox" name="item_id" value="002"/>傳遞到controller方法中的格式是:001,002,003
Controller方法中可以用String[]接收,定義如下:
public String deleteitem(String[] item_id)throws Exception{System.out.println(item_id);}1.5.7.2?List
List中存放對象,并將定義的List放在包裝類中,action使用包裝對象接收。
List中對象:
成績對象
Public class QueryVo {Private List<Items> itemList;//訂單明細(xì)//get/set方法..}包裝類中定義List對象,并添加get/set方法如下:
頁面:
<tr><td><input type="text" name=" itemList[0].id" value="${item.id}"/></td><td><input type="text" name=" itemList[0].name" value="${item.name }"/></td><td><input type="text" name=" itemList[0].price" value="${item.price}"/></td></tr><tr><td><input type="text" name=" itemList[1].id" value="${item.id}"/></td><td><input type="text" name=" itemList[1].name" value="${item.name }"/></td><td><input type="text" name=" itemList[1].price" value="${item.price}"/></td></tr>Contrller方法定義如下:
public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{System.out.println(queryVo.getItemList());}1.5.7.3?Map
在包裝類中定義Map對象,并添加get/set方法,action使用包裝對象接收。
包裝類中定義Map對象如下:
Public class QueryVo {private Map<String, Object> itemInfo = new HashMap<String, Object>();//get/set方法..}頁面定義如下:
<tr><td>學(xué)生信息:</td><td>姓名:<inputtype="text"name="itemInfo['name']"/>年齡:<inputtype="text"name="itemInfo['price']"/>.. .. ..</td></tr>Contrller方法定義如下:
public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{System.out.println(queryVo.getStudentinfo());}1.6?問題總結(jié)
1.6.1?404
頁面找不到,視圖找不到。
HandlerMapping根據(jù)url沒有找到Handler。
1.6.2?Post時中文亂碼
在web.xml中加入:
<filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>以上可以解決post請求亂碼問題。
對于get請求中文參數(shù)出現(xiàn)亂碼解決方法有兩個:
修改tomcat配置文件添加編碼與工程編碼一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>另外一種方法對參數(shù)進行重新編碼:
String userName newString(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")ISO8859-1是tomcat默認(rèn)編碼,需要將tomcat編碼后的內(nèi)容按utf-8編碼
1.7?與struts2不同
1、?springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過慮器。
2、?springmvc是基于方法開發(fā)(一個url對應(yīng)一個方法),請求參數(shù)傳遞到方法的形參,可以設(shè)計為單例或多例(建議單例),struts2是基于類開發(fā),傳遞參數(shù)是通過類的屬性,只能設(shè)計為多例。
3、?Struts采用值棧存儲請求和響應(yīng)的數(shù)據(jù),通過OGNL存取數(shù)據(jù),springmvc通過參數(shù)解析器是將request請求內(nèi)容解析,并給方法形參賦值,將數(shù)據(jù)和視圖封裝成ModelAndView對象,最后又將ModelAndView中的模型數(shù)據(jù)通過reques域傳輸?shù)巾撁妗sp視圖解析器默認(rèn)使用jstl。
總結(jié)
以上是生活随笔為你收集整理的springmvc教程--注解开发基础详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springmvc教程(3)
- 下一篇: springmvc教程(4)