SpringMvc 教程
背景
Spring 框架提供了构建Web 应用程序的全功能MVC 模块。使用Spring 可插入的MVC 架构,
可以选择是使用内置的Spring Web 框架还是Struts 这样的Web 框架。通过策略接口,Spring 框架是
高度可配置的,而且包含多种视图技术,例如JavaServer Pages(JSP)技术、Velocity、Tiles、iText 和
POI。Spring MVC 框架并不知道使用的视图,所以不会强迫您只使用JSP 技术。Spring MVC 分离了控
制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
基于spring3.2 的采用annotation 方式搭建springMVC
环境
- 上官网下载对应的zip包当然该zip 并非最新的。
- 下载地址
- 解压之后得到目录:
打开libs 会看到会多jar ,
这里边包括了所有的jar 和source 和doc。当然我们只是需要使用jar 就可以了。
- 创建空的web项目目录结构如下:
其中user实体类为:
public class User {
private String name;
private Integer age;
private Date birth;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(String name, Integer age, Date birth) {
super();
this.name = name;
this.age = age;
this.birth = birth;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name) {
super();
this.name = name;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "[" + name + "]";
}
}
在项目中添加如下jar文件:
spring-webmvc-3.2.0.RELEASE.jar
spring-core-3.2.0.RELEASE.jar
spring-context-3.2.0.RELEASE.jar
spring-beans-3.2.0.RELEASE.jar
spring-web-3.2.0.RELEASE.jar
commons-logging.jar
spring-expression-3.2.0.RELEASE.jar
其中commons-logging.jar请单独下载。
在web.xml中添加过滤器的配置
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet
-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
这个org.springframework.web.servlet.DispatcherServle即为springMVC的核心控制器。
其中init-param中配置的是spring的配置文件的文件路径。
在WEB-INF下添加spring的配置文件spring-servlet.xml 文件内容如下:
<?xmlversion="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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
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
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<!-- 启动spring自动扫描-->
<context:component-scan base-package="com.niit.springmvc"/>
<mvc:annotation-driven /> <!-- 支持spring3.0新的mvc注解-->
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射-->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandle
rAdapter"/>
</beans>
其中schemaLocation和xmlns建议直接拷贝。
创建UserController如下:
@Controller
@RequestMapping("/user.do")
public class UserController {
@RequestMapping(params = "method=add")
public String addUser(Model model) {
model.addAttribute("message", "添加了一个用户");
System.out.println("UserController.addUser()");
return "/WEB-INF/jsp/addsuc.jsp";
}
}
其中@RequestMapping("/user.do")的配置是指:该controller的请求url为:user.do
@RequestMapping(params="method=add")的注解是指:凡是请求的url为:user.do而带了参数
method=add的请求会由方法addUser来处理。
addUser的形参model为后续讲解内容。
return "/WEB-INF/jsp/addsuc.jsp"; 是告诉spring完成处理之后直接进入该视图。
添加对应的页面,测试请求user.do?method=add
springMVC 的RequestMapping 的基本设置
-
在类的上面注解@RequestMapping("/ex.do")意思为所有的ex.do 请求全部进入该类处理。如上代码中编写@RequestMapping("/user.do"). 所有的user.do 请求都会进入该Controller。
-
在自定义的controller中会调用有@RequestMapping注解字样的方法来处理请求
@Controller
@RequestMapping("/user.do")
public class UserController {
@RequestMapping
public String addUser(Model model) {
model.addAttribute("message", "添加了一个用户");
System.out.println("UserController.addUser()");
return "/WEB-INF/jsp/addsuc.jsp";
}
}
-
当然可以编写多个处理请求的方法,而这些方法的调用都是通过@RequestMapping的属性类控制调用的。
@RequestMapping属性:
value:指定请求的实际地址,指定的地址可以是URI Template 模式(最终请求的url为类的注解的url+方法注解的url)
value的uri值为以下三类:
A) 可以指定为普通的具体值;如:
@Controller @RequestMapping("/user") public class UserController { @RequestMapping(value = "/some.do") public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { System.out.println("handleRequest"); return new ModelAndView("/WEB-INF/jsp/addsuc.jsp"); } }
该注解的是说:请求的url为”user/some.do”就会进入该方法(handleRequest)处理。
url:user/some.doB) 可以指定为含有某变量的一类值(URI Template Patterns with PathVariables);
如:@RequestMapping(value="/{userId}/delete.do",method=RequestMethod.GET) public String delete(@PathVariable String userId){ System.out.println("delete:"+userId); return "/WEB-INF/jsp/addsuc.jsp"; }
这个注解:url中带了参数的数据userId url:user/1123/delete.do
使用@PathVariable 指定形参接收url中的数据C) 可以指定为含正则表达式的一类值( URI Template Patterns with RegularExpressions);
如:@RequestMapping(value="/{userBirth:\\d{4}-\\d{2}-\\d{2}}/update.do") public String update(@PathVariable String userBirth){ System.out.println("userBirth:"+userBirth); return "/WEB-INF/jsp/addsuc.jsp"; }
请求的url类似:user/1990-11-11/update.do
使用@PathVariable 指定形参接收url中的数据
method: 指定请求的method类型, GET、POST、PUT、DELETE等; (也就是说只有制定类型的请求才会进入该方法处理)
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json,text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request 中必须包含某些指定的header 值,才能让该方法处理请求。
当类没有@RequestMapping 注解时,则直接参考方法的注解匹配对于的url。
如:
public class UserController {
@Controller
@RequestMapping("/user.do")
public void managerUser() {
}
}
在这里url 为user.do 则直接使用managerUser 处理请求。
在controller 中获取前台传递的参数
将页面数据传递到controller
页面表单:
<form action="user.do" method="post">
用户名:<input type="text" name="name"/><br/>
年龄:<input type="text" name="age"/><br/>
生日:<input type="text" name="birth"/><br/>
<input type="submit" value="添加"/>
</form>
Controller为:
/**
* 1、直接使用形参获取前台传递的参数数据
* 要注意的是形参的名字必须和页面参数的名字一致
* @param model
* @param name
* @param age
* @param birth
* @return
*/
@RequestMapping(method=RequestMethod.POST)
public String addUser(Model model,String name,Integerage,Date birth){
model.addAttribute("message", "添加了一个用户");
System.out.println("name:"+name +"\tage:"+age+"\tbirht:"+birth);
System.out.println("UserController.addUser()");
return "/WEB-INF/jsp/addsuc.jsp";
}
/**
* 2、使用对象接受前台传递的参数,
* 要注意的是前台传递的参数的名称必须和对象的属性名称一直,如果不
一致则可以使用@ModelAttribute("u")String uname指定
*/
@RequestMapping(method=RequestMethod.POST)
public String addUser(Model model,User user){
model.addAttribute("message", "添加了一个用户");
System.out.println("name:"+user.getName()+"\tage:"+user.getAge()
+"\tbirht:"+user.getBirth());
System.out.println("UserController.addUser()");
return "/WEB-INF/jsp/addsuc.jsp";
}
在controller 中获取web 元素
当某个方法需要使用web对象时
(request,response,session,application)
可以使用如下方式:
除过application其他的对象都可以直接设为方法的形参即可。spring会自动将对应的对象传递给对应的形参。
而application对象可以使用session对象获取。
当然也可以在方法中使用response对象重定向到其他的url 这时方法最后
return的url则可以视作无效。
同样的也可以使用request 对象转发到其他的url。
程序示例:
@RequestMapping(value="/web.do")
public String getWebElement(HttpServletRequest request,HttpServletResponse response,HttpSession session)throws IOException, ServletException{
System.out.println("使用request获取的前台参数:"+request.getParameter("pname"));
request.setAttribute("message", "这个是request中的数据");
session.setAttribute("message", "这个是session中的数据");
session.getServletContext().setAttribute("message","这个是application中的数据");
//response.sendRedirect("http://www.baidu.com");
//return null;
//request.getRequestDispatcher("/WEB-INF/jsp/showData.jsp").forward(request, response);
return "/WEB-INF/jsp/showData.jsp";
}
将controller 中数据传递到jsp 页面
1、可以在controller中获取request对象,然后将数据设置为request对象
的属性,然后使用转发的方式进入jsp即可。这一点不赘述。
2、将方法的返回值该为ModelAndView在返回时,将数据存储在
ModelAndView对象中如:
new ModelAndView("/WEB-INF/jsp/showData.jsp","message",message)
其中第一个参数为url,第二个参数为要传递的数据的key,第三个参数为数据对象。
在这里要注意的是 数据是默认被存放在request中的。
程序示例:
//使用modelAndView对象将数据传递到前台。
@RequestMapping(value="/mad/showData_1.do")
public ModelAndView showData_1(){
String message = "这个是要传递的数据";
//其中第一个参数为url,第二个参数为要传递的数据的key,第三个参数为数据对象。
//在这里要注意的是数据是默认被存放在request中的。
return new ModelAndView("/WEB-INF/jsp/showData.jsp","message",message);
}
前台页面获取方式:
request:${requestScope.message }<br/>
可以在类的前面添加注解
@SessionAttributes({"message","user"})
这个注解可以设置对应的model中参数也会在session中存储一份。该注解中的参数为一个集合,可以写多个,如上面的例子,其中message和user
都是存储的数据的key.
示例程序:
@SessionAttributes({"message","user"}) //modelAndView中
的对应的数据也会在session中存储一份
页面获取:
session:${sessionScope.message }<br/>
数据modelAndView返回一个集合
该处理方式和上面的处理方式一直,因为modelAndView接受的数据类型是
Object的,集合也是一样的处理方式
//使用modelAndView对象将数据传递到前台。
//传递多个参数(不同类型的)
@RequestMapping(value="/mad/showData_2.do")
public ModelAndView showData_2(){
System.out.println("showData_2");
String message = "这个是要传递的数据";
User user = new User("张三", 12, new Date());
List<User> us= new ArrayList<User>();
us.add(new User("张三", 12, new Date()));
us.add(new User("张四", 13, new Date()));
us.add(new User("张五", 14, new Date()));
ModelAndView mad = new ModelAndView("/WEB-INF/jsp/showData.jsp");
//将数据存入modelMap
mad.addObject("message", message);
mad.addObject(user);//默认为类名的首字母小写
mad.addObject("users", us);
return mad;
}
使用modelAndView传递多个参数。
可以通过ModelAndView的mad.addObject("message", message);方法设置参数。
该方法中第一个参数为数据的key,第二个参数为数据对象。
也可以使用mad.addObject(user);方法
该方法中数据的参数为数据对象,数据的key为该对象的类的类名(其中首字母小写)。
使用ModelMap传递多个数据到jsp中。
在方法的参数列表中添加形参ModelMap map,spring 会自动创建 ModelMap对象。
然后调用map的put(key,value)或者addAttribute(key,value)将数据放入map中,spring会自动将数据存入request。
示例程序:
//使用modelMap对象将数据传递到前台。
//传递多个参数(不同类型的)
@RequestMapping(value="/mad/showData_3.do")
public String showData_3(ModelMap map){
System.out.println("showData_3");
String message = "这个是要传递的数据";
User user = new User("张三", 12, new Date());
List<User> us= new ArrayList<User>();
us.add(new User("张三", 12, new Date()));
us.add(new User("张四", 13, new Date()));
us.add(new User("张五", 14, new Date()));
//将数据存入modelMap
map.put("message", message);
map.addAttribute("user", user);
map.put("users", us);
return "/WEB-INF/jsp/showData.jsp";
}
页面调用:
request:${requestScope.message }<br/>
session:${sessionScope.message }<br/>
application:${applicationScope.message }<br/>
<hr/>
<h1>ModelMap中的数据</h1>
${requestScope.message }<br/>
${requestScope.user.name }<br/>
<p>列表</p>
<c:forEach items="${requestScope.users }" var="u">
${u.name }-${u.age }-${u.birth }<br/>
</c:forEach>