SpringMVC 提交参数的方式和注解详述
一、四种接收提交参数的方式
1. 方法参数直接接收表单域的值。
简单的表单如下:
<form action="${pageContext.request.contextPath}/submit" method="POST"> <input type="text" name="id" /> <input type="text" name="name" /> <input type="submit" value="提交" /> </form> 复制代码
接收时直接指定参数名称为表单域名:
@RequestMapping("/submit") public String submit(String name, String id){ System.out.println(id); System.out.println(name); return "test"; } 复制代码
2. 使用最初的HttpServletRequest对象的getParameter方法来获取值
@RequestMapping("/submit") public String submit(HttpServletRequest request){ System.out.println(request.getParameter("id")); System.out.println(request.getParameter("name")); return "test"; } 复制代码
3. 用bean来接收
准备一个bean,其中setter/getter可以部分跟对应参数对应。
public class Tag { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Tag [id=").append(id) .append(", name=").append(name) .append("]"); return builder.toString(); } } 复制代码
然后接收的时候:
@RequestMapping("/submit") public String submit(Tag tag){ System.out.println(tag); return "test"; } 复制代码
4. 通过发送JSON数据的方式提交,接收仍是bean形式
<script type="text/javascript" src="i/javascript/jquery-latest.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#button").click(function(){ // json数据 var data = {id:$("#id").val(),name:$("#name").val()}; $.ajax({ type:"POST", url:"${pageContext.request.contextPath}/submit.html", data:data }); }); }); </script> 复制代码
接收使用bean,同3
@RequestMapping("/submit") public String submit(Tag tag){ System.out.println(tag); return "test"; } 复制代码
二、多表单域接收方式
1. 方法参数数组方式
表单:
<form action="${pageContext.request.contextPath}/submit.html" method="POST"> <input type="text" name="id" /> <input type="text" name="name" /> <input type="text" name="id" /> <input type="text" name="name" /> <input type="submit" id="button" value="提交" /> </form> 复制代码
接收:
@RequestMapping("/submit") public String submit(String[] id, String[] name){ for(int i=0; i< id.length; i++){ System.out.println(id[i]); System.out.println(name[i]); } return "test"; } 复制代码
2. 用BeanList方式接收
表单:
<form action="${pageContext.request.contextPath}/submit.html" method="POST"> <input type="text" name="tags[0].id" /> <input type="text" name="tags[0].name" /> <input type="text" name="tags[1].id" /> <input type="text" name="tags[1].name" /> <input type="submit" id="button" value="提交" /> </form> 复制代码
要准备一个Bean的List类:
import java.util.List; public class TagList { private List<Tag> tags; public TagList(List<Tag> tags) { this.tags = tags; } public TagList() {} public List<Tag> getTags() { return tags; } public void setTags(List<Tag> tags) { this.tags = tags; } } 复制代码
接收:
@RequestMapping("/submit") public String submit(TagList tags){ System.out.println(tags.getTags()); return "test"; } 复制代码
三、接收参数时各种常见注解说明
@RequestBody
用在方法上,意义是会使用系统配置的HttpMessageConverter来对请求数据body部分进行解析。然后再把解析后的数据对象提供到方法参数上。
@RequestBody会根据Content-Type来分辨需要处理的内容:
常用于:application/json或application/xml等。
不能处理 multipart/form-data。
默认的application/x-www-form-urlencoded用不用@RequestBody没有关系。
@RequestParam
用于参数上,给参数标识绑定的提交值。比起Request.getParameter()会多做一步将值转换成简单类型。
其属性value指代参数域名称,而required指示是否必须传值,如果required=false则在不传值情况下给参数赋值null。
实际上在提交参数是简单类型的情况下可以忽略该注解,以下两段代码几乎的等同的:
@RequestMapping("/submit") public String submit( @RequestParam(value="id") int req_id, @RequestParam(value="name") String req_name){ System.out.println(req_id); System.out.println(req_name); return "test"; } 复制代码
@RequestMapping("/submit") public String submit(String id, String name){ System.out.println(id); System.out.println(name); return "test"; } 复制代码
如果用@RequestMapping注解的参数是int基本类型,但是required=false,这时如果不传参数值会报错(bad request (400)),因为不传值会赋值为null给int,这是不允许的。解决这个问题的方法是:用包装类型代替基本类型,如使用Integer代替int。
@ModelAttribute
如果用于Controller的方法上,那么通常是当此Controller的每个方法执行前执行,用于提前处理或者给request增加属性等。
如果用于方法的参数上面,有两种情况:
如果还有一个对应使用了@ModelAttribute注解的方法,或者是@SessionAttributes注解的SESSION值,那么这个参数会是该方法返回的对象。
如果没有对应的方法,那么就是从表单提交或者URL中获取数据对象,实际上不加@ModelAttribute注解效果也一样的。
@RequestMapping("/submit") public String submit(@ModelAttribute Tag tag){ System.out.println(tag); return "test"; } 复制代码
@PathVariable
很方便取得URL的中的值,如:
@Controller @RequestMapping("/test/{testId}") public class TestController { @RequestMapping("/method/{deepId}") public void justdoit(@PathVariable String testId, @PathVariable String deepId) { //... } } 复制代码
@RequestHeader
取得请求头里面的某项信息:
@RequestMapping("/submit") public String submit(@RequestHeader("User-Agent") String referer){ System.out.println(referer); return "test"; } 复制代码
@SessionAttributes
类级别的注解,作用是注明该Controller所使用的一个SESSION的key,该SESSION会在ModelMap参数里面保存,并且可以从里面使用。如果需要删除该SESSION值,那么得从参数里面传入SessionStatus并调用其setComplete方法。
@Controller @SessionAttributes("testSession") public class PostController extends BaseController { @RequestMapping("/test") public String index(ModelMap modelMap) { modelMap.addAttribute("testSession", new Date()); return "test"; } @RequestMapping("/submit") public String submit(ModelMap modelMap, SessionStatus sessionStatus){ if(modelMap.containsAttribute("testSession")){ System.out.println(modelMap.get("testSession")); sessionStatus.setComplete(); } return "test"; } } 复制代码
@CookieValue
取特定cookie值
@RequestMapping("/submit") public String submit(@CookieValue("JSESSIONID") String cookie){ System.out.println(cookie); return "test"; } 复制代码
以上是SpringMVC的提交参数获取方式,其实我们还可以直接通过Servlet的各种API来取得相同的数据;这里有个建议就是如果一个项目中使用了一种获取的模式,就一直用相同的方式,会更规范和容易理解。
作者:jake
链接:https://juejin.cn/post/7025858242664202247