SpringMVC学习笔记 | @RequestMapping注解的使用及其各种绑定请求参数的方法

使用@RequestMapping映射请求

SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求。

对于@RequestMapping注解,在控制器的类定义及方法定义处都可以标注

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

DispatcherServlet截获请求后,就通过控制器上@RequestMapping提供的映射信息确定请求所对应的处理方法

首先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">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

dispatcher-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.cerr.springmvc.handlers"/>

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

我们创建一个控制器类SpringMVCTest,代码如下:

package com.cerr.springmvc.handlers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

    private static final String SUCCESS = "success";
    @RequestMapping("/testRequestMapping")
    public String testRequestMapping(){
        System.out.println("testRequestMapping");
        return SUCCESS;
    }

}

对于这个控制器类,我们在类定义处注解了@RequestMapping("/springmvc"),在方法定义处注解了@RequestMapping("/testRequestMapping"),则该方法的映射链接为:springmvc/testRequestMapping。

在index.jsp中

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <a href="springmvc/testRequestMapping">Test</a>
  </body>
</html>

映射请求参数、请求方法或请求头

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

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

对于请求参数及请求头,params和headers支持简单的表达式:
例如:

  • param1:表示请求必须包含名为param1的请求参数
  • !param1:表示请求不能包含名为param1的请求参数
  • param1!=value1:表示请求包含名为param1的请求参数,但是其值不能为value1
  • {"param1=value1","param2"}:请求必须包含名为param1和param2两个参数,且param1参数的值必须为value1
package com.cerr.springmvc.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
    private static final String SUCCESS = "success";

    /***
     * 映射URL和请求参数
     * @return
     */
    @RequestMapping(value = "testParamsAndHeaders",params = {"username","age!=10"})
    public String testParamsAndHeaders(){
        System.out.println("testParamsAndHeaders");
        return SUCCESS;
    }

    /**
     * 映射URL和请求方法
     * @return
     */
    @RequestMapping(value = "/testMethod",method = RequestMethod.POST)
    public String testMethod(){
        System.out.println("testMethod");
        return SUCCESS;
    }
}

使用通配符

对于@RequestMapping注解,还支持通配符:

  • :匹配文件名中的一个字符
  • *:匹配文件名中的任意字符
  • **:匹配多层路径

例如:@RequestMapping("/testAntPath/*/abc"),可以匹配/springmvc/testAntPath/mmmm/abc等等,其中的mmmm可以替换为任意的字符。


@PathVariable

通过@PathVariable注解可以将URL中占位符参数绑定到控制器处理方法的入参中:URL中的{xxx}占位符通过@PathVariable("xxx")绑定到操作方法的入参中,例如:

package com.cerr.springmvc.handlers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

    private static final String SUCCESS = "success";

    /***
     * @PathVariable可以来映射URAL中的占位符到目标方法的参数中
     * @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">testPathVariable</a>

使用HiddenHttpMethodFilter来发送DELETE和PUT等请求

HTTP有四种表示操作方式的动词:

  • GET:获取资源
  • POST:新建资源
  • PUT:更新资源
  • DELETE:删除资源

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

REST风格的URL的实例,以CRUD为例:
/order POST:新建一个order
/order/1 PUT:修改id=1的order
/order/1 GET:获取id=1的order
/order/1 DELETE:删除id=1的order

使用HiddenHttpMethodFilter来发送PUT请求和DELETE请求的步骤

  • 需要配置HiddenHttpMethodFilter
<!-- 配置org.springframework.web.filter.HiddenHttpMethodFilter:可以把POST请求转为DELETE或POST请求 -->
    <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>
  • 需要发送POST请求
  • 需要在发送POST请求时携带一个name="_method"的隐藏域,值为DELETE或PUT

下面我们对这四种请求分别举例子,我们编写了如下的html

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form action="springmvc/testRest/1" method="post">
      <input type="hidden" name="_method" value="PUT">
      <input type="submit" value="TestRest PUT"/>
    </form>
    <br><br>

    <form action="springmvc/testRest/1" method="post">
      <input type="hidden" name="_method" value="DELETE">
      <input type="submit" value="TestRest DELETE"/>
    </form>
    <br><br>

    <form action="springmvc/testRest" method="post">
      <input type="submit" value="TestRest POST"/>
    </form>
    <br><br>

    <a href="springmvc/testRest/1">Test Rest Get</a><br>
  </body>
</html>

package com.cerr.springmvc.handlers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

    private static final String SUCCESS = "success";

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

    @RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)
    public String testRestDelete(@PathVariable("id") 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("id") Integer id){
        System.out.println("testRest GET:"+id);
        return SUCCESS;
    }

}

对于PUT、DELETE、GET请求,参数的传递我们可以使用上面所学的@PathVariable注解来将占位符的值传递给方法的参数。


请求处理方法签名

SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的响应入参中

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

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

@RequestParam来映射请求参数

使用@RequestParam来映射请求参数,其注解有如下方法:

  • value值即为请求参数的参数名
  • request可以指定该参数是否是必须传的
  • defaultValue表示请求参数的默认值

例子:在jsp文件中通过超链接传入两个参数,在控制器类中接受并打印。
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">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

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

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

dispatcher-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.cerr.springmvc.handlers"/>

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

jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <a href="springmvc/testRequestParam?username=cerr&age=11">Test testRequestParam</a>
  </body>
</html>

package com.cerr.springmvc.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
    private static final String SUCCESS = "success";

    @RequestMapping(value = "/testRequestParam")
    public String testRequestParam(@RequestParam(value = "username") String un,
            @RequestParam(value = "age",required = false) Integer age){
        System.out.println("testRequestParam " + un + " " + age);
        return SUCCESS;
    }
}

使用@RequestHeader绑定请求报头的属性值

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

package com.cerr.springmvc.handlers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
    private static final String SUCCESS = "success";

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

   
}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <a href="springmvc/testReuqestHeader">Test testReuqestHeader</a>
  </body>
</html>

@CookieValue

映射一个Cookie值,属性同@RequestParam

package com.cerr.springmvc.handlers;

import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

    private static final String SUCCESS = "success";

    @RequestMapping(value = "/testCookieValue")
    public String testCookieValue(@CookieValue("JSESSIONID") String sessionId){
        System.out.println("testCookieValue: sessionId:"+sessionId);
        return SUCCESS;
    }

}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <a href="springmvc/testCookieValue">Test testCookieValue</a>
  </body>
</html>

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

SpringMVC会按请求参数名或POJO属性名进行自动匹配,自动为该对象填充属性值,并且支持级联属性。
dept.deptId、dept.address.city等。

我们定义一个User类,里面包含另一个实体类Address:

package com.cerr.springmvc.entities;

public class User {
    private String username;
    private String password;
    private String email;
    private int age;
    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 String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

我们再定义一个实体类Address:

package com.cerr.springmvc.entities;

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 + '\'' +
                '}';
    }
}

index.jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <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">
      <input type="submit" value="Submit">
    </form>
  </body>
</html>

控制器类的代码:

package com.cerr.springmvc.handlers;

import com.cerr.springmvc.entities.User;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.springframework.stereotype.Controller;
import org.springframework.util.concurrent.SuccessCallback;
import org.springframework.web.bind.annotation.*;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

    private static final String SUCCESS = "success";

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

使用原生ServletAPI作为目标方法的参数

可以使用Servlet元素的API作为目标方法的参数,具体支持以下几种类型:

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

例如:我们将HttpServletRequest和HttpServletResponse作为目标方法的参数

@RequestMapping("/testServletAPI")
    public String testServletApi(HttpServletRequest request,
                                 HttpServletResponse response){
        System.out.println(request+" "+response);
        return SUCCESS;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值