springMVC第二章數(shù)據(jù)校驗和控制層傳參
知識點一:使用JSR303框架完成數(shù)據(jù)校驗工作
1.導(dǎo)入數(shù)據(jù)校驗所需要的jar包
2.在springMVC-servlet文件中注冊所需要的驅(qū)動
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.xt.handler"></context:component-scan>
<!-- 啟動校驗驅(qū)動 -->
<mvc:annotation-driven/>
<!-- 注入校驗bean -->
<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"></bean>
</beans>
3.創(chuàng)建pojo實體類,使用JSR303標準實現(xiàn)數(shù)據(jù)校驗@Pattern@Range...
package com.xt.pojo;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Range;
public class Survey {
private String week;
@Pattern(regexp="\\w{6,12}",message="姓名必須在6~12位")
private String name;
@Range(min=18,max=45,message="年齡必須在18~45之間")
private int age;
@Pattern(regexp="\\d{11}",message="電話必須為11位")
private String tel;
private String answer1;
private String answer2;
private String answer3;
public Survey() {
super();
// TODO Auto-generated aconstructor stub
}
public Survey(String week, String name, int age, String tel, String answer1, String answer2, String answer3) {
super();
this.week = week;
this.name = name;
this.age = age;
this.tel = tel;
this.answer1 = answer1;
this.answer2 = answer2;
this.answer3 = answer3;
}
public String getWeek() {
return week;
}
public void setWeek(String week) {
this.week = week;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAnswer1() {
return answer1;
}
public void setAnswer1(String answer1) {
this.answer1 = answer1;
}
public String getAnswer2() {
return answer2;
}
public void setAnswer2(String answer2) {
this.answer2 = answer2;
}
public String getAnswer3() {
return answer3;
}
public void setAnswer3(String answer3) {
this.answer3 = answer3;
}
@Override
public String toString() {
return "Survey [week=" + week + ", name=" + name + ", age=" + age + ", tel=" + tel + ", answer1=" + answer1
+ ", answer2=" + answer2 + ", answer3=" + answer3 + "]";
}
}
4.在handler中鲜漩,接受頁面請求腋寨,進行數(shù)據(jù)校驗相艇。
- @Valid:聲明該對象需要進行數(shù)據(jù)校驗
- @ModelAttribute("survey") 將jsp頁面?zhèn)骰貋淼臄?shù)據(jù)封裝到survey中,
- 由于 @ModelAttribute("survey")前面有@Valid,所以封裝好的survey對象也包含了校驗后的信息女气。
- BindingResult bindingResult用于收集錯誤信息,當有錯誤信息時测柠,hasError()方法為true炼鞠。
package com.xt.handler;
import javax.validation.Valid;
import javax.websocket.server.PathParam;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.xt.pojo.Survey;
@Controller
@RequestMapping("/survey")
public class SurveyHandler {
@RequestMapping(value="/{week}/check")
public String checkMessage(@Valid @ModelAttribute("survey") Survey survey,@PathVariable String week,BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
System.out.println("error");
return "/survey.jsp";
} else {
System.out.println("success");
return "/success.jsp";
}
}
}
5.創(chuàng)建survey.jsp,將數(shù)據(jù)提交到handler中
- 注冊form標簽庫:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
- 從handler中獲取封裝好的survey對象,該對象中包含了錯誤信息:
form:form modelAttribute="survey"
- 如果有錯誤信息將錯誤信息打印:
<span><form:errors path="name"/></span><br/>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>survey</title>
</head>
<body>
<form:form modelAttribute="survey" action="/springMVCT2/survey/201907/check" method="post">
<fieldset>
<legend>讀者調(diào)查問卷</legend>
<!-- 基本信息 start -->
<fieldset>
<legend>基本信息</legend>
<table>
<tr><td>姓名</td>
<td><input name="name"><span><form:errors path="name"/></span><br/></td>
</tr>
<tr><td>年齡</td>
<td><input name="age"><span><form:errors path="age"/></span><br/></td>
</tr>
<tr><td>聯(lián)系電話</td>
<td><input name="tel"><span><form:errors path="tel"/></span><br/></td>
</tr>
</table>
</fieldset>
<!-- 基本信息 end -->
<!-- 調(diào)查信息 start -->
<fieldset>
<legend>調(diào)查信息</legend>
<b>您喜歡的本期封面和內(nèi)容版式設(shè)計嗎轰胁?</b><br/>
<textarea rows="3" cols="100" name="answer1"></textarea><br/>
<b>您喜歡的本期的哪幾篇文章簇搅?</b><br/>
<textarea rows="3" cols="100" name="answer2"></textarea><br/>
<b>您不喜歡的本期的哪幾篇文章?</b><br/>
<textarea rows="3" cols="100" name="answer3"></textarea>
</fieldset>
<!-- 調(diào)查信息 end -->
<center><input type="submit" value="提交調(diào)查"></center>
</fieldset>
</form:form>
</body>
</html>
知識點二:使用ModelAndView對象進行控制層傳參
ModelAndView mv = new ModelAndView("/survey.jsp");
return mv;
- 注意:
@Valid @ModelAttribute("survey") Survey survey
和BindingResult bindingResult
之間不能添加其它注解软吐。
package com.xt.handler;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.xt.pojo.Survey;
@Controller
@RequestMapping("/survey")
public class SurveyHandler {
@RequestMapping(value="/{week}/check",method=RequestMethod.POST)
public ModelAndView checkMessage(HttpServletRequest req, @PathVariable("week") String week,@Valid @ModelAttribute("survey") Survey survey,BindingResult bindingResult) {
survey.setWeek(week);
if (bindingResult.hasErrors()) {
System.out.println("success");
ModelAndView mv = new ModelAndView("/survey.jsp");
return mv;
} else {
System.out.println("error");
ModelAndView mv = new ModelAndView("/success.jsp");
mv.addObject("week",survey.getWeek());
// mv.addObject("name",survey.getName());
req.setAttribute("name", survey.getName());
mv.addObject("age",survey.getAge());
mv.addObject("tel",survey.getTel());
mv.addObject("answer1",survey.getAnswer1());
mv.addObject("answer2",survey.getAnswer2());
mv.addObject("answer3",survey.getAnswer3());
System.out.println("success");
return mv;
}
}
}
知識點三:給request瘩将,session作用域賦值
方法:直接在public ModelAndView checkMessage(HttpServletRequest req)
參數(shù)中添加HttpServletRequest req,HttpSession sessions
。
知識點四:利用form標簽庫從model中讀取數(shù)據(jù)
`
傳統(tǒng)方式中,我們生成復(fù)選框姿现,下拉選框肠仪,都直接在jsp頁面編寫好html代碼,
但是這種方式备典,不利于代碼的可擴展性异旧,比如省份下拉框中,如果新增了其他的省份提佣,
需要修改很多處的代碼吮蛹,給代碼的可維護性大大降低。
因此我們一般在程序設(shè)計中拌屏,一般采用從數(shù)據(jù)庫讀出的方式潮针,再結(jié)合標簽來生成相應(yīng)的代碼。
以生成省份下拉框為例進行演示倚喂。
`
編寫Province pojo類
package com.xtkj.pojo;
public class Province {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Province() {
super();
// TODO Auto-generated constructor stub
}
public Province(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Province [id=" + id + ", name=" + name + "]";
}
}
編寫service層每篷,將查詢到的provinces返回給controler層
package com.xtkj.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.xtkj.pojo.Province;
@Service("userService")相當于<bean id="userService" class="...."></bean>
@Service("userService")引號里面的內(nèi)容<bean里面的id="userService">
@Service("userService")
public class UserService {
public List<Province> getProvince(){
List<Province> list = new ArrayList<Province>();
list.add(new Province(1, "湖北"));
list.add(new Province(2, "湖南"));
list.add(new Province(3, "廣西"));
list.add(new Province(4, "廣東"));
return list;
}
}
@Service("userService")
就類似于@Controller
在將service注入到handler中
有兩種方法:
1.@Autowired 自動注入端圈,需要@Service("userService")
與private UserService userService;
對象名一致
2.@Resource(name="userService")//獲取指定id的bean,通過service名稱注入
package com.xtkj.handler;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.xtkj.pojo.Province;
import com.xtkj.pojo.User;
import com.xtkj.service.UserService;
@Controller
@RequestMapping("/")
public class UserHandler {
@Autowired
//@Resource(name="userService")//獲取指定id的bean
private UserService userService ;
@RequestMapping("/regist")
public String regist(@Valid @ModelAttribute("user") User user,BindingResult br){
if(br.hasErrors()){
return "/regist.jsp";
}else{
System.out.println("account="+user.getAccount());
return "/welcome.jsp";
}
}
@RequestMapping("/goRegist")
public String goRegist(HttpServletRequest req){
System.out.println("userService="+userService);
List<Province> province = userService.getProvince();
req.setAttribute("provinces", province);
req.setAttribute("user", new User());
return "/regist.jsp";
}
}
注意:由于進入注冊頁面就需要有省份下拉框的信息,所以矗晃,在進入regist.jsp之前首先應(yīng)該
調(diào)用查詢方法,然后再請求轉(zhuǎn)發(fā)給jsp頁面宴倍。這樣jsp頁面才能獲取Province數(shù)據(jù)喧兄,由此啊楚,就有了
public String goRegist(HttpServletRequest req){...}
方法吠冤。
編寫jsp頁面恭理,使用<form:>
省份:<form:select path="province">
<form:options items="${provinces }" itemLabel="name" itemValue="id"/>
</form:select><br/>
<input type="submit" value="注冊"/>
</form:form>
完整代碼如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'regist.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<style type="text/css">
span{
color:red;
}
</style>
</head>
<body>
<form:form modelAttribute="user" action="regist.form">
賬號:<input type="text" name="account" value="${user.account }"/><span><form:errors path="account"/></span><br/>
密碼:<input type="password" name="password" value="${user.password }"/><span><form:errors path="password"/></span><br/>
頭像:<img src="img/wa.png"/><br/>
省份:<form:select path="province">
<form:options items="${provinces }" itemLabel="name" itemValue="id"/>
</form:select><br/>
<input type="submit" value="注冊"/>
</form:form>
</body>
</html>
知識點五:在SpringMVC中訪問靜態(tài)資源
由于在web.xml中DispatcherServlet的url-pattern為'/'攔截一切資源訪問拯辙,所以jsp頁面請求訪問靜態(tài)資源也會被攔截。解決辦法有以下兩種:
方法一:修改<url-pattern>
<!-- springMVC核心 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!-- <url-pattern>/</url-pattern> -->
<url-pattern>*.form</url-pattern>
</servlet-mapping>