首页 > 代码库 > SpringMVC学习笔记(二): 日常使用功能

SpringMVC学习笔记(二): 日常使用功能

前提:

1、web.xml 和spring-mvc核心配置如:SpringMVC学习笔记(一): 基础知识中注解实现。

2、类的@RequestMapping(value=http://www.mamicode.com/"/annotationController")

3、spring-mvc 推荐使用注解实现。


一、数据的接收

(一)URL参数数据的接收

1、使用 HttpServletRequest 获取参数

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 利用 HttpServletRequest 获取参数
	 * @param request
	 * @return
	 */
	@RequestMapping(value=http://www.mamicode.com/"/getParam.do")>

1)访问:http://localhost:8080/JavaSpringMvc/annotationController/getParam.do?name=shaoxioabao

2)后台打印shaoxioabao,没有参数的时候也不会报错。


2、直接获取参数

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 注解获取参数:获取参数的controller
	 * 访问路径:getParam1.do?name=sam&id=12
	 * 1、在参数列表上直接定义参数名称,参数名称\类型要匹配接收。
	 * 2、时间的接收:
	 * @param request
	 * @return
	 */
	@RequestMapping(value=http://www.mamicode.com/"/getParam1.do")>

1)访问:http://localhost:8080/JavaSpringMvc/annotationController/getParam1.do?name=shaoxioabao

2)后台输出:shaoxioabao--null--null

3)如Date参数的接收需要属性注册器的使用,不然接收报错。

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 属性编辑器
	 * 注册时间类型的属性注册器
	 * @param binder
	 */
	@InitBinder
	public void initBinder(ServletRequestDataBinder binder){
		
		binder.registerCustomEditor(Date.class, 
					new CustomDateEditor(new SimpleDateFormat("yyyy-mm-dd"), true));
	}
</span></span>


3、使用JavaBean获取参数

1)JavaBean代码:Person 和User

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">package com.springmvc.bean;
import java.util.Date;

public class Person {
	
	private String name;
	
	private Integer age;
	
	private String address;
	
	private Date birthday;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the age
	 */
	public Integer getAge() {
		return age;
	}

	/**
	 * @param age the age to set
	 */
	public void setAge(Integer age) {
		this.age = age;
	}

	/**
	 * @return the address
	 */
	public String getAddress() {
		return address;
	}

	/**
	 * @param address the address to set
	 */
	public void setAddress(String address) {
		this.address = address;
	}

	/**
	 * @return the birthday
	 */
	public Date getBirthday() {
		return birthday;
	}

	/**
	 * @param birthday the birthday to set
	 */
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address
				+ ", birthday=" + birthday + "]";
	}
}
</span></span>
<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">package com.springmvc.bean;

public class User {
	
	private String name;
	
	private Integer age;
	

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the age
	 */
	public Integer getAge() {
		return age;
	}

	/**
	 * @param age the age to set
	 */
	public void setAge(Integer age) {
		this.age = age;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
}
</span></span>

2)单个Bean参数

①、Controller代码:

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 利用javaBean获取参数
	 * 地址:http://localhost:8080/JavaSpringMvc/annotationController/getBeanParam.do?name=sam&id=123&birthday=2015-09-12
	 * 规则:1、传递的参数的名字,与实体类中setXXX中的XXX名字一致。
	 *      2、首字母大小写不限。
	 * @param person
	 * @return
	 */
	@RequestMapping(value=http://www.mamicode.com/"/getBeanParam.do")>

②、传递的参数的名字,与实体类中setXXX中的XXX名字一致。

③、首字母大小写不限。

④、Date类型的数据,需要属性注册器的使用。


3)多个JavaBean

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 多个实体:
	 * 1、一份参数,两个对象都可以接收(如name属性参数)
	 * @param person
	 * @param user
	 * @return
	 */
	@RequestMapping(value=http://www.mamicode.com/"/getBeanParam2.do")>

①、注意:一份参数,两个对象都可以接收(如name属性参数):输出

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">Person [name=sam, age=null, address=null, birthday=Mon Jan 12 00:09:00 CST 2015]
User [name=sam, age=null]</span></span>


4、接收数组参数

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 接收数组参数
	 * 1、访问地址:/annotationController/getArrayParams.do?name=sam&name=kevin
	 * 2、数组的名称与参数名称一致。
	 * 3、可以对checkBox的值接收
	 * @param name
	 * @return
	 */
	@RequestMapping(value=http://www.mamicode.com/"/getArrayParams.do")>
1)访问地址:/annotationController/getArrayParams.do?name=sam&name=kevin

2)数组的名称与参数名称一致,都为name。


(二)Form表单数据的接收

1、页面表单:

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">  	<form name="fm" action="annotationController/getFormValue.do">
    	name:<input name="name" type="text"><br>
    	age:<input name="age" type="text"><br>
    	address:<input name="address" type="text"><br>
    	birthday:<input name="birthday" type="text"><br>
    	<input type="submit" value=http://www.mamicode.com/" 提交 " >
>


1)action地址为: 类的@RequestMapping +方法的@RequestMapping

2、Controller 实现代码

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 接收表单信息
	 * 1、利用person Bean参数接收表单数据,名字的一致性
	 * 2、利用Model 返回数据
	 */
	@RequestMapping(value=http://www.mamicode.com/"/getFormValue.do",method=RequestMethod.POST)>
1)直接利用JavaBean即可接收表单数据。

2)使用Model对象参数,回显数据。


二、数据的回显


(一)myJsp.jsp页面接收显示参数

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	你好,springMVC !!
	<br/>
	${person.name}
	<br/>
	${person.age}
	<br/>
	<fmt:formatDate pattern="yyyy-mm-dd" value=http://www.mamicode.com/"${person.birthday}"/>>1、引入jstl标签。


(二)实现方式

1、ModelAndView 对象实现

1)代码

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 返回model给页面显示
	 * 把结果数据放入request中,其实不推荐使用
	 */
	@RequestMapping(value=http://www.mamicode.com/"/returnValues.do")>

2)分析

1)把返回的数据放入Map,再把Map放入返回的ModelAndView对象中。

2)ModelAndView("myJsp", map):第一个参数为view,第二个参数为model 。


2、利用map参数实现

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 利用map参数:不建议使用
	 * 1、spring会认为这个map参数就是ModelAndView对象中的Map,
	 * 会自动交给视图解析器处理,返回页面。
	 * @return
	 */
	@RequestMapping(value=http://www.mamicode.com/"/returnValues2.do")>
1)方法中定义Map形参,spring会认为这个map参数就是ModelAndView对象中的Map,会自动交给视图解析器处理,返回页面

2)其实就是第一种方法的变种。


3、使用Model类的数据参数(推荐)

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 使用Model类的数据传输,推荐使用
	 * @param model
	 * @return
	 */
	@RequestMapping(value=http://www.mamicode.com/"/returnValuesModel.do")>
1)在方法中定义Model对象的形参,把数据利用Model的addAttribute()加进去即可。


三、转发与重定向

(一)转发-默认

1、同一个Controller:可以省略forward

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 单纯的转发功能,显示myAjaxForm.jsp页面
	 */
	@RequestMapping(value=http://www.mamicode.com/"/toAjaxPage.do")>

2、不同的Controller

@RequestMapping(value=http://www.mamicode.com/"/toAjaxPage.do")>

(二)重定向 redirect

1、同一个Controller中的重定向

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 同一个Controller中的重定向
	 */
	@RequestMapping(value=http://www.mamicode.com/"/requestRedirect.do")>

1)方式:redirect关键字 + 方法的@RequestMapping 即可。


2、不同Controller中的重定向

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 不同Controller中的重定向
	 */
	@RequestMapping(value=http://www.mamicode.com/"/requestRedirect.do")>


1)redirect关键字 +" / " + 类@RequestMapping+ 方法@RequestMapping


四、Ajax

(一)Ajax请求页面:

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;"><input id="mybutton" type="button" value="AjaxToSpringMvc">
<script type="text/javascript">
  		$(function(){
  			$("#mybutton").click(function(){
  				$.ajax({
  					//url:"annotationController/getAjax.do",//注意访问地址的正确性
  					url:"annotationController/getAjaxTrue.do",//注意访问地址的正确性
  					type:"post",
  					dataType:"text",
  					data:{
  						name:"zhangsan"
  					},
  					success:function(responseText){
  						alert(responseText);
  					},
  					error:function(){
  						alert("system error");
  					}
  				});
  			});
  		});
  		
  	</script>
</span></span>

(二)HttpServletResponse 实现

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 接受Ajax的请求:不建议使用
	 * 1、返回值为void
	 * 2、定义HttpServletResponse,返回数据
	 * @param name
	 * @param response
	 */
	@RequestMapping(value=http://www.mamicode.com/"/getAjax.do")>
1、返回值为 void
2、定义HttpServletResponse,返回数据。


(三)PrintWriter 实现(推荐)

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	
	/**
	 * 接收Ajax的请求:建议直接使用PrintWriter
	 * @param name
	 * @param response
	 */
	@RequestMapping(value=http://www.mamicode.com/"/getAjaxTrue.do")>


五、上传

(一)配置上传组件 CommonsMultipartResolver 。

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">		<!-- 上传配置 -->
		<!-- id="multipartResolver"必须是multipartResolver -->
		<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
			<!-- maxUploadSize:文件上传的最大值以byte为单位 -->
			<property name="maxUploadSize" value=http://www.mamicode.com/"1024000">>

(二)上传页面:

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">    <form name="fmUpload" action="annotationController/fileUpload.do" method="post" enctype="multipart/form-data">
    	pic:<input type="file" name="pic"><br>
    	<input type="submit" value=http://www.mamicode.com/" 文件上传 " >
>

(三)Controller 上传实现

<span style="font-size:18px;"><span style="font-family:Arial;font-size:18px;">	/**
	 * 文件上传
	 * 1、必须先配置上传组件 CommonsMultipartResolver
	 * 2、
	 */
	@RequestMapping(value=http://www.mamicode.com/"/fileUpload.do")>

六、拦截器

(一)核心文件的配置

<span style="font-size:18px;">		<mvc:interceptors>
			<mvc:interceptor>
				<!-- 某一模块的拦截:/myPath/**, 拦截所有的请求/** -->
				<mvc:mapping path="/**"/>
				<bean class="com.springmvc.interceptor.MyIntercepor"></bean>
			</mvc:interceptor>
		</mvc:interceptors>
</span>

(二)自定义拦截器

<span style="font-size:18px;">package com.springmvc.interceptor;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * @Title: 自定义拦截器
 * @Description:
 * @Copyright: Copyright (c) 2015
 * @Company:
 * 
 * @author: SAM-SHO
 * @version: 1.0
 * @CreateDate:Jan 25, 2015
 */
public class MyIntercepor implements HandlerInterceptor {

	/**
	 * 执行时机:视图已经被解析完毕。Exception:监控
	 * 后置拦截
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object obj, Exception ex) throws Exception {
		System.out.println("afterCompletion...");
//		System.out.println(ex.getMessage());
		System.out.println("================");
	}

	/**
	 * 执行时机:Controller执行完,视图解析器没有把视图解析成页面
	 * 1、ModelAndView:统一修改视图,如修改Model对象的信息
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView mv) throws Exception {
		System.out.println("postHandler...");
		Map<String, Object> map = mv.getModel();
		map.put("testIntercepor", "append something");
	}

	/**
	 * 前置拦截,主要在于权限拦截。true-会去访问Controller
	 * Object-就是要访问的那个Controller
	 * 
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
		System.out.println("preHander...");
		System.out.println(obj.getClass().getName());
		return true;
	}

}
</span>

1、实现 HandlerInterceptor 接口。

2、实现3个方法,代表三个不同的执行时机:

1)preHandle :前置拦截,主要在于权限拦截。true-会去访问Controller。

2)postHandle:执行时机:Controller执行完,视图解析器没有把视图解析成页面。

3)afterCompletion:执行时机:视图已经被解析完毕。

3、参数:

1)Object:就是要访问的那个Controller。

2)ModelAndView:统一修改视图,如修改Model对象的信息。

3)Exception:监控异常。


七、@RequestBody 和 @ResponseBody 

(一)@RequestBody:

1、作用: 

1)该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上。

2)再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

2、使用时机:

1)GET、POST方式提时, 根据request header Content-Type的值来判断:

①、application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理)

②、multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据)

③、其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理)

2)PUT方式提交时, 根据request header Content-Type的值来判断:

①、application/x-www-form-urlencoded, 必须

②、multipart/form-data, 不能处理

③、其他格式, 必须;

说明:request的body部分的数据编码格式由header部分的Content-Type指定;


(二)@ResponseBody 

1、作用: 

该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

2、使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用

<span style="font-size:18px;">    @RequestMapping("/grid/easy")
    public @ResponseBody String initEasyUIDataGrid() {

		List<DataGrid> dataList = DataGridService.getData(0, 9);

	    logger.debug("Data rows Count: " + dataList.size() + " !");

        String dataJson = JsonUtil.toJson(dataList);

        logger.debug("Data grid JSON: " + dataJson);

		return dataJson;
    }
</span>


SpringMVC学习笔记(二): 日常使用功能