Spring MVC框架:第三章:獲取請(qǐng)求參數(shù)和頁(yè)面跳轉(zhuǎn)控制

獲取請(qǐng)求參數(shù)
1.什么是請(qǐng)求參數(shù)?

<a href="emp/remove?empId=3">刪除</a>

<form action="emp/save" method="post">
    姓名:<input type="text" name="empName"/><br/>
    年齡:<input type="text" name="empAge"/><br/>
    工資:<input type="text" name="empSalary"/><br/>
    <input type="submit" value="保存"/>
</form>

2.請(qǐng)求參數(shù)的四種情況
①一名一值

<a href=“emp/remove?empId=3”>刪除

在handler方法的參數(shù)上使用@RequestParam注解。

@RequestMapping("/caseOne")
public String caseOne(@RequestParam(“empId”) Integer empId) {
System.out.println(“empId=”+empId);
return “result”;
}

SpringMVC會(huì)自動(dòng)幫我們進(jìn)行類(lèi)型轉(zhuǎn)換。如果請(qǐng)求參數(shù)的名字和handler方法中對(duì)應(yīng)形參的名字一致那么可以省略@RequestParam注解。

@RequestMapping("/caseOne")
public String caseOne(Integer empId) {
System.out.println(“empId=”+empId);
return “result”;
}

②一名多值

<form action="team" method="post">
    請(qǐng)選擇你最喜歡的球隊(duì):
    <input type="checkbox" name="team" value="Brazil"/>巴西
    <input type="checkbox" name="team" value="German"/>德國(guó)
    <input type="checkbox" name="team" value="French"/>法國(guó)
    <input type="checkbox" name="team" value="Holland"/>荷蘭
    <input type="checkbox" name="team" value="Italian"/>意大利
    <input type="checkbox" name="team" value="China"/>中國(guó)
    <br/>
    <input type="submit" value="保存"/>
</form>

使用List或數(shù)組來(lái)接收。

@RequestMapping("/caseTwo")
public String caseTwo(@RequestParam(“team”) List teams) {
System.out.println(teams);
return “result”;
}
@RequestMapping("/caseTwo")
public String caseTwo(@RequestParam(“team”) String[] teams) {
System.out.println(Arrays.asList(teams));
return “result”;
}

③表單數(shù)據(jù)正好對(duì)應(yīng)一個(gè)實(shí)體類(lèi)

<form action="emp/save" method="post">
    姓名:<input type="text" name="empName"/><br/>
    年齡:<input type="text" name="empAge"/><br/>
    工資:<input type="text" name="empSalary"/><br/>
    <input type="submit" value="保存"/>
</form>

實(shí)體類(lèi):

public class Employee {
private Integer empId;
private String empName;
private int empAge;
private double empSalary;
……

直接使用和表單對(duì)應(yīng)的實(shí)體類(lèi)類(lèi)型接收

@RequestMapping("/caseThree")
public String caseThree(Employee employee) {
System.out.println(employee);
return “result”;
}

④表單對(duì)應(yīng)的實(shí)體類(lèi)包含級(jí)聯(lián)屬性

public class Student {

private Integer studentId;
private String studentName;
private School school;
private List<Subject> subjectList;
private Subject[] subjectArray;    
private Set<Teacher> teacherSet;    	
private Map<String,String> scoreMap;

{
 //在各種常用數(shù)據(jù)類(lèi)型中,只有Set類(lèi)型需要提前初始化
    //并且要按照表單將要提交的對(duì)象數(shù)量進(jìn)行初始化
    //Set類(lèi)型使用非常不便,要盡可能避免使用Set
	teacherSet = new HashSet<>();
	teacherSet.add(new Teacher());
	teacherSet.add(new Teacher());
	teacherSet.add(new Teacher());
}

handler方法

@RequestMapping("/get/param/multi/value")
public String getParamOneNameMultiValue(@RequestParam(“team”) List teamList) {
for (String team : teamList) {
System.out.println(team);
}
return “target”;
}

@RequestMapping("/get/param/entity")
public String getParamEntity(Employee employee) {    		
	System.out.println(employee);    		
	return "target";
}

//@RequestMapping("/get/param/entity")
public String getParamEntityParam(@RequestParam("empName") String empName) {    		
	System.out.println("empName="+empName);    		
	return "target";
}

@RequestMapping("/get/param/fuza")
public String getParamFuza(Student student) {
	System.out.println("StudentId="+student.getStudentId());
	System.out.println("StudentName="+student.getStudentName());
	System.out.println("SchoolId="+student.getSchool().getSchoolId());
	System.out.println("SchoolName="+student.getSchool().getSchoolName());
	List<Subject> subjectList = student.getSubjectList();
	for (Subject subject : subjectList) {
		System.out.println("科目名稱(chēng)="+subject.getSubjectName());
	}
	
	Subject[] subjectArray = student.getSubjectArray();
	for (Subject subject : subjectArray) {
		System.out.println("科目名稱(chēng)="+subject.getSubjectName());
	}
	
	Set<Teacher> teacherSet = student.getTeacherSet();
	for (Teacher teacher : teacherSet) {
		System.out.println("老師姓名="+teacher.getTeacherName());
	}
	
	Map<String, String> scoreMap = student.getScoreMap();
	Set<String> keySet = scoreMap.keySet();
	for (String key : keySet) {
		String value = scoreMap.get(key);
		System.out.println(key+":"+value);
	}
	
	return "target";
}

提交數(shù)據(jù)的表單

<form action="${pageContext.request.contextPath }/get/param/fuza" method="post">
		學(xué)生編號(hào):<input type="text" name="studentId" value="22" /><br/>
		學(xué)生姓名:<input type="text" name="studentName" value="tom" /><br/>
		
		<!-- getSchool().setSchoolId() -->
		學(xué)校編號(hào):<input type="text" name="school.schoolId" value="33" /><br/>
		學(xué)校名稱(chēng):<input type="text" name="school.schoolName" value="at" /><br/>
		
		科目1名稱(chēng):<input type="text" name="subjectList[0].subjectName" value="理論" /><br/>
		科目2名稱(chēng):<input type="text" name="subjectList[1].subjectName" value="倒庫(kù)"/><br/>
		科目3名稱(chēng):<input type="text" name="subjectList[2].subjectName" value="路考"/><br/>
		
		科目4名稱(chēng):<input type="text" name="subjectArray[0].subjectName" value="撞人"/><br/>
		科目5名稱(chēng):<input type="text" name="subjectArray[1].subjectName" value="防碰瓷"/><br/>
		科目6名稱(chēng):<input type="text" name="subjectArray[2].subjectName" value="追尾"/><br/>
		
		老師姓名:<input type="text" name="teacherSet[0].teacherName" value="卡卡西"/><br/>
		老師姓名:<input type="text" name="teacherSet[1].teacherName" value="伊魯卡"/><br/>
		老師姓名:<input type="text" name="teacherSet[2].teacherName" value="大蛇丸"/><br/>
		
		考試成績(jī):<input type="text" name="scoreMap['shuxue']" value="25" /><br/>
		考試成績(jī):<input type="text" name="scoreMap['yuwen']" value="16" /><br/>
		考試成績(jī):<input type="text" name="scoreMap['yingyu']" value="7" /><br/>
		考試成績(jī):<input type="text" name="scoreMap['lol']" value="100" /><br/>
		考試成績(jī):<input type="text" name="scoreMap['dota']" value="300" /><br/>
		
		<input type="submit" value="提交"/>
	</form>

	<br/><br/>
	
	<form action="${pageContext.request.contextPath }/get/param/entity" method="post">
		<!-- private Integer empId; -->
		編號(hào):<input type="text" name="empId"/><br/>
		
		<!-- private String empName; -->
		姓名:<input type="text" name="empName"/><br/>
		
		<!-- private Integer empAge; -->
		年齡:<input type="text" name="empAge"/><br/>
		
		<!-- private Double empSalary; -->
		工資:<input type="text" name="empSalary"/><br/>
		
		<input type="submit" value="提交"/>
	</form>

	<br/><br/>

	<form action="${pageContext.request.contextPath }/get/param/multi/value" method="post">
		請(qǐng)選擇你最喜歡的球隊(duì):<br/>
		<input type="checkbox" name="team" value="German"/>德國(guó)<br/>
		<input type="checkbox" name="team" value="Brazil"/>巴西<br/>
		<input type="checkbox" name="team" value="Italian"/>意大利<br/>
		<input type="checkbox" name="team" value="China"/>中國(guó)<br/>
		<input type="checkbox" name="team" value="Korea"/>韓國(guó)<br/>
		<input type="submit" value="提交"/>
	</form>

web.xml配置,解決字符亂碼

<!-- 在SpringMVC環(huán)境下對(duì)請(qǐng)求和響應(yīng)過(guò)程強(qiáng)制使用UTF-8字符集進(jìn)行編碼、解碼 -->
	<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>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

頁(yè)面跳轉(zhuǎn)控制
1.轉(zhuǎn)發(fā)指令

@RequestMapping("/testForward")
public String testForward() {
return “forward:/target.jsp”;
}

forward:/target.jsp
表示方法執(zhí)行完成后轉(zhuǎn)發(fā)到/target.jsp。想一想有了視圖解析器拼接字符串指定轉(zhuǎn)發(fā)頁(yè)面之后forward是否多余呢?

2.重定向指令

@RequestMapping("/testRedirect")
public String testRedirect() {
return “redirect:/target.jsp”;
}

redirect:/target.jsp
表示方法執(zhí)行完成后重定向到/target.jsp。這里重定向中使用的路徑和我們以前的寫(xiě)法不同,沒(méi)有以Web應(yīng)用名稱(chēng)開(kāi)頭,這是因?yàn)镾pringMVC會(huì)替我們加上。

3.使用原生對(duì)象完成轉(zhuǎn)發(fā)

@RequestMapping("/testForward")
public void testForward2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/target.jsp").forward(request, response);
}

你看,使用原生request對(duì)象執(zhí)行轉(zhuǎn)發(fā)后,handler方法的返回值就必須是void,意思是我們自己指定了響應(yīng)方式,不需要SpringMVC再進(jìn)行處理了。一個(gè)請(qǐng)求只能有一個(gè)響應(yīng),不能在handler方法里面給一個(gè),然后SpringMVC框架再給一個(gè)。

4.使用原生對(duì)象完成重定向

@RequestMapping("/testRedirect")
public void testRedirect2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendRedirect(request.getContextPath()+"/target.jsp");
}

使用原生response對(duì)象執(zhí)行重定向后,handler方法的返回值同樣需要設(shè)置為void,原因同上。