SpringMVC_03_方法的参数

一、方法的参数

1. JavaEE组件

  • HttpServletRequest
  • HttpServleetResponse
  • HttpSession

如下例,新建ParamController.java

@Controller
@RequestMapping("/param")
public class ParamController {

    @RequestMapping("/test1")
    public void test1(HttpServletRequest req, HttpServletResponse resp, HttpSession session) throws IOException {
        System.out.println("ParamController.test1," + req + "," + resp + "," + session);

        String username = req.getParameter("username");
        session.setAttribute("username", username);

        PrintWriter out = resp.getWriter();
        out.print("<h1>" + username + "<h1>");
        out.flush();
        out.close();
    }
}

2. IO流

  • InputStream/OutStream
  • Reader/Writer

IO流可以直接作为参数获取

    @RequestMapping("/test2")
    public void test2(InputStream is, OutputStream os) throws IOException {
        System.out.println("ParamController.test2," + "," + is + "," + os);
    }

    @RequestMapping("/test3")
    public void test3(Reader reader, Writer writer) throws IOException {
        System.out.println("ParamController.test2," + "," + reader + "," + writer);
    }

也可以通过HttpServletRequest和HttpServleetResponse获取

    @RequestMapping("/test1")
    public void test1(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        InputStream is = req.getInputStream();
        OutputStream os = resp.getOutputStream();
        Reader reader = req.getReader();
        Writer writer = resp.getWriter();
    }

3. 向界面传递数据

使用ModelMapModelMap将数据存储到Request作用域中
例:
添加result.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>result</title>
</head>
<body>
    name:${requestScope.name} <br>
    age:${age} <br>
    sex:${sex} <br>
    address:${address} <br>
</body>
</html>
    @RequestMapping("/test4")
    public String test4(Model model, Map map, ModelMap modelMap){
        model.addAttribute("name", "wql");
        map.put("age", 23);
        modelMap.addAttribute("sex", "male");
        modelMap.put("address", "beijing");
        return "result";
    }

在这里插入图片描述

4. String和基本数据类型及其包装类

4.1 @RequestParam

@RequestParam表示参数来源于请求参数,如http://localhost:8080/param/test6?name=wql&age=20中name和age就是请求参数
方法的参数如果是String类型和基本数据类型及其包装类,如果参数前面没有注解,则参数前默认添加@RequestParam注解
@RequestParam的源码如下所示

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
  • String name() default ""请求参数与方法中的参数名不一致时会用到
  • boolean required() default true;如果参数前不加注解,参数可为空;如果加上注解@RequestParam,默认该参数不能为空
  • String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";指定参数的默认值

以test5为例

    @RequestMapping("/test5")
    public String test5(@RequestParam String name,
                        @RequestParam(name = "years_old")int age,
                        @RequestParam(required = false, defaultValue = "1") Integer sex,
                        String address){
        System.out.println("name=" + name + ", age=" + age + ", sex=" + sex + ", address=" + address);
        return "result";
    }

在地址栏输入http://localhost:8080/param/test5?name=wql&years_old=20&sex=1&address=beijing,控制台可得到相应的输出
在这里插入图片描述
其中参数name不能省略,参数sex可以省略,默认值为1,参数adress可以省略,将地址栏输入改为http://localhost:8080/param/test5?name=wql&years_old=20,控制台输出如下结果
在这里插入图片描述

4.2 @PathVariable

前几天学了@PathVariable,其表示参数来源于URL,如@RequestMapping("/test6/{name}/{age}")中name和age就是URL中的参数
test5与test6做一个对比

    @RequestMapping("/test6/{name}/{age}")
    public String test6(@PathVariable("name") String stuName,
                        int age,
                        @RequestParam(required = false, defaultValue = "1") Integer sex,
                        String address){
        System.out.println("name=" + stuName + ", age=" + age + ", sex=" + sex + ", address=" + address);
        return "result";
    }

int ageString address这两个参数前面都没有注解,默认添加@RequestParam注解,但是可以省略
@PathVariable String name表示参数来源于URL,如果名字不一致,可在注解中加入
在地址栏输入http://localhost:8080/param/test6/www/20?stuName=wql&age=10
在控制台可得到
在这里插入图片描述
从上可以看出,name来自URL,age来自请求参数

4.3 @RequestHeader

@RequestHeader表示请求参数来源于请求头,关于请求头的内容,在SpringMVC_02中稍微提了一下,下图展示了请求头里的详细内容
在这里插入图片描述
我们可以通过@RequestHeader获取请求头里的内容,
首先往客户端中添加一些cookie

    @RequestMapping("/addCookie")
    public String addCookie(HttpServletResponse resp){

        //向客户端添加cookie
        Cookie cookie = new Cookie("username", "wql");
        cookie.setMaxAge(7*24*60*60);//7天
        resp.addCookie(cookie);

        return "result";
    }

然后获取请求头中的User-Agent和Cookie

    @RequestMapping("test7")
    public String test7(@RequestHeader("User-Agent") String userAgent, @RequestHeader("Cookie") String cookie){
        System.out.println("userAgent: " + userAgent + "\nCookie:" + cookie);
        return "result";
    }

在这里插入图片描述

4.4 @CookieValue

通过@RequestHeader可以获取cookie里面的信息,以字符串的形式把所有的cookie返回给我们。但是有时候cookie里面的信息比较多,比如说我们往cookie里添加名为username的cookie,用@RequestHeader的方式获取username的值比较麻烦,我们可以使用@CookieValue来获取特定的cookie值

通过@CookieValue获取cookie

    @RequestMapping("/test8")
    public String test8(@CookieValue String username, @CookieValue("JSESSIONID") String sessionId){
        System.out.println("username: " + username + "\nsessionId:" + sessionId);
        return "result";
    }

在这里插入图片描述

4.5 @RequestBody

@RequestBody表示参数来源于请求体,只有请求方式为POST时才会有请求体。
我们使用SpringMVC_01中设计的表单,将其请求方式改为POST,点击提交之后跳转至/param/test9
在登录页面输入用户名www,密码111,点击登录
在这里插入图片描述
通过审查元素可以发现多了请求体一栏
在这里插入图片描述
我们通过@RequestBody获取其信息

    @RequestMapping("/test9")
    public String test9(@RequestBody String requestBody){
        System.out.println("requestBody:" + requestBody);
        return "result";
    }

在这里插入图片描述

5. 自定义类型参数

@ModelAttribute将请求数据转换为对象,如果方法的参数为自定义的类型,默认参数前有@ModelAttribute注解
条件:对象的属性名必须与表单元素的名称相同
例:我们自定义一个类UserVo

package vo;

public class UserVo {

    private String username;
    private String password;
    private String phone;
    private String email;
    private Integer age;

    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 getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

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

    public Integer getAge() {
        return age;
    }

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

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

添加一个注册页面register.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>register</title>
</head>
<body>
    <h2>用户注册</h2>
    <form action="${pageContext.request.contextPath}/user/register" method="post">
        用户名:<input type="text" name="username"> <br>
        密码:<input type="password" name="password"> <br>
        年龄:<input type="text" name="age"> <br>
        手机号:<input type="text" name="phone"> <br>
        邮箱:<input type="text" name="email"> <br>
        <input type="submit" value="注册">
    </form>
</body>
</html>

在springmvc.xml配置可以直接访问register.xml页面

<beans>
    <mvc:view-controller path="/userRegister" view-name="register"/>
</beans>

配置UserController

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/register")
    public String register(UserVo userVo){
        System.out.println("UserController.register.userVo:" + userVo);
        return "success";
    }
}

启动程序,在地址栏输入localhost:8080/userRegister,可跳转到注册页面
在这里插入图片描述
输入注册信息,点击注册,跳转到成功页面,也控制栏输出如下
在这里插入图片描述

@ModelAttribute不仅可以用于自定义类型的数据,还可以用于向request域中添加数据,与上述方法不一样的地方时,@ModelAttribute注解需要写在方法的上方。在调用所有目标方法时,都会先调用被@ModelAttribute所注解的方法,并向模型中添加数据。

例:我们想在request域中添加一个String类型的列表,并在result.jsp中显示出来。首先在result.jsp中做如下修改

<body>
    ...

    位置选择:
    <select>
        <c:forEach items="${types}" var="type">
            <option value="">${type}</0></option>
        </c:forEach>
    </select>
</body>

在UserController中添加方法,且其被@ModelAttribute注解

    @ModelAttribute("types")
    public List<String> getTypes(){
        System.out.println("UserController.getTypes");
        List<String> list = Arrays.asList("辅助","上单","中单","打野","下路");
        return list;
    }

添加测试方法,跳转到result.jsp

    @RequestMapping("/test")
    public String test(){
        System.out.println("UserController.test");
        return "result";
    }

启动程序,在地址栏输入localhost:8080/user/test可得如下结果
在这里插入图片描述
可以看到,程序是先调用getTypes方法,而后调用test方法。
result.jsp界面显示如下
在这里插入图片描述

6. 错误参数

我们在register.xml页面里添加了一个form表单

    <form action="${pageContext.request.contextPath}/user/register" method="post">
        用户名:<input type="text" name="username"> <br>
        密码:<input type="password" name="password"> <br>
        年龄:<input type="text" name="age"> <br>
        手机号:<input type="text" name="phone"> <br>
        邮箱:<input type="text" name="email"> <br>
        <input type="submit" value="注册">
    </form>

我们在实际的开发中,需要对表单进行数据校验,其中分为客户端表单校验和服务端表单校验。
客户端表单校验中出现错误会显示给客户端,使用户更改输入的参数;而服务端的表单校验的结果由后台进行操纵。
ErrorsBindingResult可以用来接收错误信息,实现服务端的数据校验。其中ErrorsBingdingResult的父类。
接下来在UserController.java中加入错误参数

    @RequestMapping("/register")
    public String register(@ModelAttribute UserVo userVo, Errors error){
        //手动进行服务端数据校验
        if(userVo.getAge() < 0 || userVo.getAge() > 120){
            error.reject("年龄只能在0-120之间");//手动添加错误
        }
        //判断是否有错误
        if(error.hasErrors()){
            System.out.println(error);
            return "register";
        }
        System.out.println("UserController.register.userVo:" + userVo);
        return "success";
    }

启动程序,来到注册界面,在age一栏输入参数123,点击注册,控制台输出如下错误
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值