Spring MVC 属于 Spring FrameWork 的产品,提供了构建 Web 应用程序的全功能 MVC 模块。
SpringMVC 是一种基于 Java 的实现了 Web MVC 设计模式的轻量级 Web 框架。Spring MVC采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。
前端控制器(DispatcherServlet),本质就是一个Servlet。它负责接受用户的请求和转发请求。
依赖 jar 包
除Spring需要的jar包外,需要导入spring-web和srping-webmvc两个jar包。
配置文件
需要添加context和mvc约束,开启Spring的注解扫描,加载mvc驱动
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<context:component-scan base-package="com.bodhixu.ssm"/>
<mvc:annotation-driven />
beans>
前端控制器
修改“web.xml”,注册前端控制器,并加载spingmvc配置文件。
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SpringMVC01_DispatcherServletdisplay-name>
<servlet>
<servlet-name>DispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc-config.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>DispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
@Controller
public class CustomController {
@RequestMapping("/home")
public void home() {
System.out.println("home.....");
}
}
可以通过@RequestMapping 注解,为控制器指定处理 URL 请求的方法。
4.1 基本用法
@RequestMapping 注解一般用于方法。最基本的属性是value,用来指定映射的请求地址。
映射路径前面的"/"可以省略。当只有value属性时,可以省略value。
@Controller
public class BookController {
//映射路径最前面的“/”表示web应用根路径
@RequestMapping(value="/book/test1")
public void test1() {
System.out.println("test1.....");
}
//映射路径最前面的“/”可以省略
@RequestMapping(value="book/test2")
public void test2() {
System.out.println("test2.....");
}
//只有value属性,value可省略
@RequestMapping("book/test3")
public void test3() {
System.out.println("test3.....");
}
}
4.2 窄化请求映射
@RequestMapping 除了可用于方法,也可以用于类用来实现窄化请求映射。
@Controller
@RequestMapping("book2")
public class BookController2 {
@RequestMapping("/test1") //等价于 "/book2/test1"
public void test1() {
System.out.println("test1.....");
}
@RequestMapping("/test2") //等价于 "/book2/test2"
public void test2() {
System.out.println("test2.....");
}
}
4.3 限制请求方式
method 属性用来限制请求的 method 类型( GET、POST、PUT、DELETE等)。method 的值一旦指定,那么处理方法就只对指定类型的请求进行处理。method的属性值可以是某种类型,也可以是类型数组。
@RequestMapping(value="/test1", method=RequestMethod.POST)
public void test1() {
System.out.println("test1.....");
}
@RequestMapping(value="/test2", method= {RequestMethod.POST, RequestMethod.GET})
public void test2() {
System.out.println("test2.....");
}
如果请求类型不允许,则会显示405错误。
可以通过控制器映射的方法参数,接收请求中的参数信息。
5.1 简单数据类型
简单数据类型包括:整型(Integer、int)、单精度浮点型(Float、float)、双精度浮点型(Double、double)、布尔型(Boolean、boolean)、字符串(String)
<form action="${pageContext.request.contextPath }/user/login">
账号:<input type="text" name="uname"/> <br>
密码:<input type="password" name="upassword"/> <br>
<button type="submit">登录button>
form>
@RequestMapping("/user/login")
public void login(String uname, String upassword) {
System.out.println("uname:" + uname);
System.out.println("upassword:" + upassword);
}
<form action="${pageContext.request.contextPath }/user/login2">
账号:<input type="text" name="uname"/> <br>
密码:<input type="password" name="upassword"/> <br>
<button type="submit">登录button>
form>
@RequestMapping("/user/login2")
public void login2(@RequestParam(name="uname", required=true) String name,
@RequestParam(name="upassword") String pwd) {
System.out.println("name:" + name);
System.out.println("pwd:" + pwd);
}
5.2 POJO 类型
SpringMVC 会按请求参数名和 POJO 属性名进行自动匹 配,自动为该对象填充属性值。
<form action="${pageContext.request.contextPath }/user/login3">
账号:<input type="text" name="uname"/> <br>
密码:<input type="password" name="upassword"/> <br>
<button type="submit">登录button>
form>
@RequestMapping("/user/login3")
public void login(User user) {
System.out.println(user);
}
5.3 POJO 中包装类型
SpringMVC 可以在表单在的 name 属性使用“对象名.属性名”,进行级联绑定。
public class Book {
private String bname;
private int bprice;
public class Student {
private String sname;
private Book book;
<form action="${pageContext.request.contextPath }/stu/test">
姓名: <input type="text" name="sname"> <br>
书名: <input type="text" name="book.bname"> <br>
价格: <input type="text" name="book.bprice"> <br>
<button type="submit">提交button>
form>
@RequestMapping("stu/test")
public void test(Student stu) {
System.out.println("stu = " + stu);
}
5.4 简单类型数组/集合
在开发中,比如根据id批量删除等操作,可以使用数组绑定。
<form action="${pageContext.request.contextPath }/book/delete">
删除:
<input type="checkbox" name="bids" value="100">100 <br>
<input type="checkbox" name="bids" value="101">101 <br>
<input type="checkbox" name="bids" value="102">102 <br>
<input type="checkbox" name="bids" value="103">103 <br>
<input type="submit" value="提交">
form>
@RequestMapping("book/delete")
public void delete(int[] bids) {
for (int id : bids) {
System.out.println(id);
}
}
5.5 POJO 集合
public class Subject{
private long sid;
private String sname;
}
public class Teacher {
private String tname;
private List<Subject> subs;
<form action="${pageContext.request.contextPath }/teacher/test">
姓名:<input type="text" name="tname"> <br>
学科编号:<input type="text" name="subs[0].sid"><br>
学科名称:<input type="text" name="subs[0].sname"><br><br>
学科编号:<input type="text" name="subs[1].sid"><br>
学科名称:<input type="text" name="subs[1].sname"><br>
<input type="submit" value="提交">
form>
@RequestMapping("teacher/test")
public void test(Teacher th) {
System.out.println(th);
}
5.6 Servlet API 类型
HttpServletRequest
HttpServletResponse
HttpSession
后面案例中介绍
6.1 返回String
@RequestMapping("/test")
public String test() {
return "/jsp/test1.jsp"; //请求转发,返回值为转发的url地址
}
6.2 请求转发和重定向
如果返回的字符串中带 forward: (请求转发)或 redirect: (重定向)前缀 时,SpringMVC 会对他们进行特殊处理,将 forward 和 redirect:当成指示符,其后的字符串作为 真实的URL 来处理(视图解析器的前缀和后缀失效)。
@RequestMapping("/test2")
public String test(HttpSession session) {
session.setAttribute("msg", "hahaha");
return "redirect:/jsp/test2.jsp"; //其中“/”表示web应用根路径
}
6.3 返回void
如果你想按照传统Servlet方式处理请求,则可以传入HttpServletRequest、HttpServletResponse进行手动处理。一般可以用来给客户端返回Json数据。后面详细介绍。
6.4 返回ModelAndView
返回模型视图,后面介绍
SpringMVC框架默认的视图解析器是InternalResourceViewResolver,这个视图解析器支持JSP视图解析。
视图解析器中可以配置前缀名和后缀名。如果配置前缀和后缀,视图返回值表示是逻辑视图名,真实的视图名=“前缀” + 逻辑视图名 + “后缀”。
<bean id="jspResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/" />
<property name="suffix" value=".jsp" />
bean>
@RequestMapping("/test")
public String test() {
return "test"; //等价于“/jsp/test.jsp”
}
Spring MVC提供了Model、ModelAndView、ModelMap等模型向域中添加数据。
8.1 ModelAndView
处理方法返回值类型为 ModelAndView时, 可通过该对象添加模型数据并返回视图。
@RequestMapping("test")
public ModelAndView test() {
//创建模型视图
ModelAndView mv = new ModelAndView();
//设置数据模型
Book book = new Book("java", 200);
mv.addObject("book", book);
//设置视图
mv.setViewName("/jsp/test.jsp");
return mv;
}
8.2 Model、ModelMap、Map
形参为 org.springframework.ui.Model、org.springframework.ui. ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。
其中Map的key是域属性名称,value为域属性的值。
@RequestMapping("test2")
public String test(Model model) {
Book book = new Book("java", 200);
model.addAttribute("book", book);
return "/jsp/test2.jsp";
}
@RequestMapping("test3")
public String test(ModelMap map) {
Book book = new Book("java", 200);
map.put("book", book);
map.put("msg", "数据模型");
return "/jsp/test2.jsp";
}
@RequestMapping("test4")
public String test(Map<String, Object> map) {
Book book = new Book("java", 200);
map.put("book", book);
map.put("msg", "数据模型");
return "/jsp/test2.jsp";
}
8.3 @SessionAttributes
默认情况下Spring MVC将模型中的数据存储到request域中。当一个请求结束后,数据就失效了。如果要跨页面使用,那么需要使用到session。而@SessionAttributes注解就可以使得模型中的数据存储一份到session域中。
@SessionAttributes必须只能在控制器类上标注一个。
//@SessionAttributes(types= Book.class)
//@SessionAttributes(types= {Book.class, String.class}) //向session中存入指定的域属性类型的对象
//@SessionAttributes(value="book")
@SessionAttributes(value= {"book","msg"}) //向session中存入指定的域属性名称的对象
@Controller
public class BookController3 {
@RequestMapping("testSession")
public String test(Map<String, Object> map) {
Book book = new Book("java", 200);
map.put("book", book);
map.put("msg", "数据模型");
return "redirect:/jsp/test3.jsp"; //重定向
}
}