以下代码如想自己操作的话,我的环境是建立在这篇博客中。
IDEA大环境https://blog.youkuaiyun.com/monkey_wei/article/details/105788910
使用控制器接收参数往往是Spring MVC开发业务逻辑的第一步,所以我们有必要好好了解一下。
为此,我们先建一个接受各类参数的控制器——ParamsController,它很简单,整个关于参数接受的例子都可以通过它来完成。代码如下:
ParamsController
package com.ssm.example1.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/params")
public class ParamsController {
}
}
下面的例子将在接收参数控制器的基础上增加方法来演示如何接收各类参数,以角色表单为主进行论述,代码如下,如果有变动后面会谈及。
index.jsp
<%@ page contentType="text/html" pageEncoding="UTF-8" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>参数</title>
<!-- 加载Query方法-->
<script src="https://code.jquery.com/jquery-3.2.0.js"></script>
</head>
<body>
<form id="form" action="./params/commonParams.do">
<table>
<tr>
<td>角色名称</td>
<td><input id="roleName" name="roleName" value=""></td>
</tr>
<tr>
<td>备注</td>
<td><input id="note" name="note"></td>
</tr>
<tr>
<td></td>
<td align="right"><input type="submit" value="提交"></td>
</tr>
</table>
</form>
</body>
</html>
1、接收普通请求参数
Spring MVC目前比较智能化,如果传递过来的参数名称和HTTP的保存一致,那么无需任何注解也可以获取参数,代码如下:
ParamsController.java
package com.ssm.example1.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/params")
public class ParamsController {
@RequestMapping("/commonParams")
public ModelAndView comoonParams(String roleName,String note){
System.out.println("roleName=>"+roleName);
System.out.println("note=>"+note);
ModelAndView mv=new ModelAndView();
mv.setViewName("index");
return mv;
}
}
上面是通过参数名称和HTTP请求参数的名称一致来获取参数,当运行tomcat后输入http://localhost:8080/params/commonParams.do?roleName=hjw&¬e=shuai 后,控制台就会输出
参数。
如果参数名称不一致是没法获取到参数的,而且这样的方式允许参数为空。
当然这样还是比较简单,但是能够满足大部分简单的表单需求。在参数很多的情况下,比如新增一个用户需要多达十几个字段,在用这样的方式,显然方法的参数会非常多,这个时候就应该考虑使用一个pojo来管理这些参数。在没有任何注解的情况下,Spring MVC也有映射POJO的能力。我们新建一个角色参数类,代码如下:
RoleParams
package com.ssm.example1.pojo;
public class RoleParams {
private String roleName;
private String note;
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
显然这个POJO的属性和HTTP参数一一对应了,在ParamController中添加一个方法来通过这个POJO获取HTTP请求参数。代码如下:
@RequestMapping("/commonParamPojo")
public ModelAndView commonParamPojo(RoleParams roleParams){
System.out.println("roleName=>"+roleParams.getRoleName());
System.out.println("note=>"+roleParams.getNote());
ModelAndView mv=new ModelAndView();
mv.setViewName("index");
return mv;
}
测试如图所示:
结果:
2、使用@RequestParam注解获取参数
有时候前端的参数命名规则和后台的不一样,比如前端把角色名称的参数命名为role_name,这个时候就需要@RequestParam注解来解决这个问题。代码如下:
@RequestMapping("/requestParam")
//使用@RequestParam(”role_name")指定映射HTTP参数名称
public ModelAndView requestParam(@RequestParam("role_name") String roleName,String note){
System.out.println("roleName=>"+roleName);
System.out.println("note=>"+note);
ModelAndView mv=new ModelAndView();
mv.setViewName("index");
return mv;
}
测试如图所示:
结果:
注意,如果参数被@RequestParam注解,那么默认的情况下还参数不能为空,如果为空则系统会抛出异常。如果希望允许它为空,那么要修改它的配置项required为false,比如下面代码:
@RequestParam("role_name",required=false) String roleName
设置required为false后,将允许参数为空。
3、使用URL传递参数
一些网站使用URL的形式传递参数,这符合RESTFul风格,对于一些业务比较简单的应用是非常常见的,比如获取一个角色的信息,这个时候也许我们希望的是把URL写作/params/getRole/1,其中1就是一个参数,它代表的是角色编号,只是它在URL中传递,这时候就需要@RequestMapping和@PathVariable两个注解共同协作完成,代码如下:
@RequestMapping("/getRole/{id}")
//注解@PathVariable表示从URL的请求地址中获取参数
public ModelAndView pathVariable(@PathVariable("id") Long id){
Role role=roleService.getRole(id);
ModelAndView mv=new ModelAndView();
//绑定数据模型
mv.addObject(role);
//设置为JSON视图
mv.setView(new MappingJackson2JsonView());
return mv;
}
4、传递JSON参数
有时候参数的传递还需要更多的参数,比如除了查看角色名称和备注,查询可能还需要分页参数,这也是十分常见的场景,对于查询参数,假设还有开始行start和限制返回大小的limit,那么我们就可以设置一个PageParams类来传递。代码如下:
package com.ssm.example1.pojo;
public class PageParams {
private int start;
private int limit;
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
}
那么RoleParams也需要相应的进行一些改变:
package com.ssm.example1.pojo;
public class RoleParams {
private String roleName;
private String note;
private PageParams pageParams=null; //分页参数
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
这样查询参数和分页参数都可以传递了,那么客户端需要怎么传递呢?首先写一段JavaScript代码来模拟这个过程,往表单插入一段JavaScript代码,代码如下:
<script src="https://code.jquery.com/jquery-3.2.0.js">
$(document).ready(function () {
//JSON参数和类RoleParams一一对应
var data={
//角色查询参数
roleName:'role',
note:'note',
//分页参数
pageParams:{
start:1,
limit:20
}
}
//Jquery的post请求
$.post({
url:"./params/findRoles.do",
//此处需要告知传递参数类型为JSON,不能缺少
contentType:"application/json",
//将JSON转化为字符串传递
data:JSON.stringify(data),
//成功后的方法
success:function (result) {
}
})
})
</script>
这样设置之后就可以使用Spring MVC提供的注释@RequestBody接收参数,代码如下:
@RequestMapping("findRoles")
public ModelAndView findRoles(@RequestBody RoleParams roleParams){
List<Role> roleList=roleService.findRoles(roleParams);
ModelAndView mv=new ModelAndView();
//绑定数据模型
mv.addObject(roleList);
//设置为JSON视图
mv.setView(new MappingJackson2JsonView());
return mv;
}
这样Spring MVC把传递过来的参数转化为POJO,就可以接受对应JSON的参数了。
5、接收列表数据和表单序列化
在一些厂家中,如果要一次性删除多个角色,那么肯定是想将一个角色编号的数组传递给后台,或需要新增角色,甚至同时增加多个角色,无论如何都要用到Java的集合或者数组。Spring MVC也对这样的场景做了支持,我们就以删除多个角色为例,显然你希望传递一个角色编号的数组给后台处理,通过JavaScript模仿传递角色数组给后台,代码如下:
<script src="https://code.jquery.com/jquery-3.2.0.js">
$(document).ready(function () {
//删除角色数组
var idList=[1,2,3];
//JQuery的post请求
$.post({
url:"./params/delectRoles.do",
data:JSON.stringify(idList),
contentType:"application/json",
success:function (result) {
}
})
})
</script>
通过JSON的字符串将参数传递到后台,这个时候就可以写RequestMapping方法了。代码如下:
@RequestMapping("/delectRoles")
public ModelAndView deleteRoles(@RequestBody List<Long> idList){
ModelAndView mv=new ModelAndView();
int total=roleService.deleteRoles(idList);
//绑定数据模型
mv.addObject("total",total);
//设置为JSON视图
mv.setView(new MappingJackson2JsonView());
return mv;
}
通过表单序列化也可以将表单数据转化为字符串传递给后台,因为一些隐藏表单需要一定的计算,所以我们也需要在用户点击提交按钮后,通过序列化去提交表单,代码如下:
<script type="text/javascript">
$(document).ready(function () {
$("#commit").click(function () {
var str=$("form").serializeToString();
//提交表单
$.post({
url:"./params/commonParamPojo2.do",
data:$("form").serializeToString(),
//成功后的方法
success:function () {
}
})
})
})
</script>