SpringMVC知识点总结-DX的笔记

SpringMVC知识点总结

什么是MVC?

  • MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范
    1. Model(模型)
      • 数据模型,提供要展示的数据,可以认为是领域模型或 JavaBean组件(包含数据和行为)
      • 模型一般包括:Value Object(数据Dao) 和 服务层 (行为Service)
      • 也就是模型提供了模型数据查询和模型数据状态更新等功能,包括数据和业务
    2. View(视图)
      • 负责进行模型的展示,就是用户界面
    3. Controller(控制器)![请添加图片描述](https://img-
      • 接收请求,处理响应
      • 将请求委托给模型(Mode)进行处理,把处理完的模型数据返回给视图(View)
      • 控制器做了个调度员的工作
  • 是将 业务逻辑数据显示 分离的方法来组织代码
  • MVC主要作用是降低了视图与业务逻辑间的双向偶合
  • MVC不是一种设计模式,MVC是一种架构模式,不同的MVC存在差异
    在这里插入图片描述

什么是SpringMVC?

  • Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架
  • 充当controller,其本质就是一个Servlet
  • 轻量级,简单易学,简洁灵活,高效 , 基于请求响应的MVC框架
  • 与Spring兼容性好,无缝结合
  • 约定优于配置
  • 功能强大:RESTful、数据验证、格式化、本地化、主题等

Spring的原理

  • 前置控制器(DispatcherServlet),是SpringMVC的控制中心
    • Spring的web框架围绕DispatcherServlet设计
    • DispatcherServlet的作用是将请求分发到不同的处理器
    • Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功能
    • DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)
  • 处理器映射器(HandlerMapping)
    • 存储所有当前程序中的处理器,如果在处理器映射器中查找不到资源路径,直接返回404
  • 处理器适配器(HandlerAdapter)
    • 用于适配各种处理器,调用具体的处理器程序
  • Handler(具体处理器)
    • 开发者自己写,开发者实现相应接口或者使用注解声明的程序,用于处理具体的请求
  • 视图解析器(ViewResolver)
    • 根据处理器返回的数据,进行数据处理,将数据处理成相应的格式,JSP/JSON等等
  • 在这里插入图片描述- 在这里插入图片描述

MVC框架要做哪些事情

  1. 将url映射到 java类 或 java类 的方法
  2. 封装用户提交的数据
  3. 处理请求—>调用相关的业务处理—>封装响应数据
  4. 将响应的数据进行渲染 . jsp / html 等表示层数据

开发流程

  1. maven依赖

    <dependencies>
        <!--spring-web-mvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.4</version>
        </dependency>
        <!--servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <!--开发与测试环境可使用,不要打包,因为servlet中有此包-->
            <scope>provided</scope>
        </dependency>
        <!--jsp依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
            <scope>provided</scope>
        </dependency>
        <!--jstl-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
  2. 配置核心控制器:web.xml配置DispatchServlet

    <?xml version="1.0" encoding="UTF-8"?>
    <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>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--通过初始化参数,配置springmvc配置文件的名字和位置
            默认位置:/WEB-INF/[servlet-name]-servlet.xml  -->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--修改核心配置器,servlet启动时机,在服务器启动时创建,默认是第一次访问时创建-->
        <load-on-startup>1</load-on-startup>
      </servlet>
    
      <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--进入springmvc的请求路径
            第一种:*.后缀名 后缀名不能使用jsp和静态资源后缀,不支持restful
            第二种:/*      在springmvc中是错误的,会导致静态资源和jsp进入springmvc流程
            第三种:/       表示接收所有的请求,但不包括jsp,但是静态资源需要单独处理,支持restful     -->
        <url-pattern>*.do</url-pattern>
      </servlet-mapping>
    
      <!--设置欢迎页-->
      <welcome-file-list>
        <welcome-file>/pages/index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    
  3. 配置spring配置文件:处理器映射器,处理器适配器,视图解析器,组件扫描

    <?xml version="1.0" encoding="UTF-8"?>
    <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"/>
    
        <!--配置方式一:手动配置-->
        <!--    1.处理器映射器-->
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
        <!--    2.处理器适配器-->
        <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>
    
  4. 处理器编写

    /**
     * @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;
        }
    }
    

URL映射和请求方法

  • 一个请求可以设置多个url,但一个 url 只能对应一个请求
  • 返回值可以是ModelAndView,也可以是String(逻辑视图名)
  • 可以使用注解配置请求方法,get请求和post请求
@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" %>
<html>
<body>
<h2>Hello World!</h2>
<a href="/hello.do">向hello.do发送请求</a><br>
测试一个方法多个请求:<a href="/url1.do">url1.do</a> &nbsp;<a href="/url2.do">url2.do</a> &nbsp;<a href="/url3.do">url3.do</a> <br>
<a href="/testGet.do">测试get请求</a><br>
<form action="/testGet.do" method="post">
    <button>测试post请求</button>
</form>
<hr/>
<a href="/user/add.do">添加用户</a><br>
<a href="/user/delete.do">删除用户</a><br>
<a href="/user/update.do">修改用户</a><br>
<a href="/user/select.do">查询用户</a><br>
<hr/>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
<span style="text-align: center">
    <h1>成功</h1>
    <p>获取到数据为:${msg}</p>
</span>
</body>
</html>

转发和重定向

@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";
    }
}

测试页面

<hr/>
<a href="/student/add.do">添加学生(请求转发到页面)</a><br>
<a href="/student/delete.do">删除学生(重定向到页面)</a><br>
<a href="/student/update.do">修改学生(请求转发到方法)</a><br>
<a href="/student/select.do">查询学生(重定向到方法)</a><br>
<hr/>

传入请求参数

  • 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";
        }
    }
    
  • 测试界面

    <div style="text-align: center">
        <h2>域对象的使用</h2>
        <hr/>
        <a href="/param.do">使用Model接收数据</a><br>
        <hr/>
        <form action="/simpleParam.do" method="post">
            多种类型的请求参数会自动转换:
            <label>编号:</label>
            <input type="text" name="id">
            <label>姓名:</label>
            <input type="text" name="name">
            <label>生日:</label>
            <input type="date" name="birth">
            <button type="submit">提交</button>
        </form>
        <a href="/simpleParam2.do?empno=2">手动绑定参数</a><br>
        <form action="/obj.do" method="post">
            传入自定义对象:
            <label>编号:</label>
            <input type="text" name="id">
            <label>姓名:</label>
            <input type="text" name="name">
            <label>成绩:</label>
            <input type="text" name="score">
            <label>生日:</label>
            <input type="date" name="birthday">
            <button type="submit">提交</button>
        </form>
        <a href="/array.do?ids=2&ids=1&ids=5">传入数组</a><br>
        <a href="/list.do?ids=2&ids=1&ids=5">传入list集合</a><br>
        <form action="/map.do" method="post">
            传入map集合:
            <label>编号:</label>
            <input type="text" name="id">
            <label>姓名:</label>
            <input type="text" name="username">
            <label>金额:</label>
            <input type="text" name="money">
            <label>生日:</label>
            <input type="date" name="birthday">
            <button type="submit">提交</button>
        </form>
    </div>
    

拦截器

  • SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理

  • 作用:可以拦截请求,和处理响应

  • 过滤器与拦截器的区别

    • 拦截器是AOP思想的具体应用
    • 过滤器
    • servlet规范中的一部分,任何java web工程都可以使用
    • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
    • 拦截器
      • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
      • 拦截器只会拦截访问的控制器方法,如果访问的是jsp/html/css/image/js是不会进行拦截的
  • 实现方法

    1. 实现接口HandlerInterceptor
    2. 重写方法
  • 执行流程:

    1. preHandle --> postHandle --> afterCompletion
    2. 第一个拦截器的pre方法先执行,它post方法和after方法就会后执行

在这里插入图片描述

  • 写拦截器类

    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>
            <!--拦截路径  /**:所有请求   /*:只拦截一级层级的请求路径,如/a.do(/a/b.do 是二级路径)-->
            <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" %>
    <html>
    <head>
        <title>用户登录</title>
    </head>
    <body>
        <div style="text-align: center">
            <form action="/login.do">
                <p style="font-size: 18px;color: red;">${msg}</p>
                <p>
                    <label>用户名:</label>
                    <input type="text" name="username">
                </p>
                <p>
                    <label>密码:&emsp; </label>
                    <input type="password" name="password">
                </p>
                <p>
                    <button type="submit">登录</button>
                </p>
            </form>
        </div>
    </body>
    </html>
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <body>
        <div style="text-align: center">
            <h2>首页</h2>
            <p><a href="/hello.do">向hello.do发送请求</a></p>
            <p><a href="/logout.do">退出登录</a></p>
            <br>
            <br>
            <p><h4>用户管理</h4></p>
            <p><a href="/select.do">用户查询</a></p>
            <p><a href="/update.do">用户修改</a></p>
            <p><a href="/add.do">用户新增</a></p>
            <p><a href="/delect.do">用户删除</a></p>
    
            <hr>
        </div>
    </body>
    </html>
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>success</title>
    </head>
    <body>
    <span style="text-align: center">
        <h1>成功</h1>
        <p>${msg}</p>
        <p><a href="/pages/index.jsp">首页</a></p>
        <p><a href="/logout.do">退出登录</a></p>
    </span>
    </body>
    </html>
    

异步请求和响应

  • 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

    <!--这里已经自动配置了json-->
    <mvc:annotation-driven/>
    
    <!--手动配置fastjson -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <!--配置支持的媒体类型,设置默认的响应内容类型-->
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=utf-8</value>
                        <value>text/html;charset=utf-8</value>
                    </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" %>
    <html>
    <head>
        <title>Json获取数据</title>
    </head>
    <body>
    <h2>Json获取数据</h2>
    <div style="text-align: center">
        <div style="color: red" id="node"></div>
        <br>
        <br>
        <p>
            <button type="button" οnclick="responseString()">获取字符串</button>
            <button type="button" οnclick="responseObject()">获取对象</button>
            <button type="button" οnclick="responseList()">获取List</button>
            <button type="button" οnclick="sendData()">发送Data数据</button>
            <button type="button" οnclick="sendJson()">发送Json数据</button>
        </p>
    </div>
    
    <script type="text/javascript" src="/js/jquery.js"></script>
    <script type="text/javascript">
    //************************字面量对象与json字符串*******************************
        //字面量对象:一种javascript对象
        var obj = {
            id: 10,
            name: '张三'
        }
        //json字符串:拥有特殊格式的字符串
        var json = '{"id":20,"name":"李四"}';
        //字面量对象与json字符串的转换
        alert(obj);
        alert(json);
        alert(JSON.stringify(obj));
        alert(JSON.parse(json));
    //**************************************************************************
        function responseString() {
            $.ajax('/getString.do', {
                type: 'get',
                success: function (res) {
                    console.log(res);
                    $('#node').html(res);
                }
            })
        }
    
        function responseObject() {
            $.ajax('/getObj.do', {
                type: 'get',
                success: function (res) {
                    console.log(res);
                    $('#node').html("id=" + res.id + ",name=" + res.name + ",birthday=" + res.birthday);
                }
            })
        }
    
        function responseList() {
            $.ajax('/getList.do', {
                type: 'get',
                success: function (res) {
                    console.log(res);
                    //遍历方式一
                    $.each(res, function () {
                        $('#node').html("id=" + this.id + ",name=" + this.name + ",birthday=" + this.birthday);
                    })
                    //遍历方式二
                    res.forEach(function (item, index, arr) {
                        console.log(item, index, arr);
                    });
                }
            })
        }
    
        function sendData() {
            $.ajax('/sendData.do', {
                type: 'post',
                contentType: 'application/x-www-form-urlencoded',
                data: {
                    id: 50,
                    name: 'qingqing'
                },
                success: function (res) {
                    console.log(res);
                }
            })
        }
    
        function sendJson() {
            $.ajax('/sendJson.do', {
                type: 'post',
                contentType: 'application/json',
                data: JSON.stringify({
                    id: 50,
                    name: 'qingqing',
                    birthday: '1998-06-12'
                }),
                success: function (res) {
                    console.log(res);
                }
            })
        }
    </script>
    </body>
    </html>
    

restful风格

  • Http协议设计的初衷

    • HTTP协议在设计时,期望使用一个URL表示一种资源
      • 获取这个资源就使用GET
      • 修改这个资源PUT
      • 删除这个资源用DELETE
      • 创建这个资源使用POST
    • 但是在实际使用中,多个URL表示一个资源,违背了HTTP协议的设计初衷,并且命名也是个问题
  • 相关注解

    //请求注解
    @GetMapping   === @RequestMapping(value = "{id}/{name}",method = RequestMethod.GET)
    @PostMapping
    @PutMapping
    @DeleteMapping("{id}")
    //参数注解
    //把路径上的数据 映射到方法形式参数上
    @PathVariable("id")
    //接收和响应JSON相关的注解 接收JSON
    @RequestBody
    

路径跳转

页面跳转

  • 页面之间的跳转采用绝对路径

  • ${pageContext.request.contextPath}/开头的路径,表示在路径动态追加当前项目的根路径ContextPath;

    <a href="${pageContext.request.contextPath}/user/find.do">user/find</a>
    
  • 或者在页面的head标签中添加base标签,达到追加ContextPath的目的

    <head>
        <base href="${pageContext.request.contextPath}/">
    </head>
    

请求处理方法

  • 请求处理方法有两种:转发与重定向

  • 原生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的目的

<head>
    <base href="${pageContext.request.contextPath}/">
</head>

请求处理方法

  • 请求处理方法有两种:转发与重定向

  • 原生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";
          }
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值