一、SpringMVC概述

  1. Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的
    MVC 框架之一 。
  2. Spring3.0之后全面超越 Struts2,成为最优秀的 MVC 框架。
  3. Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任
    何接口。
  4. 支持REST风格的URL请求。
  5. 采用了松散耦合可插拔组件结构,比其他MVC框架更据扩展性。

1、搭建SpringMVC的环境

SpringMVC框架学习(一)
配置好测试需要使用的Tomcat
SpringMVC框架学习(一)
在工程下自动生成的web.xml文件中配置SpringMVC所需要的前端控制器

<!--SpringMVC前端控制器/核心控制器:DispatcherServlet-->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <!--给DispatcherServlet配置初始化参数,指定DispatcherServlet的核心配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>

        <!--
            load-on-startup:设置DispatcherServlet在服务器启动时候加载
                            Servlet创建时机:
                                1、请求到达以后创建
                                2、服务器启动即创建
        -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--指定请求的匹配-->
    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

接下来配置springmvc.xml

<!--1、组件扫描-->
    <context:component-scan base-package="springmvc"></context:component-scan>

    <!--2、视图解析器
        工作机制:prefix + 请求处理方法的返回值 + suffix = 物理视图路径
        /WEB-INF/views/success.jsp
        WEB-INF : 服务器内部路径。不能从浏览器端访问该路径下的资源,但是可以内部转发进行访问。
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

2、入门小程序

/**
 * 请求处理器/控制器
 */
@Controller
public class SpringMVCHandler {
    
    /**
     * 处理客户端请求:http://localhost:8080/SpringMVC/hello
     *
     * @RequestMapping : 完成请求与请求方法的映射
     */
    @RequestMapping(value = "/hello")
    public String handleHello(){
        System.out.println("Hello SpringMVC");
        return "success";   //通过视图解析器解析得到具体的视图,在转发去往该视图。
    }
}

return返回的字符串会自动寻找同名的.jsp文件进行映射,所以我们需要在views视图文件夹下创建映射界面success.jsp文件。

<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1 align="center">Success</h1>
</body>
</html>

简单描述原理:书写的index.jsp文件在发送请求的时候

<servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

中的 url-pattern会自动匹配发送过来的请求种类,通过servlet-name找到DispatcherServlet这时会读取springmvc.xml配置文件,进而创建springmvc的容器对象。同时springmvc.xml文件中的组件扫描会扫描@Controller和@RequestMapping注解,进而得到具体请求和请求方法的映射。

千万注意:在书写视图解析器的配置文件时prefix路径的views后面一定要加一个斜杠不然就会报错。

二、SpringMVC入门

1、@RequestMapping注解

<1>、value路径累加

当我们在类名前添加@RequestingMapping注解的时候,它所填的路径名是要加在方法上的@RequestingMapping前面的,然后在index.jsp里面做反射的视乎把路径写全才能做映射。

@Controller
@RequestMapping(value = "/springmvc")
public class SpringmvcHandler {
	/**
     *@RequestMapping  映射方式
     */
    @RequestMapping(value = "/testRequestingMapping")
    public String  testRequesting(){
        return "success";
    }
}
<a href="/springmvc/testRequestMapping">Test RequestMapping</a>
<2>、method映射请求

在value后面可以以逗号的形式再写上method

/**
     * @RequestMapping method 映射方式
     */
    @RequestMapping(value = "/testRequestingMethod", method = RequestMethod.GET)
    public String testRequestingMethod(){
        return "success";
    }

测试使用的是超链接,请求方式是GET,如果写POST就会包405请求方式不支持的错误,因此为了防止错误还可以这样写:

 @RequestMapping(value = "/testRequestingMethod", method = {RequestMethod.GET, RequestMethod.POST})

还可以使用按钮的方式:

 <form action="/testRequestingMappingMethod" method="post">
      <input type="submit" value="POST"/>
  </form>
<3>、params映射请求参数
	/**
     * @RequestMapping 映射请求参数、请求头信息
     *
     * params  请求参数
     * headers  请求头信息
     */
    @RequestMapping(value = "/testRequestingParamsAndHeaders", params = {"username", "age"})
    public String testRequestingParamsAndHeaders(){
        return "success";
    }
<a href="/testRequestingParamsAndHeaders?username=tom&age=20">Test RequestMapping Params And Headers</a>

如果需要在提交的时候不含有这个参数,或者参数能等于这个值,可以在参数之前加上一个感叹号。

<4>、headers
@RequestMapping(value = "/testRequestingParamsAndHeaders", params = {"username", "age"},headers = "language")
    public String testRequestingParamsAndHeaders(){
        return "success";
    }
<a href="/testRequestingParamsAndHeaders">Test RequestHeaders</a>

每一个网页中都包含许多Headers信息,爬虫的人很清楚Headers中含有很多的列表信息,所以这也可以成为我们提交信息的一种,当页面中包含Headers的信息才能成功跳转界面。

<5>、RequestMapping映射请求占位符PathVariable注解

带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:
URL 中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中。

@RequestMapping(value = "testPathVariable/{id}/{name}")
    public String testPathVariable(@PathVariable("id")String id, @PathVariable("name")String name){
        System.out.println(id + " " + name + "  forever");
        return "success";
    }
 <a href="testPathVariable/1234/John">Test PathVariable</a>

2、REST

<1>、概述
(1)、URL风格

order/2 HTTP GET :得到 id = 2 的 order
order/2 HTTP DELETE:删除 id = 2的 order
order HTTP PUT:更新order
order HTTP POST:新增 order

(2)、HiddenHttpMethodFilter

浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不
支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使
得支持 GET、POST、PUT 与 DELETE 请求。

(3)、HiddenHttpMethodFilter工作机制

SpringMVC框架学习(一)

<2>、环境搭建
<!--配置REST过滤器  HiddenHttpMethodFilter
       将满足转换条件的请求进行转换
       1、必须是post请求
       2、必须要通过_method能获取到一个请求参数值(要转换成的请求方式)
   -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
<3>、四种方法的示例
	 /**
     * REST GET
     */
    @RequestMapping(value = "/order/{id}",method = RequestMethod.GET)
    public String testRestGET(@PathVariable("id")Integer id){
        System.out.println("REST GET :" + id);
        return "success";
    }

    /**
     * REST DELETE
     */
    @RequestMapping(value = "/order/{id}", method = RequestMethod.DELETE)
    public String testRestDELETE(@PathVariable("id")Integer id){
        System.out.println("REST DELETE : " + id);
        return "success";
    }

    /**
     * REST POST
     */
    @RequestMapping(value = "/order", method = RequestMethod.POST)
    public String testRestPOST(){
        System.out.println("REST POST");
        return "success";
    }

    /**
     * REST PUT
     */
    @RequestMapping(value = "/order", method = RequestMethod.PUT)
    public String testRestPUT(){
        System.out.println("REST PUT");
        return "success";
    }

index.jsp文件中需要书写的:

<%--查询订单号是1001的订单--%>
  <a href="order/1001">REST GET</a>

  <%--删除订单号是1001的订单--%>
  <form action="order/1001" method="post">
    <%--隐藏域--%>
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="REST DELETE SUBMIT">
  </form>

  <%--添加一个订单--%>
  <form action="order" method="post">
    <input type="submit" value="REST POST">
  </form>

  <%--修改订单--%>
  <form action="order" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="REST PUT">
  </form>

3、处理请求数据

1)Spring MVC 通过分析处理方法的签名,HTTP请求信息绑定到处理方法的相应人参中。
2)Spring MVC 对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。
3)必要时可以对方法及方法入参标注相应的注解( @PathVariable 、@RequestParam、@RequestHeader 等)、
4)Spring MVC 框架会将 HTTP 请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。

<1>、@RequestParam

作用:映射请求参数映射到请求处理方法的形参中

<a href="/testRequestParam?username=mary&age=18">Test RequestParam</a>
 	/**
     *@RequestParam  映射请求参数到请求处理方法的形参
     *      1、如果请求参数名和形参名字一致,那么@RequestParam可以省略不写
     *      2、@RequestParam注解标注的形参必须要赋值,必须要能从请求对象中获取到对应的请求参数
     *          可以使用required来设置不是必须的
     *          可以使用defaultValue来指定一个默认值取代null
     *  客户端的请求:testRequestParam?username=mary&age=18
     */
    @RequestMapping(value = "/testRequestParam")
    public String testRequestParam(@RequestParam("username")String name, @RequestParam("age")Integer age){
        System.out.println(name + "  " + age);
        return "success";
    }
<2>、@RequestHeader
	/**
     *@RequestHeader   映射请求头信息到请求方法的形参中
     */
    @RequestMapping(value = "/testRequestHeaders")
    public String testRequestHeader(@RequestHeader("Accept-language")String acceptLanguage){
        System.out.println(acceptLanguage);
        return "success";
    }
<a href="/testRequestHeaders">Test RequestHeader</a>

申请的网页会携带一个Headers请求,对信息进行一次信息筛选一次就可以了,有用法和RequestMapping一样

<3>、@CookieValue
	/**
     * @CookieValue 映射Cookie信息到请求方法形参中
     */
    @RequestMapping(value = "/testCookieValue")
    public String testCookieValue(@CookieValue("JSESSIONID")String sessionID){
        System.out.println(sessionID);
        return "success";
    }

申请网页时会自动生成一个JSESSIONID,通过@CookieValue检验

<4>、使用POJO作为参数

1)使用 POJO 对象绑定请求参数值
2)Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.address.tel 等。

	/**
     * TESTPOJO
     */
    @RequestMapping(value = "testPOJO")
    public String testPOJO(User user){
        System.out.println(user);
        return "success";
    }
  @Controller
  public class Address {

    private String province;
    private String city;
    
    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}
@Controller
public class User {

    private String username;
    private String password;
    private Integer gender;
    private Address address;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", gender=" + gender +
                ", address=" + address +
                '}';
    }
}
<form action="testPOJO" method="post">
    用户名字:<input type="text" name="username">
    <br>
    密码:<input type="password" name="password">
    <br>
    性别: 男:<input type="radio" name="gender" value="1">
         女:<input type="radio" name="gender" value="0">
    <br>
    省份:<input type="text" name="address.province">
    <br>
    城市:<input type="text" name="address.city">
    <br>
    <input type="submit" value="注册">
  </form>

4、处理响应数据

<1>、ModelAndView
	/**
     * ModelAndView
     * SpringMVC会把ModelAndView中模型数据存放到request域对象中
     */
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){

        ModelAndView modelAndView = new ModelAndView();
        //添加模型数据
        modelAndView.addObject("username", "Tom");
        //设置视图信息
        modelAndView.setViewName("success");
        return modelAndView;
    }
 <a href="/testModelAndView">Test ModelAndView</a>

SpringMVC会将modelAndView中模型数据保存到request域对象中,提交申请用界面将参数展示出来。

<body>
    <h1>OK</h1>
    username:${requestScope.username}
</body>
<2>、Model
	 /**
     * Module
     */
    @RequestMapping("/testModel")
    public String testModule(Model model){
        model.addAttribute("loginMsg","用户名或者密码错误");
        return "success";
    }
<3>、Map
 	/**
     * Map
     * SpringMVC在调用玩请求处理方法之后,不管方法的返回值是什么类型都会处理成一个ModuleAndView对象
     */
    @RequestMapping("/testMap")
    public String testMap(Map<String, Object> map){
        map.put("password", 123456);
        return "success";
    }

相关文章: