
- 
maven依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.3.4version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.3.3version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
dependencies>
配置核心控制器:web.xml配置DispatchServlet
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>*.dourl-pattern>
servlet-mapping>
<welcome-file-list>
<welcome-file>/pages/index.jspwelcome-file>
welcome-file-list>
web-app>
配置spring配置文件:处理器映射器,处理器适配器,视图解析器,组件扫描
<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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.dx"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
bean>
beans>
处理器编写
/**
* @Controller标识当前类为处理器类
*/
@Controller
public class Controler01 {
/**
* 处理请求的方法
* 返回值类型为ModelAndView或String
*/
@RequestMapping("/hello.do")
public ModelAndView helloMvc(){
ModelAndView modelAndView = new ModelAndView();
/* ViewName: 逻辑视图名
* 真实页面地址(物理视图名)= 公共前缀 + 逻辑视图名 + 公共后缀
* 物理视图名: /pages/success.jsp
* 逻辑视图名: success
*/
modelAndView.setViewName("success");
//设置数据:类似于在域对象中设置数据
modelAndView.addObject("msg", "hello springmvc!");
return modelAndView;
}
}
@Controller
public class Controler02 {
/**
* 可以设置多个url
* 使用大括号 {"url1","url2"...}
*/
@RequestMapping({"/url1.do","/url2.do","/url3.do"})
public ModelAndView url(){
System.out.println("一个方法可以有多个url请求");
return new ModelAndView("success");
}
/**
* 使用注解配置请求类型
* method = RequestMethod.请求方法
* method = {RequestMethod.请求方法1,RequestMethod.请求方法2}
*/
@RequestMapping(value = "/testGet.do",method = RequestMethod.GET)
public ModelAndView testGet(){
System.out.println("只接受get请求");
return new ModelAndView("success");
}
}
@RequestMapping("/user")
@Controller
public class Controller03_curd {
@RequestMapping("/add.do")
public ModelAndView add(){
System.out.println("添加用户");
return new ModelAndView("success");
}
@RequestMapping("/delete.do")
public ModelAndView delete(){
System.out.println("删除用户");
return new ModelAndView("success");
}
/**
* 直接返回逻辑视图名的字符串
*/
@RequestMapping("/update.do")
public String update(){
System.out.println("修改用户");
return "success";
}
@RequestMapping("/select.do")
public String select(){
System.out.println("查询用户");
return "success";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Hello World!
向hello.do发送请求
测试一个方法多个请求:url1.do url2.do url3.do
测试get请求
添加用户
删除用户
修改用户
查询用户
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
success
成功
获取到数据为:${msg}
@RequestMapping("/student")
@Controller
public class Controller04_request {
/**
* 处理请求之后页面的跳转方式
* 1.请求转发到页面(jsp)
* 当方法返回值为逻辑视图名时,请求转发到页面。默认
*/
@RequestMapping("/add.do")
public String add(HttpServletRequest request, HttpServletResponse response, HttpSession session){
System.out.println("添加学生");
String msg = request.getParameter("msg");
System.out.println(msg);
request.setAttribute("msg","studentList");
return "success";
}
/**
* 2.重定向到页面
* 关键字 redirect: + 物理视图名(真实地址)
*/
@RequestMapping("/delete.do")
public String delete(HttpServletRequest request){
System.out.println("删除学生");
request.setAttribute("msg","delete student");
return "redirect:/pages/success.jsp";
}
/**
* 3.请求转发到处理请求的方法
* 关键字 forward: + 物理视图名
*/
@RequestMapping("/update.do")
public String update(){
System.out.println("修改学生");
return "forward:/student/add.do";
}
/**
* 4.重定向到处理请求的方法
* 关键字 redirect: + 物理视图名
*/
@RequestMapping("/select.do")
public String select(){
System.out.println("查询学生");
return "redirect:/student/add.do";
}
}
测试页面
添加学生(请求转发到页面)
删除学生(重定向到页面)
修改学生(请求转发到方法)
查询学生(重定向到方法)
Person.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private Integer id;
private String name;
private Double score;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
}
Controller
@Controller
public class Controller05_Parameter {
/**
* SpringMVC中自带的方法形参有:
* 1.HttpServletRequest
* 2.HttpServletResponse
* 3.HttpSession
* 4.Model 由SpringMVC提供的一个API,作用:代替原生request域
*/
@RequestMapping("/param.do")
public String param(Model model, HttpServletRequest request) {
// request.setAttribute("msg","request Object");
model.addAttribute("msg","model Object");
return "success";
}
/**
* 通过方法形参 直接接收请求参数 自动实现类型转换
* 要求:请求参数于形参名一致
* 如果类型转换异常,则响应400状态码
* 使用场景:根据单个数据查询
*/
@RequestMapping("/simpleParam.do")
public String simpleParam(Integer id, String name, @DateTimeFormat(pattern = "yyyy-MM-dd") Date birth) {
System.out.println("id="+id);
System.out.println("name="+name);
System.out.println("brith="+birth);
return "success";
}
/**
* 手动绑定请求参数与形参
* @RequestParam
* required = true(默认):要求必须有请求参数
*/
@RequestMapping("/simpleParam2.do")
public String simpleParam2(@RequestParam(value = "empno",required = false,defaultValue = "1") Integer id) {
System.out.println("id="+id);
return "success";
}
/**
* 传入自定义对象
* 要求:请求参数名与成员变量名一致
* 这里的name也可以正常获取
* 使用场景:新增和修改时提交数据使用自定义对象
*/
@RequestMapping("/obj.do")
public String obj(Person person,String name) {
System.out.println("person="+person);
System.out.println("name="+name);
return "success";
}
/**
* 数组
* 接收的是同一个参数名的多个参数值
* 使用场景:批量删除
*/
@RequestMapping("/array.do")
public String arrayParam(Integer[] ids) {
System.out.println("数组:ids="+ Arrays.toString(ids));
return "success";
}
/**
* list集合
* 注意:SpringMVC中List集合无法直接接收数据,需要使用 @RequestParam
* 使用场景:批量删除、批量修改、批量新增
*/
@RequestMapping("/list.do")
public String listParam(@RequestParam List<Integer> ids) {
System.out.println("list集合:ids="+ ids);
return "success";
}
/**
* Map集合
* 类似于pojo对象,map集合是万能的对象
* person.setid(666);
* map.set("id",666);
* 注意:SpringMVC中Map集合无法直接接收数据,需要使用 @RequestParam
* 使用场景:批量删除、批量修改、批量新增
*/
@RequestMapping("/map.do")
public String mapParam(@RequestParam Map<String,Object> map) {
System.out.println("map集合:map="+ map);
return "success";
}
}
测试界面
SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理
作用:可以拦截请求,和处理响应
过滤器与拦截器的区别
实现方法
执行流程:

写拦截器类
public class interceptor_1 implements HandlerInterceptor {
/**
* 预处理方法:执行Controller前执行,做前置处理
* @param request 原生的request
* @param response 原生的response
* @param handler 处理器Controller
* @return blooean型,true表示放行(调用后续的拦截器或Controller方法),false表示拦截,请求不再向后执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器1的------>preHandle");
return true;
}
/**
* 后处理方法:所有拦截器都放行,此方法才执行(进入Controller时执行)
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器1的------>postHandle");
}
/**
* 请求处理完成之后方法:当前拦截器放行,就会执行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("拦截器1的------>afterCompletion");
}
}
public class interceptor_2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器2的------>preHandle");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器2的------>postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("拦截器2的------>afterCompletion");
}
}
Controller
@Controller
public class HelloInterceptor {
@RequestMapping("/hello.do")
public String hello(){
System.out.println("Controller的hello方法执行了.....");
return "success";
}
}
springmvc.xml配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/hello.do"/>
<bean class="com.dx.interceptor.interceptor_1"/>
mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.dx.interceptor.interceptor_2"/>
mvc:interceptor>
mvc:interceptors>
拦截器
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object username = session.getAttribute("username");
if (username == null) {
System.out.println("拦截器 拦截");
request.setAttribute("msg","请先登录");
request.getRequestDispatcher("/pages/login.jsp").forward(request,response);
return false;
}
System.out.println("拦截器 放行");
return true;
}
}
配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login.do"/>
<bean class="com.dx.interceptor.LoginInterceptor"/>
mvc:interceptor>
mvc:interceptors>
Controller
/**
* 实现用户登录功能
* 如果session不存在则拦截
* */
@Controller
public class LoginController {
@RequestMapping("/login.do")
public String login(String username,String password,HttpServletRequest request, HttpSession session){
//模拟用户登录
if (StringUtils.hasLength(username) && username.equals("admin") && StringUtils.hasLength(password) && password.equals("admin")) {
request.setAttribute("msg","登录成功");
session.setAttribute("username", username);
return "index";
} else {
request.setAttribute("msg","登录失败");
return "login";
}
}
@RequestMapping("/logout.do")
public String logout(HttpSession session) {
session.removeAttribute("username");
return "login";
}
}
@Controller
public class UserController {
@RequestMapping("/select.do")
public String select(){
System.out.println("用户查询");
return "success";
}
@RequestMapping("/add.do")
public String add(){
System.out.println("用户新增");
return "success";
}
@RequestMapping("/update.do")
public String update(){
System.out.println("用户修改");
return "success";
}
@RequestMapping("/delect.do")
public String delect(){
System.out.println("用户删除");
return "success";
}
}
pages
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
用户登录
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
success
成功
${msg}
pojo
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
//将字符串转换为日期对象
@DateTimeFormat(pattern = "yyyy-MM-dd")
//将日期对象转换为字符串
// @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") //jackson中的注解
@JSONField(format = "yyyy-MM-dd") //fastjson中的注解
private Date birthday;
}
springmvc.xml配置json
<mvc:annotation-driven/>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=utf-8value>
<value>text/html;charset=utf-8value>
list>
property>
bean>
mvc:message-converters>
mvc:annotation-driven>
Controller
@Controller
public class JsonController {
/**
* 处理异步请求的方法
* 方法需要用@ResponseBody
* 1.将Java对象转换为json字符串 @ResponseBody
* 2.将json字符串转换为Java对象 @RequestBody
*/
@ResponseBody
@RequestMapping("/getString.do")
public String getString(){
System.out.println("向前端发送字符串");
return "ok";
}
@ResponseBody
@RequestMapping("/getObj.do")
public Student getObj(){
Student student = new Student(10,"wp",new Date());
System.out.println("向前端发送student:"+student);
return student;
}
@ResponseBody
@RequestMapping("/getList.do")
public List<Student> getList() {
Student student1 = new Student(10, "wp", new Date());
Student student2 = new Student(11, "lq", new Date());
Student student3 = new Student(12, "cmy", new Date());
Student student4 = new Student(13, "gss", new Date());
System.out.println("向前端发送studentList");
return Arrays.asList(student1,student2,student3,student4);
}
/**
* 在同步请求中:响应时的商榷头(ContentType)text/html
* 在异步请求中: application/json
*
* 响应时,如果响应的是一个Java自定义对象,将被转换为json字符串对象
* 如果响应的是一个List集合(在集合中放置Java自定义对象),将被转换为json字符串数组
*/
@ResponseBody
@RequestMapping("/sendData.do")
public String sendData(Student student) {
System.out.println(student);
return "ok";
}
@ResponseBody
@RequestMapping("sendJson.do")
public String sendJson(@RequestBody Student student) {
System.out.println(student);
return "ok";
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Json获取数据
Json获取数据
Http协议设计的初衷
相关注解
//请求注解
@GetMapping === @RequestMapping(value = "{id}/{name}",method = RequestMethod.GET)
@PostMapping
@PutMapping
@DeleteMapping("{id}")
//参数注解
//把路径上的数据 映射到方法形式参数上
@PathVariable("id")
//接收和响应JSON相关的注解 接收JSON
@RequestBody
页面之间的跳转采用绝对路径
以${pageContext.request.contextPath}/开头的路径,表示在路径动态追加当前项目的根路径ContextPath;
user/find
或者在页面的head标签中添加base标签,达到追加ContextPath的目的
请求处理方法有两种:转发与重定向
原生Servlet
请求处理方法之间的跳转采用绝对路径
请求转发:无需在路径前添加ContextPath。转发为服务端内部跳转,斜杠/即表示当前项目ContextPath
req.getRequestDispatcher("/teacher/find.do").forward(req, resp);
重定向:必须在路径前添加ContextPath。重定向为客户端跳转,需要和页面跳转一样追加当前项目ContextPath。
resp.sendRedirect(req.getContextPath() + "/course/find.do");
SpringMVC
请求处理方法之间的跳转采用绝对路径。
请求转发与重定向时均无需在路径前添加ContextPath,SpringMVC会自动处理路径
@Controller
public class UserController {
@RequestMapping("/user/find.do")
public String find(){
return "forward:/role/find.do";
}
}
@Controller
public class MenuController {
@RequestMapping("/menu/find.do")
public String find(){
return "redirect:/pages/system/menu.jsp";
}
}
se标签,达到追加ContextPath的目的
请求处理方法有两种:转发与重定向
原生Servlet
请求处理方法之间的跳转采用绝对路径
请求转发:无需在路径前添加ContextPath。转发为服务端内部跳转,斜杠/即表示当前项目ContextPath
req.getRequestDispatcher("/teacher/find.do").forward(req, resp);
重定向:必须在路径前添加ContextPath。重定向为客户端跳转,需要和页面跳转一样追加当前项目ContextPath。
resp.sendRedirect(req.getContextPath() + "/course/find.do");
SpringMVC
请求处理方法之间的跳转采用绝对路径。
请求转发与重定向时均无需在路径前添加ContextPath,SpringMVC会自动处理路径
@Controller
public class UserController {
@RequestMapping("/user/find.do")
public String find(){
return "forward:/role/find.do";
}
}
@Controller
public class MenuController {
@RequestMapping("/menu/find.do")
public String find(){
return "redirect:/pages/system/menu.jsp";
}
}