SpringMvc學習筆記(基礎+詳細)
本人技術小白,學習SpringMvc後,將相關內容整理下來,供大家分享,歡迎批評指正。
本文主要介紹如下方面相關知識,並分為不同章節,大家可根據自身需求選擇性閱讀:
- SpirngMvc的HelloWorld(一個SpringMvc例項的簡單流程)
- 使用@RequestMapping對映請求
- 對映請求引數、請求頭
- 處理模型資料
- 檢視和檢視解析器
- 資料轉換、校驗、格式化
- 檔案的上傳
- 使用攔截器
一.SpringMvc的Helloworld,一個SpringMvc例項的簡單流程
1.在web.xml檔案中配置DispacherServlet:配置SpringMvc配置檔案的位置和名稱
<servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置DispatcherServlet的初始化引數:SpringMvc配置檔案的位置和名稱 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- Map all requests to the DispatcherServlet for handling --> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
2.建立springMvc配置檔案,根據web.xml檔案中的配置。配置檔名為:springMvc.xml,位於src路徑下
1).自動掃描的包在spring中有相關介紹,此處不做介紹
2).配置檢視解析器:為了將handler方法的返回值解析為實際的物理檢視,此處為解析成jsp。
<!-- 配置自動掃描的包 --> <context:component-scan base-package="springmvc.helloworld"></context:component-scan> <!-- 配置檢視解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean>
3.使用@RequestMapping對映請求
1).使用@RequestMapping註解對映請求的URL
2).返回值(此處為“success”)會通過檢視解析解析為實際的物理檢視,此處為InternalResourceViewResolver,並
通過prefix + 返回值 + suffix 這樣的方式得到實際的物理檢視,然後做轉發操作
@Controller
public class HelloWorld {
@RequestMapping("/helloWorld")
public String hello(){
System.out.println("helloWorld");
return "success";
}
}
4.兩個jsp頁面
1).首頁(index.jsp)
<body>
<a href="helloWorld">To success</a>
</body>
2).目標頁面(success.jsp),注意:根據檢視解析器中的配置,success.jsp位於/WEB-INF/views目錄下
<body>
<h1>Hello!</h1>
</body>
5.現象:進入index.jsp頁面後,點選超連結,則可進入success.jsp頁面
二、使用@RequestMapping對映請求
1.SpringMvc使用@RequestMapping註解為控制器指定可以處理的URL請求,註解可以標記在類上或方法上
2.Dispatcher截獲請求後就通過@RequestMapping提供的對映資訊確定請求所對應的處理方法
[email protected]中可以指定value(請求URL)、method(請求的方法)、params(請求引數)、heads(請求頭),他們之間時 與的關係,使用多個條件聯合查詢,可使請求精確化。
4.支援Ant風格的Url,Ant風格地址支援三種匹配符: ?:匹配檔名中的一個字元
*:匹配檔名中的任意字元
**:** :匹配多層路徑
[email protected]對映URL繫結的佔位符
通過@PathVariable可以將URL中佔位符引數繫結到控制器處理方法的入參中
請求的URL為:<a href="helloworld/1">To success</a> ,可將“1”傳入到方法中
@RequestMapping("/helloworld/{id}")
public String hello(@PathVariable("id") Integer id){
System.out.println("helloWorld"+id);
return "success";
}
三、對映請求引數、請求頭
SpirngMvc通過分析處理方法的簽名,將Http請求資訊繫結到處理方法的相關入參中
1.使用@RequestParam可以把請求引數傳遞給請求方法 value:引數名、required:是否必須
請求Url:<a href="helloworld?username=123">To success</a>,可將請求引數中的“123”傳遞給方法。
@RequestMapping("/helloworld")
public String hello(@RequestParam(value="username" required=false) String un){
System.out.println("helloWorld:"+un);
return "success";
}
2.使用@RequestHeader繫結請求報頭資訊,請求頭包含了若干屬性,伺服器可據此獲知客戶端的資訊。
@RequestMapping("/helloworld")
public String hello(@RequestHeader("Accept-Encoding") String encoding){
System.out.println("helloWorld:"+encoding);
return "success";
}
3.使用@CookieValue繫結請求中的Cookie值
@RequestMapping("/helloworld")
public String hello(@CookieValue("JSESSIONID") String sessionId){
System.out.println("helloWorld:"+sessionId);
return "success";
}
4.使用POJO物件繫結請求引數,SpirngMvc會按照請求引數名和POJO屬性名自動進行匹配,自動為該物件填充屬性,支援級聯屬性
1).表單,此表單對應一個User的JavaBean
<form action="testPojo" method="post">
username:<input type="text" name="username"> <br>
password:<input type="password" name="password"> <br>
age:<input type="text" name="age"><br>
<input type="submit" name="Submit">
</form>
2).處理方法,,結果會在控制輸出user: User [username=adfd, password=585, age=13]
@RequestMapping("/testPojo")
public String testPojo(User user) {
System.out.println(user);
return "success";
}
5.MVC的Handler可以接收ServletAPI
HttpServletRequest、HttpServletResponse、HttpSession、java.security.Principal、Locale、InputStream、OutputStream
Reader、Writer
四、處理模型資料
1.ModelAndView
控制器處理方法的返回值可以是ModelAndView,其包含模型和資料資訊,Springmvc會將model中的資料放到request域中。
新增模型資料: ModelAndView addObject(String attributeName,Object attributeValue)
ModelAndView addAllObject(Map<String,?> modelMap)
設定檢視: void setView(View view)
void setViewName(String ViewName)
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
ModelAndView mv = new ModelAndView("success");
mv.addObject("time", new Date());
return mv;
}
可在目標頁面success.jsp接收time:
time:<%=request.getAttribute("time") %>
2.Map及Model 也可以傳入Map和Model型別,目標方法可以新增Map型別(也可以是Model型別或是ModelMap型別引數)
@RequestMapping("testMap")
public String testMap(Map<String, Object> map) {
map.put("names", Arrays.asList("Li","Wu","Zhang"));
return "success";
}
同樣可在目標頁面success.jsp接收到names引數
names:<%=request.getAttribute("names") %>
3. @SessionAttributes 注意:此註解只能放在類上
若希望在多個請求之間共用某個模型引數,則可以在控制器類上標註一個@SessionAttributes,SpringMVC將在模型中對應的屬性暫 存到HttpSession中。
value屬性:通過屬性名指定需要放到會話中的屬性
types屬性:通過模型屬性的物件型別指定哪些模型屬性需要放到會話中
@SessionAttributes(value= {"user"},types= {String.class})
@Controller
public class HelloWorld {
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Map<String, Object> map) {
User user = new User("Li", "123456", 24);
map.put("user", user);
return "success";
}
}
可在目標頁面的session域中得到user
user:<%=session.getAttribute("user") %>
4. @ModelAttribute @ModelAttribute 標記的方法, 會在每個目標方法執行之前被 SpringMVC 呼叫!
ModelAttribute的典型應用:模擬修改操作
執行流程:*執行 @ModelAttribute註解修飾的方法:從資料庫中取出物件,把物件放入到Map中,鍵為user
**SpringMVC從Map中取出User物件,並把表單的請求引數賦給User物件的對應屬性值。
***SpringMVC把上述物件傳入目標方法的引數。
1).表單
<!--
模擬修改操作:
1.原始表單為:1,Tom,123456,24
2.密碼不能被修改
3。表單回顯,模擬操作直接在表單上填寫對應屬性值
-->
<form action="testModelAttribute" method="post">
<input type="hidden" name="id" value="1">
username:<input type="text" name="username" value="Tom"> <br>
age:<input type="text" name="age" value="24"><br>
<input type="submit" name="Submit">
</form>
2).主方法
@ModelAttribute
public void getUser(@RequestParam(value="id") Integer id,Map<String,Object> map) {
if(id!=null) {
User user = new User(1, "Tom", "123456", 24);
System.out.println("從資料庫中取出:"+user);
map.put("user", user);
}
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user) {
System.out.println("修改:" + user);
return "success";
}
3).結果
如若在表單中將修改age或是username,都將修改成功,其餘值不變
五、檢視及檢視處理器
1.SpringMVC如何解析檢視:
對於那些返回String、view或ModelMap等型別的處理方法,SpringMvc都會將其裝配成一個ModelAndView物件。view介面時無狀 態的,不會有執行緒安全問題
2.重定向
如果返回的字串中帶有“forward:”或“redirect:”字首時,SpringMVC會對他們進行特殊處理,將其當成指示符,其後的字串
作為URL來處理。
六、資料的轉換、格式化、校驗
1.資料轉換
SpringMVC定義了3種類型的轉換器介面:
* Converter<S,T>:將S型別轉換為T型別物件
* ConverterFactory:將相同系列多個“同質”Conterver封裝在一起
* GenericConverter: 會根據源類物件及目標所在的宿主主類中的上下文資訊進行型別轉換
例項如下:
1)表單
<form action="testConverter" method="POST">
<!-- 格式例如:Harry-123456-24 -->
Employee:<input type="text" name="user">
<input type="submit" name="Submit">
</form>
2).轉換器
@Component
public class UserConverter implements Converter<String, User> {
@Override
public User convert(String source) {
if(source != null) {
System.out.println("aa");
String[] vals = source.split("-");
if(vals != null) {
String username = vals[0];
String password = vals[1];
String age = vals[2];
User user = new User(username, password, Integer.parseInt(age));
System.out.println("converter:"+user);
return user;
}
}
return null;
}
}
3).配置檔案
<mvc:annotation-driven conversion-service="converterService"></mvc:annotation-driven>
<!-- 配置converterService -->
<bean id="converterService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="userConverter"/>
</set>
</property>
</bean>
4).目標方法
@RequestMapping("/testConverter")
public String testConverter(@RequestParam("user") User user) {
System.out.println(user);
return "success";
}
2.資料格式化
1).在配置檔案中新增上<mvc:annotation-driven ></mvc:annotation-driven>
2).在目標型別的屬性上配置
@NumberFormat(pattern="#.###")
private double price;
@DateTimeFormat(pattern="yyyy-mm-dd")
private Date birth;
3.資料的校驗
1).使用 JSR 303 驗證標準,在 SpringMVC 配置檔案中新增 <mvc:annotation-driven />,<mvc:annotation-driven />會預設裝配好一個 LocalValidatorFactoryBean。
2).需要在 bean 的屬性上新增對應的註解
例如:@NotNull :被註釋的元素不能為空 @Past :備註是的元素必須是一個過去的日期
@Email :被註釋的元素必須是一個email
3). 在目標方法 bean 型別的前面新增 @Valid 註解
七、檔案上傳
SpringMvc通過MutipartResolver實現檔案上傳
1.配置MutipartResolver
<!-- 配置 MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="1024000"></property>
</bean>
2.表單
<form action="testFileUpload" method="POST" enctype="multipart/form-data">
File: <input type="file" name="file"/>
Desc: <input type="text" name="desc"/>
<input type="submit" value="Submit"/>
</form>
3.目標方法
@RequestMapping("/testFileUpload")
public String testFileUpload(@RequestParam("desc") String desc,
@RequestParam("file") MultipartFile file) throws Exception {
System.out.println("InputStream:" + file.getInputStream());
return "success";
}
八、使用攔截器
SpringMvc也可以使用攔截器對請求進行攔截,可以自定義攔截器來實現特定的功能,自定義攔截器必須實現HandlerInterceptor介面
1.實現HandlerInterceptor介面的攔截器類
public class FirstInterceptor implements HandlerInterceptor {
/**
* 渲染檢視之後被呼叫. 釋放資源
*/
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("afterCompletion");
}
/**
* 呼叫目標方法之後, 但渲染檢視之前.
* 可以對請求域中的屬性或檢視做出修改.
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("postHandle");
}
/**
* 該方法在目標方法之前被呼叫.
* 若返回值為 true, 則繼續呼叫後續的攔截器和目標方法.
* 若返回值為 false, 則不會再呼叫後續的攔截器和目標方法.
*
* 可以考慮做許可權. 日誌, 事務等.
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("preHandle");
return true;
}
}
2.配置攔截器
<!-- 配置攔截器 -->
<mvc:interceptors>
<bean class="springmvc.helloworld.FirstInterceptor"></bean>
</mvc:interceptors>