前言
本文主要講解的知識點如下:
- 參數(shù)綁定
- 數(shù)據(jù)回顯
- 文件上傳
參數(shù)綁定
我們在Controller使用方法參數(shù)接收值,就是把web端的值給接收到Controller中處理,這個過程就叫做參數(shù)綁定...
默認支持的參數(shù)類型
從上面的用法我們可以發(fā)現(xiàn),我們可以使用request對象、Model對象等等,其實是不是可以隨便把參數(shù)寫上去都行???其實并不是的...
Controller方法默認支持的參數(shù)類型有4個,這4個足以支撐我們的日常開發(fā)了
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Model
參數(shù)的綁定過程
一般地,我們要用到自定義的參數(shù)綁定就是上面所講的日期類型轉(zhuǎn)換以及一些特殊的需求....對于平常的參數(shù)綁定,我們是無需使用轉(zhuǎn)換器的,SpringMVC就已經(jīng)幫我們干了這個活了...
自定義綁定參數(shù)【老方式、全部Action均可使用】
在上一篇我們已經(jīng)簡單介紹了怎么把字符串轉(zhuǎn)換成日期類型了【使用的是WebDataBinder方式】...其實那是一個比較老的方法,我們可以使用SpringMVC更推薦的方式...
在上次把字符串轉(zhuǎn)換成日期類型,如果使用的是WebDataBinder方式的話,那么該轉(zhuǎn)換僅僅只能在當前Controller使用...如果想要全部的Controller都能夠使用,那么我們可以使用WebBindingInitializer方式
如果想多個controller需要共同注冊相同的屬性編輯器,可以實現(xiàn)PropertyEditorRegistrar接口,并注入webBindingInitializer中。
實現(xiàn)接口
public class CustomPropertyEditor implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"), true));
}
}
配置轉(zhuǎn)換器
注入到webBindingInitializer中
<!-- 注冊屬性編輯器 -->
<bean id="customPropertyEditor" class="cn.itcast.ssm.controller.propertyeditor.CustomPropertyEditor"></bean>
<!-- 自定義webBinder -->
<bean id="customBinder"
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<!-- propertyEditorRegistrars用于屬性編輯器 -->
<property name="propertyEditorRegistrars">
<list>
<ref bean="customPropertyEditor" />
</list>
</property>
</bean>
<!-- 注解適配器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<!-- 在webBindingInitializer中注入自定義屬性編輯器、自定義轉(zhuǎn)換器 -->
<property name="webBindingInitializer" ref="customBinder"></property>
</bean>
自定義參數(shù)轉(zhuǎn)換器【新方式、推崇方式】
上面的方式是對象較老的,現(xiàn)在我們一般都是實現(xiàn)Converter接口來實現(xiàn)自定義參數(shù)轉(zhuǎn)換...我們就來看看實現(xiàn)Converter比上面有什么好
配置日期轉(zhuǎn)換器
public class CustomDateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
try {
//進行日期轉(zhuǎn)換
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
配置去除字符串轉(zhuǎn)換器
public class StringTrimConverter implements Converter<String, String> {
@Override
public String convert(String source) {
try {
//去掉字符串兩邊空格,如果去除后為空設(shè)置為null
if(source!=null){
source = source.trim();
if(source.equals("")){
return null;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return source;
}
}
從上面可以得出,我們想要轉(zhuǎn)換什么內(nèi)容,就直接實現(xiàn)接口,該接口又是支持泛型的,閱讀起來就非常方便了...
配置轉(zhuǎn)換器
<!-- 轉(zhuǎn)換器 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/>
<bean class="cn.itcast.ssm.controller.converter.StringTrimConverter"/>
</list>
</property>
</bean>
<!-- 自定義webBinder -->
<bean id="customBinder"
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<!-- 使用converter進行參數(shù)轉(zhuǎn) -->
<property name="conversionService" ref="conversionService" />
</bean>
<!-- 注解適配器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<!-- 在webBindingInitializer中注入自定義屬性編輯器、自定義轉(zhuǎn)換器 -->
<property name="webBindingInitializer" ref="customBinder"></property>
</bean>
如果是基于<mvc:annotation-driven>的話,我們是這樣配置的
<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"/>
<bean class="cn.itcast.ssm.controller.converter.StringTrimConverter"/>
</list>
</property>
</bean>
@RequestParam注解
我們一般使用的參數(shù)綁定都有遵循的規(guī)則:方法參數(shù)名要與傳遞過來的name屬性名相同。
在默認的情況下,只有名字相同,SpringMVC才會幫我們進行參數(shù)綁定...
如果我們使用@RequestParam注解的話,我們就可以使方法參數(shù)名與傳遞過來的name屬性名不同...
該注解有三個變量
- value【指定name屬性的名稱是什么】
- required【是否必須要有該參數(shù)】
- defaultvalue設(shè)置默認值
例子:我們的方法參數(shù)叫id,而頁面帶過來的name屬性名字叫item_id,一定需要該參數(shù)
public String editItem(@RequestParam(value="item_id",required=true) String id) {
}
Controller方法返回值
Controller方法的返回值其實就幾種類型,我們來總結(jié)一下....
- void
- String
- ModelAndView
- redirect重定向
- forward轉(zhuǎn)發(fā)
數(shù)據(jù)回顯
其實數(shù)據(jù)回顯我們現(xiàn)在的話就一點也不陌生了....我們剛使用EL表達式的時候就已經(jīng)學會了數(shù)據(jù)回顯了,做SSH項目的時候也有三圈問題的數(shù)據(jù)回顯...
在頁面上數(shù)據(jù)回顯本質(zhì)上就是獲取reqeust域的值..
而在我們SpringMVC中,我們是使用Model來把數(shù)據(jù)綁定request域?qū)ο笾械?/strong>
一般地我們都是使用model.addAttribute()的方式把數(shù)據(jù)綁定到request域?qū)ο笾?..其實SpringMVC還支持注解的方式
@ModelAttribute注解
我們可以將請求的參數(shù)放到Model中,回顯到頁面上
上面這種用法和model.addAttribute()的方式是沒啥區(qū)別的,也體現(xiàn)不了注解的方便性...
而如果我們要回顯的數(shù)據(jù)是公共的話,那么我們就能夠體會到注解的方便性了,我們把公共需要顯示的屬性抽取成方法,將返回值返回就行了。
那我們就不用在每一個controller方法通過Model將數(shù)據(jù)傳到頁面。
SpringMVC文件上傳
我們使用Struts2的時候,覺得Struts2的文件上傳方式比傳統(tǒng)的文件上傳方式好用多了...
http://blog.csdn.net/hon_3y/article/details/71091593
既然我們正在學習SpringMVC,那么我們也看一下SpringMVC究竟是怎么上傳文件的...
配置虛擬目錄
在這次,我們并不是把圖片上傳到我們的工程目錄中...
那為啥不將圖片直接上傳到我們的工程目錄中呢???我們仔細想想,按照我們之前的做法,直接把文件上傳到工程目錄,而我們的工程目錄是我們寫代碼的地方 ...往往我們需要備份我們的工程目錄。
如果把圖片都上傳到工程目錄中,那么就非常難以處理圖片了...
因此,我們需要配置Tomcat的虛擬目錄來解決,把上傳的文件放在虛擬目錄上...
又值得注意的是,Idea使用的Tomcat并不能使用傳統(tǒng)的配置方式,也就是修改server.xml方式來配置虛擬目錄,在Idea下好像不支持這種做法...
有興趣的同學可以去測試一下:
http://blog.csdn.net/hon_3y/article/details/54412484
那么我在網(wǎng)上已經(jīng)找到了對應的解決辦法,就是如果在idea上配置虛擬目錄
http://blog.csdn.net/LABLENET/article/details/51160828
檢測是否配置成功:
快速入門
在SpringMVC中文件上傳需要用到的jar包
- commons-fileupload-1.2.2.jar
- commons-io-2.4.jar
配置文件上傳解析器
<!-- 文件上傳 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設(shè)置上傳文件的最大尺寸為5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
測試的JSP
<%--
Created by IntelliJ IDEA.
User: ozc
Date: 2017/8/11
Time: 9:56
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>測試文件上傳</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload.action" method="post" enctype="multipart/form-data" >
<input type="file" name="picture">
<input type="submit" value="submit">
</form>
</body>
</html>
值得注意的是,在JSP的name屬性寫的是picture,那么在Controller方法參數(shù)的名稱也是要寫picture的,否則是獲取不到對應的文件的..
@Controller
public class UploadController {
@RequestMapping("/upload")
//MultipartFile該對象就是封裝了圖片文件
public void upload(MultipartFile picture) throws Exception {
System.out.println(picture.getOriginalFilename());
}
}
總結(jié)
- 在SpringMVC中的業(yè)務方法默認支持的參數(shù)有四種
- request
- response
- session
- model
- 我們的參數(shù)綁定(自動封裝參數(shù))是由我們的轉(zhuǎn)換器來進行綁定的?,F(xiàn)在用的一般都是Converter轉(zhuǎn)換器
- 在上一章中我們使用WebDataBinder方式來實現(xiàn)對日期格式的轉(zhuǎn)化,當時僅僅是可用于當前Action的。我們想要讓全部Action都可以使用的話,有兩種方式:
- 實現(xiàn)PropertyEditorRegistrar(比較老的方式)
- 實現(xiàn)Converter(新的方式)
-
參數(shù)綁定都有遵循的規(guī)則:方法參數(shù)名要與傳遞過來的name屬性名相同
- 我們可以使用@RequestParam注解來具體指定對應的name屬性名稱,這樣也是可以實現(xiàn)參數(shù)綁定的。
- 還能夠配置該參數(shù)是否是必須的。
- Controller方法的返回值有5種:
- void
- String
- ModelAndView
- redirect重定向
- forward轉(zhuǎn)發(fā)
- Model內(nèi)部就是將數(shù)據(jù)綁定到request域?qū)ο笾械摹?/li>
- @ModelAttribute注解能夠?qū)?shù)據(jù)綁定到model中(也就是request中),如果經(jīng)常需要綁定到model中的數(shù)據(jù),抽取成方法來使用這個注解還是不錯的。
- idea配置虛擬目其實就是加多一個deployment,然后配置它的應用路徑
- SpringMVC的文件上傳就是配置一個上傳解析器,使用MultipartFile來接收帶過來的文件。
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學,可以關(guān)注微信公眾號:Java3y