Spring MVC学习总结(二):Spring MVC参数获取方式

一、@RequestMapping注解

      RequestMapping是一个用来处理请求地址映射的注解,Spring MVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求。当DispatcherServlet截获请求后,就通过控制器上的@RequestMapping提供的映射信息确定请求所对应的处理方法。

      使用位置:在控制器的类定义以及方法处

      类定义处:提供初步的请求映射信息,相对于web应用的根目录,表示类中的所有响应请求的方法都是以该地址作为父路径。

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

@RequestMapping有六个属性,具体介绍如下:

(1)value:指定请求的实际地址,指定的地址可以是具体地址、可以RestFul动态获取、也可以使用正则设置。

@Controller
@RequestMapping(value = "/user")        //RequestMapping用来类上
public class UserController {
    //RequestMapping用来方法上
    @RequestMapping(value = "/login")
    public void  login(){

    }
}

(2)method:指定请求的method类型, GET、POST、PUT、DELETE等。如下:

    /**
     *  请求的method必须是get
     */
    @RequestMapping(value = "/test01", method = RequestMethod.GET)
    public void test01(){
        System.out.println("get方式访问");
    }
    /**
     *  请求的method必须是delete
     */
    @RequestMapping(value = "/test02", method = RequestMethod.DELETE)
    public void test02(){
        System.out.println("delete方式访问");
    }

(3)params: 规定了页面发起请求时request中必须包含的参数值。

关于params的一些简单的表达式操作:

param:请求中必须包含param的请求参数。

!param:请求中必须不包含param的请求参数。

param!=value;请求中param的值必须不为value。

{“param1=value1”,”param2”}:请求中必须包含param1和param2的请求参数,且param1的值必须为value1。

示例如下:

    @RequestMapping(value = "/paramTest01", params = "username")
    public void paramTest01(){
        System.out.println("参数中必须包含username的请求参数");
    }
    @RequestMapping(value = "/paramTest02", params = "username=tom")
    public void paramTest02(){
        System.out.println("参数中必须包含username的请求参数,并且值必须为tom");
    }
    @RequestMapping(value = "/paramTest03", params = "!address")
    public void paramTest03(){
        System.out.println("参数中必须不包含address的请求参数");
    }
    @RequestMapping(value = "/paramTest04", params = {"username=tom","age"})
    public void paramTest04(){
        System.out.println("参数中必须包含username和age的两个请求参数,并且username的值必须为tom");
    }

(4)headers:规定了页面发起请求时request中必须包含的header值。

      示例:通过User-Agent指定当浏览器为火狐时方可访问。

    @RequestMapping(value = "/testHeader", headers = {"User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0"})
    public void testHeader(){
        System.out.println("火狐浏览器才能访问");
    }

(5)consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html。

(6)produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。

二、Spring中获取请求参数的注解

1、@PathVariable注解

(1)介绍:@PathVariable是Spring3.0的一个新功能,用于接收请求路径中占位符的值。它只支持一个属性value,类型是为String,代表绑定的属性名称。默认不传递时,绑定为同名的形参。 

(2)语法:@PathVariable("xxx")通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中

(3)案例

<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/pathVariable01/3">@PathVariable指定URL变量名</a>
<a href="${pageContext.request.contextPath}/pathVariable01/tom/18k">@PathVariable定义多个URL变量</a>
</body>
</html>
    /**
     * @PathVariable指定URL变量名
     * @param id
     * @return
     */
    @RequestMapping(value = "/pathVariable01/{id}")
    public String pathVariable01(@PathVariable("id") Integer id){
        System.out.println(id);
        return "success";
    }

    /**
     * 定义多个URL变量
     * @param name
     * @param age
     * @return
     */
    @RequestMapping(value = "/pathVariable01/{name}/{age}")
    public String pathVariable02(@PathVariable(value = "name") String name, @PathVariable(value = "age") Integer age){
        System.out.println("name is : " + name + ", age is : " + age);
        return "success";
    }

 注意:

a.在index.jsp中请求的url写法应为:

      <a href="${pageContext.request.contextPath}/pathVariable01/3">@PathVariable指定URL变量名</a>

      错误写法:

      <a href="${pageContext.request.contextPath}/pathVariable01/{3}">@PathVariable指定URL变量名</a>

b.PathVariable的value值必须和方法的入参名相同。

2、@RequestParam注解

(1)介绍该注解是Spring MVC中用于接收用户发起请求时所携带的参数信息,用于控制器中处理请求的方法上。

(2)语法

@RequestParam(value = "参数名", required = true/false, defaultValue = "默认值"

相当于Servlet中的request.getParameter("参数名");

参数介绍:

value:参数名称

required:该参数在用户发起请求的时候是否是必须的,true表示必须携带该参数,false表示非必须。默认值为true。

defaultValue:该参数的默认值,如果不指定,则为null。

示例:

@RequestParam(value = "name", required = false, defaultValue = "tom"

等价于:username = request.getParameter("name");

说明:用户发起请求时需要携带name参数,但也可以没有此参数,当该值没有赋值时,默认值为tom。

(3)案例

index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/request01?name=tom">用户请求携带name参数</a>
<a href="${pageContext.request.contextPath}/request02?name=Jerry">name参数必须有</a>
<a href="${pageContext.request.contextPath}/request03?name=Mack">系统默认方式获取参数</a>
</body>
</html>

RequestTestController:

@Controller
public class RequestTestController {

    /**
     * 普通写法:用户发起请求时携带name参数
     * @param name 用户名
     * @return
     */
    @RequestMapping(value = "/request01")
    public String request01(@RequestParam("name") String name){
        System.out.println(name);
        return "success";
    }

    /**
     * 用户发起请求时必须携带name参数,如果name为null,则其默认值为tom
     * @param username
     * @return
     */
    @RequestMapping(value = "/request02")
    public String request02(@RequestParam(value = "name", required = true, defaultValue = "tom") String username){
        System.out.println(username);
        return "success";
    }
    /**
     * 系统默认方式获取请求参数:直接给方法的入参上写一个和请求参数名称相同的变量,这个变量就用来接收请求参数的值
     * 若有值则为用户指定的值,若无值则为Null。
     * @param name
     * @return
     */
    @RequestMapping(value = "/request03")
    public String request03(String name){
        System.out.println(name);
        return "success";
    }
}

说明:系统默认方式获取请求参数,直接给方法的入参写一个和请求参数名称相同的变量即可得到此值。如果使用RequestParam注解,则方法的入参和请求的参数名可以不一致,参考上述例子中的requesto2方法。

(4)RequestParam和PathVariable的区别

相同点:RequestParam和PathVariable都是用来处理前端传递过来的请求参数
不同点:RequestParam处理的是请求参数,是将对应请求路径下的请求参数值映射到处理器参数上。PathVariable处理的是路径变量,是将请求路径变量的值映射到处理器参数上。

举个例子:

若请求为/user?name=tom,则RequestParam获取到的是?之后的key-value,通过在Controller中的方法入参获取到参数的值。

若请求为/user/{name},则PathVariable获取的是路径上占位符的值,也就是{name}的值。

3、@RequestHeader注解

(1)介绍:获取请求的头信息。

(2)语法:

@RequestHeader(value = "参数名", required = true/false, defaultValue = "默认值"

相当于Servlet中request.getHeader("参数名");

示例:

@RequestHeader("User-Agent")

等价于:userAgent = request.getHeader("User-Agent");

参数介绍:

value:参数名称

required:该参数在用户发起请求的时候是否是必须的,true表示必须携带该参数,false表示非必须。默认值为true。

defaultValue:该参数的默认值,如果不指定,则为null。

(3)案例

<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/requestHeader01">@RequestHeader使用1</a>
<a href="${pageContext.request.contextPath}/request02">@RequestHeader使用2</a>
</body>
</html>
    @RequestMapping(value = "/requestHeader01")
    public String requestHeader01(@RequestHeader("User-Agent") String userAgent){
        System.out.println(userAgent);
        return "success";
    }
    @RequestMapping(value = "/requestHeader02")
    public String requestHeader02(@RequestHeader(value = "User-Agent", required = false) String userAgent){
        System.out.println(userAgent);
        return "success";
    }

 4、@CookieValue注解

(1)介绍:将请求的Cookie数据,映射到功能处理方法的参数上。

(2)语法

@CookieValue(value = "参数名", required = true/false, defaultValue = "默认值"

Servlet中的写法:

Cookie[] cookies = request.getCookies();
for(Cookie c : cookies){
    if(c.getName().equals("cookieName")){
        String value = c.getValue();
    }
}

示例:

@CookieValue("JSESSIONID")

等价于:

Cookie[] cookies = request.getCookies();
for(Cookie c : cookies){
    if(c.getName().equals("JSESSIONID")){
        String value = c.getValue();
    }
}

参数介绍:

value:参数名称

required:该参数在用户发起请求的时候是否是必须的,true表示必须携带该参数,false表示非必须。默认值为true。

defaultValue:该参数的默认值,如果不指定,则为null。

(3)案例

<a href="${pageContext.request.contextPath}/getCookie">@CookieValue使用</a>
    @RequestMapping(value = "/getCookie")
    public String getCookie(@CookieValue("JSESSIONID") String cookieVal){
        System.out.println(cookieVal);
        return "success";
    }

 5、Spring MVC中POJO对象的使用

      前面介绍了Spring MVC中获取参数的几种方式,但是当参数过多时,这种一一对应的方式就会显得代码中很乱,解决这一问题就需要使用POJO进行多参数封装。Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值(通过属性的set方法)。使用如下:

(1)在index.jsp中创建表单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/pojoUse">
    姓名: <input type="text" name="name"><br>
    性别: <input type="text" name="sex"><br>
    年龄: <input type="text" name="age"><br>
    电话: <input type="text" name="tel"><br>
    家庭住址: <input type="text" name="address"><br>
    <input type="submit" value="提交"><br>
</form>
</body>
</html>

 说明:form表单中的提交按钮,其type应该为submit,如果type为button则无法访问到后台。因为自己的失误在这里折腾了很久,后面才发现这个问题。

(2)创建Teacher对象。

public class Teacher {
    private String name;
    private String sex;
    private String age;
    private String tel;
    private String address;

    public Teacher() {
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAge() {
        return age;
    }

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

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getAddress() {
        return address;
    }


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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age='" + age + '\'' +
                ", tel='" + tel + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

(3)在Controller中使用POJO对象

    @RequestMapping(value = "/pojoUse", method = RequestMethod.POST)
    public String pojoUse(Teacher teacher){
        System.out.println(teacher);
        return "success";
    }

此外,Spring MVC中还支持级联属性。现对上述代码进行修改。

(1)在form表单中加入book的信息。

<form method="post" action="${pageContext.request.contextPath}/pojoUse">
    姓名: <input type="text" name="name"><br>
    性别: <input type="text" name="sex"><br>
    年龄: <input type="text" name="age"><br>
    电话: <input type="text" name="tel"><br>
    家庭住址: <input type="text" name="address"><br>
    书名: <input type="text" name="book.bName"><br>
    作者: <input type="text" name="book.bAuthor"><br>
    价格: <input type="text" name="book.bPrice"><br>
    <input type="submit" value="提交"><br>
</form>

(2)创建Book类。

public class Book {
    private String bName;
    private String bAuthor;
    private Double bPrice;

    public Book() {
    }

    public String getbName() {
        return bName;
    }

    public void setbName(String bName) {
        this.bName = bName;
    }

    public String getbAuthor() {
        return bAuthor;
    }

    public void setbAuthor(String bAuthor) {
        this.bAuthor = bAuthor;
    }

    public Double getbPrice() {
        return bPrice;
    }

    public void setbPrice(Double bPrice) {
        this.bPrice = bPrice;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bName='" + bName + '\'' +
                ", bAuthor='" + bAuthor + '\'' +
                ", bPrice=" + bPrice +
                '}';
    }
}

(3)在Teacher中添加Book属性,提供get和set方法,覆写toSring()。


    private Book book;


    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age='" + age + '\'' +
                ", tel='" + tel + '\'' +
                ", address='" + address + '\'' +
                ", book=" + book +
                '}';
    }
}

注意:

a.实体类中必须有无参构造的存在。

b.请求参数名和对象中的属性名要一致。

c.上面的表单中,如果输入中文则后台接受的数据会出现乱码。

解决方案:在web.xml中配置字符编码过滤器。

  <!--   字符编码过滤器  -->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!--  encoding:指定一个具体的字符集  -->
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <!-- forceEncoding:处理 response中的字符编码  -->
    <init-param>
    <param-name>forceEncoding</param-name>
    <param-value>true</param-value>
  </init-param>

猜你喜欢

转载自blog.csdn.net/weixin_47382783/article/details/113005667