spring mvc
它是用来开发基于 web 的应用程序。
流行的 mvc 框架
struts 1.x
webwork
struts 2.x (webwork+struts 1.x) ssh 经常暴露安全问题
springmvc 更容易上手,相对更安全
mvc 思想
model 模型 - 数据 domain
view 视图 - 数据的展现方式 jsp, jstl, el
controller 控制器 - 结合模型和视图,控制请求流程 servlet, controller
- servlet 如果作为控制器
缺点1:请求参数处理麻烦 String 值 = request.getParameter("参数名")
缺点2:当业务比较多时,servlet 类的数量膨胀不好管理
- controller 优点
优点:利用spring 各种思想,ioc, di, aop, 可扩展性高
spring mvc 使用步骤
1) 添加jar依赖
<!-- spring mvc 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.21.RELEASE</version> </dependency> <!-- servlet, jsp, 标签库 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.2.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
2) 添加 spring 配置文件 spring.xml 在beans标签之中加入以下配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" 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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 启用了 与 springmvc 相关的注解 @RestController @RequestMapping @ResponseBody @ExceptionHandler ... --> <mvc:annotation-driven/> <!--扫描控制器类,需要管理的包名下的类,如:com.westos.controller--> <context:component-scan base-package="包名.类名"/> <!-- 配置视图的完整路径(前缀 和 后缀) 配置视图解析器--> <mvc:view-resolvers> <mvc:jsp prefix="/" suffix=".jsp"/> </mvc:view-resolvers> </beans>
3) 添加控制器 web.xml文件中
spring 提供的前控制器(实际是一个servlet),作为一个统一入口,由它来分发请求,进入真正的控制器,需要使用 web.xml 文件配置它的路径 。
<!-- 配置前控制器 (servlet) ,下面的两个name,随便什么名字都可以,但是要两个都相同--> <servlet> <servlet-name>aa</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指明 spring 配置文件的位置, 根据它创建 spring容器 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!-- tomcat 启动时, 就创建和初始化 servlet, 同时创建 spring 容器 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>aa</servlet-name> <!-- / 用来匹配所有的路径 --> <url-pattern>/</url-pattern> </servlet-mapping>
自己提供的控制器
@Controller public class 控制器类 { @RequestMapping("请求路径") // 请求路径要唯一 public String 方法1() { } ... @RequestMapping("请求路径") public String 方法n() { } }
4) 配置视图
控制器方法的返回值是一个视图名,此视图名经过视图解析器解析为一个完整路径,利用请求转发跳转至该jsp。
<mvc:view-resolvers> <!-- 前缀 + 视图名 + 后缀 == 完整路径, 再利用请求转发跳转至 jsp --> <mvc:jsp prefix="/" suffix=".jsp" /> </mvc:view-resolvers>
5) 处理请求参数
地址实例:http://localhost:8080/c1?name=zhangsan&age=18&birthday=1995-9-6
方法1: 只要把方法的参数名称和请求的参数名称对象,springmvc 会将请求参数的值赋值给方法参数,并完成类型转换
日期类型需要特殊处理,请求参数类型转换出错,会出现400错误, 日期可以使用 @DateTimeFormat(pattern="日期格式")方法2:当请求参数较多时,可以把请求参数映射到java对象的属性上
class User{
private String name;
private Integer age;
private Date birthday;
}方法3:把参数信息包含在路径当中
删除用户/deleteUser?id=1
/deleteUser?id=2/deleteUser/1 删除1号用户
/deleteUser/2 删除2号用户// 例如 /deleteUser/1 {id} 的值就是1 /deleteUser/2 {id} 的值就是2
@RequestMapping("/deleteUser/{id}")
// @PathVariable 获取一个路径变量的值{id}, 然后复制给方法参数
public String c4(@PathVariable("id") int aa) {
System.out.println("值为:" + aa);
return "hello";
}6) 处理模型数据
Model接口, 需要调用Model 的相关方法把数据存入模型,页面上再从模型中获取数据并显示。
.addAttribute("名字", 对象); // 将数据加入 Model
原理:会把模型中数据放入request作用域
使用传统 servlet 中的类
HttpServletRequest, HttpServletResponse, HttpSession 他们都可以作为控制器方法的参数,直接使用即可,spring会把他们准备好
代码演示
1、使用springmvc的例子
控制类,也可以说这个类是用来定义页面的地址,以及控制页面跳转的类
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import java.util.Date;
// 表示它是一个控制器类, 并且配合扫描交给 spring 容器管理
@Controller
public class HelloController {
// 在web 的请求路径和 java 代码之间建立映射关系, 以方法为单位映射
@RequestMapping("/c1")
public String a1(String name, Integer age,@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday) {
System.out.println("执行了 a1 方法: name:" + name + " age:" + age + " birthday:" + birthday);
return "hello";
// 返回值代表视图的名字,但要注意它不是完整路径
// /hello.jsp
}
@RequestMapping("/c2")
public String a2() {
System.out.println("执行了 a2 方法");
// 没有经过视图解析器,直接转发进行了跳转
return "forward:/hello.jsp";
}
@RequestMapping("/c3")
public String c3(User user) {
System.out.println(user);
return "hello";
}
// 例如 /deleteUser/1 {id} 的值就是1 /deleteUser/2 {id} 的值就是2
@RequestMapping("/deleteUser/{id}")
// @PathVariable 获取一个路径变量的值{id}, 然后复制给方法参数
public String c4(@PathVariable("id") int aa) {
System.out.println("值为:" + aa);
return "hello";
}
// model 不需要自己创建, 只需要在控制器方法上声明一个 Model 类型的参数, spring 会帮我们创建好
@RequestMapping("/c5")
public String c5(Model model) {
model.addAttribute("name", "张三");
model.addAttribute("list", Arrays.asList("苹果","草莓","橘子"));
return "model";
}
// 跳转至 jsp 视图之前, springmvc 会把 model 中的每一项数据存入 request作用域
/*
如下存入:
request.setAttribute("name", "张三");
request.setAttribute("list", Arrays.asList("苹果","草莓","橘子"));
*/
@RequestMapping("/c6")
// 控制方法的返回值代表 视图名, Model 代表的是模型,用来存储数据
public ModelAndView c6() {
ModelAndView mav = new ModelAndView();
mav.addObject("name", "张三");
mav.addObject("list", Arrays.asList("苹果","草莓","橘子"));
//在对象中存入要跳转的视图的名字,也就是jsp页面的名字
mav.setViewName("model");
return mav;
}
}
hello.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
进入了hello.jsp
</body>
</html>
model.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!--从作用域中拿到值,用el表达式来取值-->
${name}
<hr>
<ul>
<c:forEach items="${list}" var="a">
<li>${a}</li>
</c:forEach>
</ul>
</body>
</html>
结果
下面是都是服务器上输出的结果(地址为:/c1、/c2、/c3、/deleteUser/{id} 的结果),它们都会跳转到hello.jsp页面,如下图:
//在地址栏输入 localhost:8080/c1?name=zhangsan&age=18&birthday=1995-9-6 时服务器结果如下结果如下
执行了 a1 方法: name:zhangsan age:18 birthday:Wed Sep 06 00:00:00 CST 1995
//输入 localhost:8080/c2 时,服务器输出结果如下
执行了 a2 方法
//输入localhost:8080/c3?name=jack 时,服务器输出的结果如下
User{name='jack', age=null, birthday=null}
//输入localhost:8080/deleteUser/3 时,服务器输出的结果如下
值为:3
当输入的地址是 /c5 或 /c6 时结果如下图所示:
2、使用传统 servlet 中的类例子
控制类
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Controller
public class ServletController {
@RequestMapping("/s1")
public String s1(HttpServletRequest request,HttpServletResponse response,HttpSession session) {
//session作用域中存入值,返回给视图servlet.jsp
session.setAttribute("name", "老王");
return "servlet";
}
}
servlet.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- page 找, request 找, session 找, application 找 会依次查找4个作用域,直到找到-->
${ sessionScope.name }
</body>
</html>
结果
总结
在 sping mvc 中运用注解的方式把代码放到容器中管理,减少了很多配置和代码的书写,用过它可以很简单的与jsp进行交互,不用在写繁琐的servlet代码,可以说是大大地好啦!!!
简而言之,加油吧!!!好好学习天天向上!!!