SpringMVC中控制器接收JSP页面表单的参数接收方式详解及细节注意(400错误)

控制器方法中参数的接收

(1)以前的参数接收:

String  param = req.getParameter(name);

(2)SpringMVC简化这个操作,只需要给控制器方法添加参数即可

a:本质上还是调用上述方法进行接收,只不过做了封装

b:参数类型(特殊类型除外,例如:Date)可以自动转换

注意:

(1)表单中的name属性值和方法列表值保持一致,如果不一致,不会报错,但那是接收到的值是null,需要注意的是,int类型的参数不能是null,所以服务器和页面都会报错:所以,为避免这种错误,在定义实体类的时候实体类中的属性类型基本类型最好定义成包装类型

(2)当接收到的数据属日期类型时,如果仅仅使用Date作为接收参数类型时,是不能解决问题的,因为日期是有格式定义的,并且表单中的日期格式必须要和方法参数列表中的日期格式一一对应,不然也会报错;可以通过注解@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday,两次避免错误;此外,在SpringMVC中,400类型的错误,一般都是由于接收参数类型不匹配所造成的

(3)当参数列表为Boolean类型的数据时,表单中提交的参数值可以是true或者false,能够正常接收,也可以是1或者0,其中1代表true,0代表false

婚否: <input type="radio" name="married" value="1"> 已婚

     <input type="radio" name="married" value="0"> 未婚<br>

(4)当方法参数列表为一个对象时,SpringMV也可以进行参数接收,不过要求对象的属性名称必须和表单中的name值保持一致。其中,如果对象中的属性为另一个对象,在表单中可以通过对象名.属性名来进行对属性的赋值

地址: <select name="address.city">

(5)当方法参数列表为list集合,表单中的name属性值,可以通过下面方式进行命名:

 地址1: <select name="addrList[0].city">

(6)不能使用map集合作为方法参数列表

<form action="${pageContext.request.contextPath}/demo1" method="post">
    用户名: <input type="text" name="username"><br>
    年龄: <input type="text" name="age"><br>
    生日: <input type="text" name="birthday">yyyy-MM-dd<br>
    爱好: <input type="checkbox" name="hob" value="java"> java
    <input type="checkbox" name="hob" value="C++"> C++
    <input type="checkbox" name="hob" value="PHP"> PHP<br>
    婚否: <input type="radio" name="married" value="1"> 已婚
    <input type="radio" name="married" value="0"> 未婚<br>
    地址: <select name="address.city">
    <option value="北京">北京</option>
    <option value="上海">上海</option>
    <option value="天津">天津</option>
</select><br>
    地址1: <select name="addrList[0].city">
    <option value="北京">北京</option>
    <option value="上海">上海</option>
    <option value="天津">天津</option>
</select><br>
    地址2: <select name="addrList[1].city">
    <option value="北京">北京</option>
    <option value="上海">上海</option>
    <option value="天津">天津</option>
</select><br>
    <input type="submit" value="提交">
</form>

  

package com.bjsxt.controller;

import com.bjsxt.pojo.User;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Arrays;
import java.util.Date;

@Controller
public class DemoController {

    @RequestMapping("/demo1")
    public String demo1(User user) {
        System.out.println(user);
        return "index.jsp";
    }

    @RequestMapping("/demo2")
    public String demo2(String username,
                        Integer age,
                        @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday,
                        String[] hob,
                        Boolean married) {
        System.out.println("username = " + username);
        System.out.println("age = " + age);
        System.out.println("birthday = " + birthday);
        System.out.println("hob = " + Arrays.toString(hob));
        System.out.println("married = " + married);
        return "index.jsp";
    }
}

  

public class User implements Serializable {
  //此处省略getter和setter方法,正常测试时需要添加 private String username; private Integer age; @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birthday; private String[] hob; private Boolean married; private Address address; private List<Address> addrList = new ArrayList<>(); }

  

public class Address implements Serializable {
    private String city;
}

请求参数的进阶优化

使用SpringMVC进行参数接收,这种方式存在的问题:

(1)如果前台传递的参数和后台接收的参数名称不一致

(2)如果参数为空(null,“ ”),怎么处理

(3)如何对参数进行限制

解决名称不一致问题

@RequestParam:可以对请求参数进行加工,常用属性如下:

(1)value:用于定义参数的名称,如果同名,可以不写

(2)required:布尔值,用于表示参数是否必须接收

true默认值,表示必须传递,否则会抛出400错误

false表示可以不进行传递,使用null为参数赋值

(3)defaultValue:默认值,当接收到的参数为null或者空字符串时,默认值生效

注:当使用defalutValue时,required无效

@RequestMapping("/demo")
public String demo(
        @RequestParam(value = "page", defaultValue = "1") int page,
        @RequestParam(required = false, defaultValue = "10") int size) {
    System.out.println("page = " + page);
    System.out.println("size = " + size);
    return "index.jsp";
}

  

对参数进行限制

在某些情况下,传递的参数是有限制的,例如管理系统中,要求管理员登录时,用户名和密码必须传递,同时,又要求用户名必须为admin。

这时,就可以通过@RequestMapping进行限制

@RequestMapping:用于给控制器进行映射,使用位置是在一个方法上

控制器类:对当前控制器中所有的方法添加访问前缀(窄化:使路径匹配更加精确)

属性:

value:默认属性,用于配置映射的路径,/login

可以精确匹配:/demo

模糊后缀匹配:/demo.xxx

可以目录匹配:/demo/

params:用于对请求参数做限制

method:表示当前控制器方法能处理的请求参数,例如get或者post

produces:可以设置响应头,需要配置@ResponseBody注解来使用

@RequestMapping(value = "/login", params = {"username=admin", "password"})
public String login(String username, String password) {
    System.out.println("username = " + username);
    System.out.println("password = " + password);
    return "index.jsp";
}

  

Restful风格参数的传递

Restful风格的参数传递:即参数伪装到路径中,参数也作为路径的一部分

传统方式传参: localhost:8080/demo?name=admin&pwd=123

Restful风格: localhost:8080/demo/admin/123

例如:京东商城,书旗网

Restful风格传参需要配置@pathvariable注解SpEL一起实现:

{name}/{pwd}类似于占位符

@RequestMapping("/rest/{name}/{pwd}")
public String rest(
        @PathVariable("name") String username,
        @PathVariable String pwd) {
    System.out.println("username = " + username);
    System.out.println("pwd = " + pwd);
    return "/index.jsp";
}

  

<a href="${pageContext.request.contextPath}/rest/zhangsan/123">Restful风格传参</a>

  

 

  

 

posted @ 2019-06-11 22:27  小菜鸟大梦想  阅读(1459)  评论(0编辑  收藏