SpringMVC 之一(概述、@RequestMapping 及处理方法签名)

1、SpringMVC概述

(1)Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的 MVC 框架之一

(2)Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架

(3)Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。

(4)支持 REST 风格的 URL 请求

(5)采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性

2、SpringMVC 的 HelloWorld

步骤:
(1)加入 jar 包
在这里插入图片描述
(2)在 web.xml 中配置 DispatcherServlet

配置 DispatcherServlet :DispatcherServlet 默认加载 /WEB-INF/<servletName-servlet>.xml 的 Spring 配置文件, 启动 WEB 层的 Spring 容器。可以通过 contextConfigLocation 初始化参数自定义配置文件的位置和名称。

<?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">
    <!-- 配置 DispatcherServlet -->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置 DispatcherServlet 的一个初始化参数:配置 SpringMVC 配置文件的位置和名称 -->
        <!--
            实际上也可以不通过 contextConfigLocation 来配置 SpringMVC 的配置文件,而使用默认的。
            默认的配置文件为:/WEB-INF/<servlet-name>-servlet.xml
        -->
        <!--
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

(3)加入 Spring MVC 的配置文件
/WEB-INF/springDispatcherServlet-servlet.xml

<?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 http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="com.mycode.springmvc"></context:component-scan>

    <!-- 配置视图解析器:如何把 handler 方法返回值解析为实际的物理视图 
		将视图逻辑名解析为: /WEB-INF/pages/<viewName>.jsp
	-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

(4)编写处理请求的处理器,并标识为处理器

@Controller
public class HelloWorld {
    
    

    /**
     * 1.使用 @RequestMapping 注解来映射请求的 URL
     * 2.返回值会通过视图解析器解析为实际的物理视图,对于InternalResourceViewResolver 视图解析器,会做如下的解析:
     *   通过 prefix + returnVal + 后缀  这样的方式得到实际的物理视图,然后会做转发操作
     *
     *   /WEB-INF/views/success.jsp
     *
     * @return
     */
    @RequestMapping("/helloworld")
    public String hello(){
    
    
        System.out.println("hello world");
        return "success";
    }
}

(5)编写视图

/WEB-INF/views/success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h4>Success Page</h4>
</body>
</html>

3、使用 @RequestMapping 映射请求

3.1 使用 URL 映射请求

(1)Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求

(2)在控制器的类定义及方法定义处都可标注
@RequestMapping

  • 类定义处:提供初步的请求映射信息。相对于 WEB 应用的根目录
  • 方法处:提供进一步的细分映射信息。相对于类定义处的 URL。若类定义处未标注 @RequestMapping,则方法处标记的 URL 相对于 WEB 应用的根目录

(3)DispatcherServlet 截获请求后,就通过控制器上 @RequestMapping 提供的映射信息确定请求所对应的处理方法。
在这里插入图片描述

3.2 使用请求参数、请求方法或请求头映射请求

(1)@RequestMapping 除了可以使用请求 URL 映射请求外,还可以使用请求方法、请求参数及请求头映射请求

(2)@RequestMapping 的 value、method、params 及 heads 分别表示请求 URL、请求方法、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。

(3)params 和 headers支持简单的表达式:

  • param1: 表示请求必须包含名为 param1 的请求参数
  • !param1: 表示请求不能包含名为 param1 的请求参数
  • param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
  • {“param1=value1”, “param2”}: 请求必须包含名为 param1 和 param2 的两个请求参数,且 param1 参数的值必须为 value1

示例1:使用 method 属性指定请求方式

	/**
     * 常用:使用 method 属性来指定请求方式
     * @return
     */
    @RequestMapping(value = "/testMethod",method = RequestMethod.POST)
    public String testMethod() {
    
    
        System.out.println("testMethod");
        return SUCCESS;
    }
	<form action="springmvc/testMethod" method="post">
        <input type="submit" value="submit">
    </form>

示例2:使用 params 和 headers 来更加精确的映射请求

/**
     * 了解:可以使用 params 和 headers 来更加精确的映射请求。params 和 headers 支持简单的表达式。
     * @return
     */
    @RequestMapping(value = "testParamsAndHeaders",
            params = {
    
    "username","age!=10"},headers = {
    
    "Accept-Language=en-US,zh-TW;q=0.9,zh;q=0.8,en-US;q=0.7,en;q=0.6"})
    public String testParamsAndHeaders(){
    
    
        System.out.println("testParamsAndHeaders");
        return SUCCESS;
    }

3.3 @RequestMapping 还支持 Ant 风格的 URL:

  • /user/*/createUser:匹配 /user/aaa/createUser、/user/bbb/createUser 等 URL
  • /user/**/createUser: 匹配 /user/createUser、/user/aaa/bbb/createUser 等 URL
  • /user/createUser??: 匹配 /user/createUseraa、/user/createUserbb 等 URL

Ant 风格资源地址支持 3 种匹配符

  • ?:匹配文件名中的一个字符
  • *:匹配文件名中的任意字符
  • ** :匹配多层路径
	@RequestMapping("/testAntPath/*/abc")
    public String testAntPath(){
    
    
        System.out.println("testAntPath");
        return SUCCESS;
    }
<a href="springmvc/testAntPath/mnxyz/abc">Test AntPath</a>

3.4 @PathVariable 映射 URL 绑定的占位符

(1)带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义

(2)通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中。

/**
     * @PathVariavle 可以来映射 URL 中的占位符到目标方法的参数中
     * @param id
     * @return
     */
    @RequestMapping("testPathVariable/{id}")
    public String testPathVariable(@PathVariable("id") Integer id) {
    
    
        System.out.println("testPathVariable:" + id);
        return SUCCESS;
    }
<a href="springmvc/testPathVariable/1">Test PathVariable</a>

(3)REST

  • REST:即 Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。

  • 资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它 可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识别符。

  • 表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。

  • 状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。

  • 示例:
    /order/1 HTTP GET :得到 id = 1 的 order
    /order/1 HTTP DELETE:删除 id = 1 的 order
    /order/1 HTTP PUT:更新id = 1的 order
    /order HTTP POST:新增 order
    HiddenHttpMethodFilter:浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与 DELETE 请求。

web.xml

<?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">

    <!-- 
    配置 org.springframework.web.filter.HiddenHttpMethodFilter:可以把 POST 请求转为 DELETE 或 PUT 请求
    -->
    <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>

    <!-- 配置 DispatcherServlet -->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置 DispatcherServlet 的一个初始化参数:配置 SpringMVC 配置文件的位置和名称 -->
        <!--
            实际上也可以不通过 contextConfigLocation 来配置 SpringMVC 的配置文件,而使用默认的。
            默认的配置文件为:/WEB-INF/<servlet-name>-servlet.xml
        -->
        <!--
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        -->
        <load-on-startup>1</load-on-startup>
    </servlet>

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

springDispatcherServlet-servlet.xml

<?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 http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="com.mycode.springmvc"></context:component-scan>

    <!-- 配置视图解析器:如何把 handler 方法返回值解析为实际的物理视图 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

SpringMVCTest.java

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
    
    
    private static final String SUCCESS = "success";
    /*
     Rest 风格的 URL
     以 CRUD 为例:
        新增: /order  POST
        修改: /order/1    PUT
        获取: /order/1    GET
        删除: /order/1    DELETE

     如何发送 PUT 请求和 DELETE 请求呢?
        1、需要配置 HiddenHttpMethodFilter
        2、需要发送 POST 请求
        3、需要在发送 POST 请求时携带一个 name="_method" 的隐藏域,值为 DELETE 或 PUT

     在 SpringMVC 的目标方法中如何得到 id 呢?
        使用 @PathVariable 注解
     */
    @RequestMapping(value = "/testRest/{id}",method = RequestMethod.PUT)
    public String testRestPut(@PathVariable Integer id){
    
    
        System.out.println("testRest PUT:" + id);
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)
    public String testRestDelete(@PathVariable Integer id){
    
    
        System.out.println("testRest Delete:" + id);
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest",method = RequestMethod.POST)
    public String testRest(){
    
    
        System.out.println("testRest POST");
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest/{id}",method = RequestMethod.GET)
    public String testRest(@PathVariable Integer id){
    
    
        System.out.println("testRest GET:" + id);
        return SUCCESS;
    }
}

注意:如果 web 项目是运行在 Tomcat 8 下,你会发现被过滤成 DELETE 和 PUT 请求,到达控制器后,返回时(forward)会报 HTTP 405 的错误提示

原因:当在index.jsp中提交后,HiddenHttpMethodFilter 会将 method 转换成对应的 DELETE 或 PUT,SpingMVC 会继续用对应的请求重定向到success.jsp 中,而 jsp 只支持 GET、POST、HEAD 请求方法。

4、请求处理方法签名

  • Spring MVC 通过分析处理方法的签名,将 HTTP 请求信息绑定到处理方法的相应入参中。

  • Spring MVC 对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。

  • 必要时可以对方法及方法入参标注相应的注解(@PathVariable、@RequestParam、@RequestHeader 等)、Spring MVC 框架会将 HTTP 请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。

(1)使用 @RequestParam 绑定请求参数值

在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法

  • value:参数名
  • required:是否必须。默认为 true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常。

SpringMVCTest.java

	/*
        @RequestParam 来映射请求参数。
        value 值即为请求参数的参数名
        required 该参数是否必须,默认为 true
        defaultValue 请求参数的默认值
     */
    @RequestMapping(value="/testRequestParam")
    public String testRequestParam(@RequestParam(value = "username") String un,
                                   @RequestParam(value = "age",required = false,defaultValue = "0") int age){
    
    
        System.out.println("RequestParam, username:" + un + ",age:" + age);
        return SUCCESS;
    }

index.jsp

<a href="springmvc/testRequestParam?username=zhaolei&age=11">Test RequestParam</a>

(2)使用 @RequestHeader 绑定请求头的属性值

请求头包含了若干个属性,服务器可据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中

SpringMVCTest.java

/*
        了解
        映射请求头信息
        用法同 @RequestParam
     */
    @RequestMapping("/testRequestHeader")
    public String testRequestHeader(@RequestHeader(value = "Accept-Language") String al) {
    
    
        System.out.println("testRequestHeader," + al);
        return SUCCESS;
    }

index.jsp

<a href="springmvc/testRequestHeader">Test RequestHeader</a>

(3)使用 @CookieValue 绑定请求中的 Cookie 值

  • @CookieValue 可让处理方法入参绑定某个 Cookie 值

SpringMVCTest.java

	/*
        了解:
        @CookieValue:映射一个 Cookie 值,属性同 @RequestParam
     */
    @RequestMapping("/testCookieValue")
    public String testCookieValue(@CookieValue("JSESSIONID") String sessionId){
    
    
        System.out.println("testCookieValue:sessionId=" + sessionId);
        return SUCCESS;
    }

index.jsp

<a href="springmvc/testCookieValue">Test CookieValue</a>

(4)使用 POJO 对象绑定请求参数值

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

SpringMVCTest.java

	@RequestMapping("/testPojo")
    public String testPojo(User user){
    
    
        System.out.println("testPojo:" + user);
        return SUCCESS;
    }

index.jsp

<form action="springmvc/testPojo" method="post">
    username:<input type="text" name="username" />
    <br>
    password:<input type="password" name="password" />
    <br>
    email:<input type="text" name="email" />
    <br>
    age:<input type="text" name="age"/>
    <br>
    city:<input type="text" name="address.city"/>
    <br>
    province:<input type="text" name="address.province"/>
    <br>
    <input type="submit" value="submit"/>
</form>

(5)使用 Servlet API 作为入参

MVC 的 Handler 方法可以接受的 ServletAPI 类型的参数

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • java.security.Principal
  • Locale
  • InputStream
  • OutputStream
  • Reader
  • Writer

SpringMVCTest.java

	@RequestMapping("/testServletAPI")
    public void testServletAPI(HttpServletRequest request,
                               HttpServletResponse response, Writer out) throws IOException {
    
    
        System.out.println("testServletAPI," + request + "," + response);
        out.write("hello springmvc");
//        return SUCCESS;
    }

index.jsp

<a href="springmvc/testServletAPI">Test ServletAPI</a>

猜你喜欢

转载自blog.csdn.net/Lu1048728731/article/details/112134208
今日推荐