SpringMVC(一):基本应用

目录

1. SpringMVC 简介

1.1 MVC 模式

1.2 SpringMVC 概述

1.3 SpringMVC 快速入门

1.4 web 工程执行流程

1.5 小结

2. SpringMVC 组件概述

2.1 SpringMVC 的执行流程

2.2 SpringMVC 组件解析

 2.3 SpringMVC 注解解析

2.4 小结

3. SpringMVC 的请求

3.1 请求参数类型介绍

3.2 获取基本类型参数

 3.3 获取对象类型参数

 3.4 中文乱码过滤器

 3.5 获取数组类型参数

 3.6 获取集合(复杂)类型参数

 3.7 自定义类型转换器

 3.8 相关注解

 3.9 获取 Servlet 相关 API

4. SpringMVC 的响应

4.1 SpringMVC 响应方式介绍

4.2 返回字符串逻辑视图

4.3 void 原始 ServletAPI

4.4 转发和重定向

4.5 ModelAndView

4.6  直接返回字符串数据

4.7 @SessionAttributes

4.8  小结

5. 静态资源访问的开启

6. @DateTimeFormat(日期格式转换) 


1. SpringMVC 简介

1.1 MVC 模式

MVC 是软件工程中的一种软件架构模式,它是一种分离业务逻辑与显示界面的开发思想。

  • M(model)模型:处理业务逻辑,封装实体
  • V(view) 视图:展示内容
  • C(controller)控制器:负责调度分发(1.接收请求、2.调用模型、3.转发到视图)

1.2 SpringMVC 概述

SpringMVC 是一种基于 Java 的实现 MVC 设计模式的轻量级 Web 框架,属于Spring Framework 的后续产品,已经融合在 Spring Web Flow 中。

SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring 3.0 的发布,全面超越 Struts 2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

SpringMVC 的框架就是封装了原来 Servlet 中的共有行为;例如:参数封装,视图转发等。

1.3 SpringMVC 快速入门

需求:客户端发起请求,服务器接收请求,执行逻辑并进行视图跳转。

步骤分析:

  1. 创建web项目,导入 SpringMVC 相关坐标
  2. 配置 SpringMVC 前端控制器 DispatcherServlet
  3. 编写 Controller 类和视图页面
  4. 使用注解配置 Controller 类中业务方法的映射地址
  5. 配置 SpringMVC 核心文件 spring-mvc.xml

1. 创建 web 项目,导入 SpringMVC 相关坐标

war



    UTF-8
    UTF-8
    1.11
    1.11
    1.11



    
    
        org.springframework
        spring-webmvc
        5.1.5.RELEASE
    
    
    
        javax.servlet
        javax.servlet-api
        3.1.0
        provided
    
    
    
        javax.servlet.jsp
        jsp-api
        2.2
        provided
    

    ...


2. 在Web.xml中配置 SpringMVC 前端控制器 DispatcherServlet




    
    
        DispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
        
            contextConfigLocation
            classpath:spring-mvc.xml
        
        
        2
    

    
        DispatcherServlet
        
        /
    


3. 编写 Controller 类和视图页面
UserController.java

public class UserController {
    public String quick() {
        // 业务处理
        System.out.println("SpringMVC Quick Start...");
        // 页面跳转 请求转发
        return "/WEB-INF/pages/success.jsp";
    }
}

/WEB-INF/pages/success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    SUCCESS



    

success... ${username}

<% System.out.println("Success...");%>

4. 使用注解配置 Controller 类中业务方法的映射地址

@Controller
public class UserController {
    @RequestMapping("/quick")
    public String quick() {
        System.out.println("SpringMVC Quick Start...");
        return "/WEB-INF/pages/success.jsp";
    }
}

5. 配置 SpringMVC 核心文件 spring-mvc.xml



    
    


1.4 web 工程执行流程

客户端(浏览器)发送请求到 Tomcat 服务器,Tomcat 服务器发送响应到客户端。

服务器的 Tomcat 引擎:

  1. 接受客户端请求,解析请求资源地址
  2. 创建代表请求的 request 对象
  3. 创建代表响应 response 对象
  4. 调用目标资源
  5. 获得 response 中的内容,组装成 HTTP 响应返回客户端

服务器的 Web 应用:

  1. 获得请求资源地址
  2. 解析映射地址,找到对应的处理器(Controller)
  3. 处理器执行对应的方法(进行业务逻辑以及视图跳转操作),获取被访问的真实资源

1.5 小结

  • SpringMVC 是对 MVC 设计模式的一种实现,属于轻量级的 WEB 框架。
  • SpringMVC 的开发步骤:
    1. 创建 web 项目,导入 SpringMVC 相关坐标
    2. 配置 SpringMVC 前端控制器 DispatcherServlet
    3. 编写 Controller 类和视图页面
    4. 使用注解配置 Controller 类中业务方法的映射地址
    5. 配置 SpringMVC 核心文件 spring-mvc.xml

2. SpringMVC 组件概述

2.1 SpringMVC 的执行流程

SpringMVC(一):基本应用_第1张图片

  1. 用户发送请求时,这个请求会先到前端控制器 DispatcherServlet。
  2. DispatcherServlet 收到请求后会调用 HandlerMapping 处理器映射器。由此得知,这个请求该由哪个Controller来处理(注意:这里只是得知,并未真正调用Controller)。
  3. 处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
  4. DispatcherServlet 调用 HandlerAdapter 处理器适配器,告诉处理器适配器应该要去执行哪个Controller。
  5. HandlerAdapter 经过适配后,调用具体的处理器(Controller,也叫后端控制器)。
  6. Controller 执行完成返回 ModelAndView。
  7. HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。
  8. DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器进行解析。
  9. ViewReslover 解析后向DispatcherServlet 返回具体 View对象。
  10. DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
  11. DispatcherServlet 将渲染后的视图响应响应用户。

2.2 SpringMVC 组件解析

  1. 前端控制器:DispatcherServlet
    用户请求到达前端控制器,它就相当于 MVC 模式中的 C;DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求;DispatcherServlet 的存在降低了组件之间的耦合性。

  2. 处理器映射器:HandlerMapping
    HandlerMapping 负责根据用户请求的url找到 Handler 即处理器(也就是自己编写的Controller);SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式、实现接口方式、注解方式等。

  3. 处理器适配器:HandlerAdapter
    按照特定规则(HandlerAdapter要求的规则)去执行Handler,通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

  4. 处理器:Handler【开发者编写
    它是开发中要编写的具体业务控制器;由 DispatcherServlet 把用户请求转发到 Handler;由 Handler 对具体的用户请求进行处理。

  5. 视图解析器:ViewResolver
    View Resolver 负责将处理结果生成 View 视图;View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

  6. 视图:View 【开发者编写
    SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。

  7. SpringMVC 中的三大组件是什么?
    处理器映射器 HandlerMapping;
    处理器适配器 HandlerAdapter;
    视图解析器 ViewResolver;
    如果是四大组件,则加上前端控制器 DispatcherServlet。

spring-mvc.xml



    
    

    
    

    
    
        
        
        
    


UserController.java

    @RequestMapping("/quick")
    public String quick() {
        System.out.println("SpringMVC Quick Start...");
        // 页面跳转 请求转发 返回逻辑视图名
        return "success";
    }

 2.3 SpringMVC 注解解析

@Controller

SpringMVC 基于 Spring 容器,所以在进行 SpringMVC 操作时,需要将 Controller 存储到 Spring 容器中,如果使用 @Controller 注解标注的话,就需要使用:



注意配置 SpringMVC 的 base package 只扫描 web 层的包,其它包交给 Spring 容器扫描;这样 SpringMVC 的容器就相当于是 Spring 容器的一个子容器。 

@RequestMapping

* 作用:用于建立请求 URL 和处理请求方法之间的对应关系。

* 位置:
1. 类上:请求 URL 的第一级访问目录。此处不写的话,就相当于应用的根目录;写的话需要以 / 开头。
    它出现的目的是为了使 URL 可以按照模块化管理:
        用户模块
            /user/add
            /user/update
            /user/delete
            ...
        账户模块
            /account/add
            /account/update
            /account/delete
2. 方法上:请求 URL 的第二级访问目录,和一级目录组成一个完整的 URL 路径。

* 属性:
1. value:用于指定请求的 URL;它和 path 属性的作用是一样的
2. method:用来限定请求的方式
3. params:用来限定请求参数的条件
    例如:
        params={"accountName"} 表示请求参数中必须有 accountName
        params={"money!100"} 表示请求参数中 money 不能是100


@Controller
@RequestMapping("/user") //一级访问目录
public class UserController {

    /**
     * http://localhost:8080/springmvc_quickstart/user/quick?accountName=zm
     * 
     * path :作用等同于 value,同样是设置方法的映射地址
     * method:用来限定请求的方式 RequestMethod.POST: 只能以 post 的请求方式访问该访问,其他请求方式会报错
     * params:用来限定请求参数的条件 params={"accountName"} 表示请求参数中必须有 accountName
     */
    @RequestMapping(
            path = "/quick", // 二级访问目录
            method = {RequestMethod.POST, RequestMethod.GET},
            params = {"accountName"})
    public String quick() {
        // 业务处理
        System.out.println("SpringMVC Quick Start...");
        // 页面跳转 请求转发 返回逻辑视图名
        return "success";
    }

}

2.4 小结

-- SpringMVC的三大组件
处理器映射器:HandlerMapping
处理器适配器:HandlerAdapter
视图解析器:View Resolver

-- 开发者编写
处理器:Handler
视图:View


3. SpringMVC 的请求

3.1 请求参数类型介绍

客户端请求参数的格式是: name=value&name=value ...

服务器要获取请求的参数的时候要进行类型转换,有时还需要进行数据的封装

SpringMVC 可以接收如下类型的参数:

  • 基本类型参数

  • 对象类型参数

  • 数组类型参数

  • 集合类型参数

3.2 获取基本类型参数

Controller 中的业务方法的参数名称要与请求参数的 name 一致,参数值会自动映射匹配。并且能自动做类型转换;自动的类型转换是指从 String 向其他类型的转换。

requestParam.jsp

<%-- ${pageContext.request.contextPath} 动态的来获取当前的项目路径 - springmvc_quickstart;
      a 标签的请求方式:get 请求 
--%>

    基本类型参数

在 UserController 中添加方法

@RequestMapping("/simpleParam")
public String simpleParam(Integer id, String username) {
    System.out.println(id);
    System.out.println(username);
    return "success";
}

 3.3 获取对象类型参数

Controller 中的业务方法参数的 POJO 属性名与请求参数的 name 一致,参数值会自动映射匹配。

requestParam.jsp

<%-- form 表单;该表单提交的请求方式为 post 类型 --%>
编号:
用户名:

创建 User 类

public class User {
    private Integer id;
    private String username;
    // setter getter...
}

在 UserController 中添加方法

@RequestMapping("/pojoParam")
public String pojoParam(User user){
    System.out.println(user);
    return "success";
}

 3.4 中文乱码过滤器

当 post 请求时,数据会出现乱码,可以在 web.xml 设置一个过滤器来进行编码的过滤。


    CharacterEncodingFilter
    org.springframework.web.filter.CharacterEncodingFilter
    
        encoding
        UTF-8
    


    CharacterEncodingFilter
    /*

 3.5 获取数组类型参数

Controller 中的业务方法数组名称与请求参数的 name 一致,参数值会自动映射匹配。

requestParam.jsp

编号:
1
2
3
4

在 UserController 中添加方法

@RequestMapping("/arrayParam")
public String arrayParam(Integer[] ids){
    System.out.println(Arrays.toString(ids));
    return "success";
}

 3.6 获取集合(复杂)类型参数

获得集合参数时,要将集合参数包装到一个 POJO 中才可以。

requestParam.jsp

搜索关键字:
user对象:
list集合: 元素1: 元素2:
Map集合: 元素1: 元素2:

创建 QueryVo 类

public class QueryVo {

    private String keyword;
    private User user;
    private List userList;
    private Map userMap;
    // setter getter...
}

在 UserController 中添加方法

@RequestMapping("/queryParam")
public String queryParam(QueryVo queryVo){
    System.out.println(queryVo);
    return "success";
}

 3.7 自定义类型转换器

SpringMVC 默认已经提供了一些常用的类型转换器。例如:客户端提交的字符串转换成 INT 型进行参数设置,日期格式类型要求为:yyyy/MM/dd 不然的话会报错;对于特有的行为,SpringMVC 提供了自定义类型转换器方便开发者自定义处理。

requestParam.jsp

生日:

配置自定义日期转换 DateConverter

public class DateConverter implements Converter {

    /**
     * s 就是表单传递过来的请求参数,如 2012-12-12
     */
    @Override
    public Date convert(String s) {
        // 将日期字符串转换成日期对象,进行返回
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

spring-mvc.xml



    
        
            
        
    



在 UserController 中添加方法

@RequestMapping("/converterParam")
public String converterParam(Date birthday){
    System.out.println(birthday);
    return "success";
}

 3.8 相关注解

@RequestParam
当请求的参数 name 名称与 Controller 的业务方法参数名称不一致时,就需要通过 @RequestParam 注解显示的绑定

requestParam.jsp


    分页查询

在 UserController 中添加方法

/**
 * name:匹配页面传递参数的名称
 * defaultValue:设置参数的默认值
 * required:设置是否必须传递该参数,默认值为 true;如果设置了默认值,值自动改为 false
 */
@RequestMapping("findByPage")
public String findByPage(
    @RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNum,
    @RequestParam(defaultValue = "5") Integer pageSize) {
    System.out.println(pageNum);
    System.out.println(pageSize);
    return "success";
}

@RequestHeader
获取请求头的数据。

在 UserController 中添加方法

@RequestMapping("/requestHeader")
public String requestHead(@RequestHeader("cookie") String cookie){
    System.out.println(cookie);
    return "success";
}

@CookieValue
获取 cookie 中的数据。

在 UserController 中添加方法

@RequestMapping("/cookieValue")
public String cookieValue(@CookieValue("JSESSIONID") String jSessionId){
    System.out.println(jSessionId);
    return "success";
}

 3.9 获取 Servlet 相关 API

SpringMVC 支持使用原始 Servlet API 对象作为控制器方法的参数进行注入,常用的对象如下:

@RequestMapping("/servletAPI")
public String servletApi(HttpServletRequest request, HttpServletResponse response, HttpSession session){
    System.out.println(request);
    System.out.println(response);
    System.out.println(session);
    return "success";
}


4. SpringMVC 的响应

4.1 SpringMVC 响应方式介绍

页面跳转:

  1. 返回字符串逻辑视图
  2. void 原始 ServletAPI
  3. ModelAndView

返回数据:

  1. 直接返回字符串数据
  2. 将对象或集合转为 json 返回

4.2 返回字符串逻辑视图

直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转到指定页面

@RequestMapping("/returnString")
public String returnString() {
    return "success";
}

4.3 void 原始 ServletAPI

可以通过 request、response 对象实现响应

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

    
        Index
    
    
        Hello ${username}
    

在 UserController 中添加方法

@RequestMapping("/returnVoid")
public void returnVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   

    // 借助 request 对象完成请求转发,一次请求
    request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
    request.getRequestDispatcher("/index.jsp").forward(request, response);

    // 借助 response 对象完成重定向,两次请求。WEB-INF - 安全目录:不允许外部请求直接访问该目录资源,只可以进行服务器内部转发
    response.sendRedirect(request.getContextPath() + "/index.jsp");
}

4.4 转发和重定向

企业开发一般使用返回字符串逻辑视图实现页面的跳转,这种方式其实就是请求转发;也可以写成:forward 转发。如果用了 forward,则路径必须写成实际视图 URL,不能写逻辑视图。它相当于:

request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response)

使用请求转发,既可以转发到 JSP,也可以转发到其他的控制器方法。

@RequestMapping("/forward")
public String forward(Model model){
    // 在模型中设置一些值
    model.addAttribute("username","zhangsan");
    // 使用请求转发,既可以转发到 jsp,也可以转发到其他的控制器方法
   
    // 跳转到其他的Controller: 也就是跳转到product模块中的findAll方法
    // return "forward:/product/findAll";

    return "forward:/WEB-INF/pages/success.jsp";
}

Redirect 重定向:可以不写虚拟目录,SpringMVC 框架会自动拼接,并且将 Model 中的数据拼接到 URL 地址上;重定向的目标 JSP 页面不能写在 WEB-INF 目录中,否则无法找到。

@RequestMapping("/redirect")
public String redirect(Model model) {
    // 底层使用的还是 request.setAttribute("username","lucky"),
    // 域范围是一次请求,所以重定向后,请求发生了变化,请求域的值无法获取
    model.addAttribute("username", "lucky");
    return "redirect:/index.jsp";
}

注意: 当用了关键字 forward 或 redirect 后,不会再走视图解析器了,所以路径不能写逻辑视图。

4.5 ModelAndView

方式一
在 Controller 中方法创建并返回 ModelAndView 对象,并且设置视图名称

/**
 * model:模型:作用封装存放数据
 * View :视图:用来展示数据
 */
@RequestMapping("/returnModelAndView")
public ModelAndView returnModelAndView(){
    ModelAndView modelAndView = new ModelAndView();
    // 设置模型数据
    modelAndView.addObject("username","modelAndView 方式一");
    // 设置视图名称。视图解析器解析 modelAndView 拼接前缀和后后缀
    modelAndView.setViewName("success");
    return modelAndView;
}

方式二
在 Controller 中方法形参上直接声明 ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置视图,同样可以跳转页面

@RequestMapping("/returnModelAndView2")
public ModelAndView returnModelAndView2(ModelAndView modelAndView){
    // 设置模型数据
    modelAndView.addObject("username","modelAndView 方式二");
    // 设置视图名称。视图解析器解析 modelAndView 拼接前缀和后后缀
    modelAndView.setViewName("success");
    return modelAndView;
}

4.6  直接返回字符串数据

@RequestMapping("/returnVoid")
public void returnVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /* 直接返回数据 */
    response.setContentType("text/html;charset=utf-8");
    response.getWriter().write("张三 ");
    
}

4.7 @SessionAttributes

如果在多个请求之间共用数据,则可以在控制器类上标注一个 @SessionAttributes,配置需要在 session 中存放的数据范围,SpringMVC 将存放在 model 中对应的数据暂存到 HttpSession 中。

注意:@SessionAttributes 只能定义在类上

@Controller
@RequestMapping("/user") //一级访问目录
@SessionAttributes("username") // 向 request 域中(model)中存入 key 为 username 时,会同步到 session 域中
public class UserController {

    ...

    @RequestMapping("/forward")
    public String forward(Model model) {
        // 在模型中设置一些值
        model.addAttribute("username", "zhangsan");
        // 使用请求转发,既可以转发到 jsp,也可以转发到其他的控制器方法
        // return "forward:/product/findAll";
        return "forward:/WEB-INF/pages/success.jsp";
    }

    ...

    @RequestMapping("/returnString")
    public String returnString(){
        return "success";
    }
}

4.8  小结

  • 页面跳转采用返回字符串逻辑视图
    -- forward 转发: 可以通过Model向request域中设置数据。
    -- redirect 重定向:直接写资源路径即可,虚拟目录springMVC框架自动完成拼接。

  • 数据存储到 request 域中
    Model model
    model.addAttribute("username", "张三");


5. 静态资源访问的开启

requestParam.jsp

...
<%-- 引入 jquery.js --%>

...

当有静态资源需要加载时,比如 jQuery 文件,通过谷歌开发者工具抓包发现,没有加载到 jQuery 文件,原因是 SpringMVC 的前端控制器 DispatcherServlet 的 url-pattern 配置的是 /(默认配置),代表对所有的静态资源都进行处理操作,这样就不会执行 Tomcat 内置的 DefaultServlet 处理,可以通过以下两种方式在 spring-mvc.xml 指定放行静态资源。

方式一:放行指定的静态资源





方式二:放行全部的静态资源



6. @DateTimeFormat(日期格式转换) 

一般SpringMVC日期格式,默认格式为:"yyyy/MM/dd" 这种格式。但我们一般前台使用的日期格式为:"yyyy-MM-dd",那么此时SpringMVC不能自动帮我们转换成想要的格式。所以,我们需要调整日期格式,可以在实体类中类型为Date的属性上使用注解@DateTimeFormat来指定日期格式。如下:

package com.zm.domain;

import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

public class UserVo {
   
    
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date startCreateTime;
    
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date endCreateTime;

你可能感兴趣的:(框架,mvc,spring,java,springmvc)