隐藏

SpringMVC入门(三)SpringMVC的参数传递、跳转方式

发布:2021/7/25 13:56:00作者:管理员 来源:本站 浏览次数:1178

前言
      本章讲解SpringMVC的参数传递和其跳转方式


方法
1.概念


我们知道,SpringMVC用来简化控制层的编写,代替以前的servlet。但是我们前台的参数是怎样传递到控制层去使用呢?控制层怎样进行页面的跳转呢?就这些话题,我们接下来进行一个探讨。


2.基本数据类型传值和对象传值


例如,我们的前台页面有如下表单:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<form action="/test1" method="post">
    用户名:<input name="username" type="text" value=""><br/>
    密码:<input name="password" type="password" value=""><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>
后台的controller只要与它参数名称相同就可以准确的接收该参数 


package cn.edu.ccut.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
/**
 * @Auther:jwang
 * @Date:2019/1/7
 * @Description:cn.edu.ccut.controller
 * @Version 1.0
 **/
@Controller
public class TestController {
 
    @RequestMapping("/test1")
    public String test1(String username,String password){
        System.out.println("username="+username);
        System.out.println("password="+password);
        return "test";
    }
}
输入非中文的时候,正常进行显示:




如果输入的是中文,则乱码!!这里我多说一嘴,我们一定要解决这个中文乱码!






 spring为我们配置了字符编码的过滤器,我们来配置一下web.xml,这将解决所有的post请求带来的中文乱码问题:


<!-- 配置字符编码过滤器 -->
<filter>
    <filter-name>characterEncoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
 
<filter-mapping>
    <filter-name>characterEncoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
我们重启再次运行看一下效果:




解决了该乱码问题,那么书归正传,继续我们的传值方式的讲解,还有一种是对象传递:


定义User实体类:其属性的username和password和我们表单上的两个文本框名称相一致也同样可以传递:






编写Controller方法:


package cn.edu.ccut.controller;
 
import cn.edu.ccut.bo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
/**
 * @Auther:jwang
 * @Date:2019/1/7
 * @Description:cn.edu.ccut.controller
 * @Version 1.0
 **/
@Controller
public class TestController {
    //普通传值方式
    @RequestMapping("/test1")
    public String test1(String username,String password){
        System.out.println("username="+username);
        System.out.println("password="+password);
        return "test";
    }
    //对象传值方式
    @RequestMapping("/test2")
    public String test2(User user){
        System.out.println("username="+user.getUsername());
        System.out.println("password="+user.getPassword());
        return "test";
    }
}
 我们查看一下此时的效果:






 3.复杂数据类型传值


我们表单中写的就是一个普通的text文本框,那么我们的单选框、多选框、下拉框、文本域又是如何传值的呢,我们进行测验:


重新编写表单:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<form action="/test3" method="post">
    用户名:<input type="text" name="username" id="username" value="张三"/><span id="usernameSpan"></span><br/>
    性&nbsp;&nbsp;&nbsp;&nbsp;别:<input type="radio" name="sex" value="男" checked="checked"/>男<input type="radio" name="sex" value="女"/>女<span></span><br/>
    爱&nbsp;&nbsp;&nbsp;&nbsp;好:<input type="checkbox" name="hobby" value="足球" />足球<input type="checkbox" name="hobby" value="游泳"/>游泳
    <input type="checkbox" name="hobby" value="棋牌" />棋牌<span></span><br/>
    毕业院校:<select name="school" id="school" class="sd">
        <option value="--请选择--">--请选择--</option>
        <option value="清华大学">清华大学</option>
        <option value="北京大学">北京大学</option>
        <option value="挖掘机技术学院">挖掘机技术学院</option>
    </select><span></span><br/>
    个人简介:<textarea rows="3" cols="20" name="introduce" id="introduce"></textarea><span></span><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>
我们尝试将这些传递到后台,编写controller如下,我们先都用String接收


//复杂传值测试
@RequestMapping("/test3")
public String test3(String username,String sex,String hobby,String school,String introduce){
    System.out.println("文本框username="+username);
    System.out.println("单选钮sex="+sex);
    System.out.println("多选框hobby="+hobby);
    System.out.println("下拉框school="+school);
    System.out.println("文本域introduce="+introduce);
    return "test";
}
运行结果如下:




证明是可行的,但是我们中有一个多选框我们想把它编程List方便操作,那么怎么改变呢?做如下更改


//复杂传值测试
@RequestMapping("/test3")
public String test3(String username, String sex, @RequestParam("hobby") List<String> hobby, String school, String introduce){
    System.out.println("文本框username="+username);
    System.out.println("单选钮sex="+sex);
    System.out.println("多选框hobby="+hobby);
    System.out.println("下拉框school="+school);
    System.out.println("文本域introduce="+introduce);
    return "test";
}
 运行结果如下:






可见我们成功的完成了几乎所有表单元素的参数传递。


注解@RequestParam解释
该注解一共有三个参数:value,required以及defaultValue


value:表示修改传递过来的属性名称,将以value的值为准,一般用于前台传递参数名称和后台方法参数名称不一致
required:可选值为true/false,true表示该参数必须赋值,不赋值将会报错
defaultValue:表示赋值一个默认值给该参数
4.超链接和restful风格参数传递


在页面中编写一个超链接携带参数username和password如下:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<a href="/test1?username=admin&password=admin">超链接</a>
</body>
</html>
我们点击一下看效果:






可见和普通的传值方式没有什么区别!


restful传值方式:
超链接进行如下更改:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<a href="/test4/admin/admin">超链接</a>
</body>
</html>
 乍一看好像是请求了一个controller,其实controller是/test4,它传递了两个参数admin和admin


controller进行如下更改:


package cn.edu.ccut.controller;
 
import cn.edu.ccut.bo.User;
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.RequestParam;
 
import java.util.List;
 
/**
 * @Auther:jwang
 * @Date:2019/1/7
 * @Description:cn.edu.ccut.controller
 * @Version 1.0
 **/
@Controller
public class TestController {
    //普通传值方式
    @RequestMapping("/test1")
    public String test1(String username,String password){
        System.out.println("username="+username);
        System.out.println("password="+password);
        return "test";
    }
    //对象传值方式
    @RequestMapping("/test2")
    public String test2(User user){
        System.out.println("username="+user.getUsername());
        System.out.println("password="+user.getPassword());
        return "test";
    }
 
    //复杂传值测试
    @RequestMapping("/test3")
    public String test3(String username, String sex, @RequestParam("hobby") List<String> hobby, String school, String introduce){
        System.out.println("文本框username="+username);
        System.out.println("单选钮sex="+sex);
        System.out.println("多选框hobby="+hobby);
        System.out.println("下拉框school="+school);
        System.out.println("文本域introduce="+introduce);
        return "test";
    }
 
    //restful传值方式
    @RequestMapping("/test4/{username}/{password}")
    public String test4(@PathVariable String username, @PathVariable String password){
        System.out.println("username="+username);
        System.out.println("password="+password);
        return "/test";
    }
}
我们运行一下看效果:






 注解@PathVariable解释
该注解只有一个参数value,该注解的功能表示获取请求路径上占位符为指定参数名称的值,我们上面的例子就是username,如果占位符和方法参数名称不一致,可以设置该注解的value值,效果和@RequestParam的value值类似!


 


特别的:
我们可以使用Map接收所有的简单参数(复选框等复杂参数只能获取第一个值)


实例:使用复杂数据类型传值讲解中的例子


controller方法作如下改动:


//复杂传值测试
@RequestMapping("/test3")
public String test3(String username, String sex, @RequestParam("hobby") List<String> hobby, String school, String introduce, @RequestParam Map<String, Object> conts){
    System.out.println("文本框username="+username);
    System.out.println("单选钮sex="+sex);
    System.out.println("多选框hobby="+hobby);
    System.out.println("下拉框school="+school);
    System.out.println("文本域introduce="+introduce);
    return "redirect:test.jsp";
}
我们可以发现,我们在Map上添加了一个@RequestParam注解,则默认接收所有参数和值以键值对的形式保存!


这一点应对参数较多时用处还是很大的,和对象传值方式类似!


跳转方式
1.请求转发


默认的controller的跳转方式为请求转发,相当于return "forward:路径",默认forward:可以省略,所以我们常见的跳转是这样的:






2.重定向


通过配置 return "redirect:路径"来表示进行重定向






特别的:如果使用了forward或者redirect的话,自定义的视图解析器将不起作用!


附录:
@ResponseBody注解的使用
之前我们发现一个问题,就是controller中只能配置返回值类型为String,这是因为这些方法仅仅加上了@RequestMapping注解,他就表示执行完方法之后进行页面跳转,可是有些情况我们不需要它跳转,只是为了获取得到的对象值,如ajax


controller进行如下编写:
 


package cn.edu.ccut.controller;
 
import cn.edu.ccut.bo.User;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
 
import java.util.List;
 
/**
 * @Auther:jwang
 * @Date:2019/1/7
 * @Description:cn.edu.ccut.controller
 * @Version 1.0
 **/
@Controller
public class TestController {
    //普通传值方式
    @RequestMapping("/test1")
    public String test1(String username,String password){
        System.out.println("username="+username);
        System.out.println("password="+password);
        return "test";
    }
    //对象传值方式
    @RequestMapping("/test2")
    public String test2(User user){
        System.out.println("username="+user.getUsername());
        System.out.println("password="+user.getPassword());
        return "test";
    }
 
    //复杂传值测试
    @RequestMapping("/test3")
    public String test3(String username, String sex, @RequestParam("hobby") List<String> hobby, String school, String introduce){
        System.out.println("文本框username="+username);
        System.out.println("单选钮sex="+sex);
        System.out.println("多选框hobby="+hobby);
        System.out.println("下拉框school="+school);
        System.out.println("文本域introduce="+introduce);
        return "redirect:test.jsp";
    }
 
    //restful传值方式
    @RequestMapping("/test4/{username}/{password}")
    public String test4(@PathVariable String username, @PathVariable String password){
        System.out.println("username="+username);
        System.out.println("password="+password);
        return "/test";
    }
 
    //使用@ResponseBody注解将数据转化为json
    @RequestMapping("/test5")
    @ResponseBody
    public User test5(User user){
        System.out.println("username="+user.getUsername());
        System.out.println("password="+user.getPassword());
        return user;
    }
}
前台使用超链接的方式进行访问,效果如下:




我们在前台获得了如下的json,代表我们成功的实现了返回数据的操作,而不是跳转页面!