常见的一个web服务,如何获取请求参数?java
通常最多见的请求为GET和POST,get请求的参数在url上能够获取,post请求参数除了url上还有可能在表单中,文件上传时,获取方式又和通常的参数获取不同web
本篇则主要集中在不一样请求方式下,获取参数的使用姿式ajax
首先须要搭建一个后端的请求,为了快速演示spring
利用spring-boot建立了一个机器简单的工程,依赖版本 1.5.4.RELEASE
后端
get请求参数,通常都是直接挂在请求的url上,因此获取这些参数仍是比较简单的spring-mvc
这个能够说是最基本最多见的的方式了,javax.servlet.ServletRequest#getParameter
来获取对应的参数,下面各处一个实例mvc
@RestController @RequestMapping(path = "webs/demo") public class DemoController { @RequestMapping(path = "req1") public String req1(HttpServletRequest request) { String user = request.getParameter("user"); String password = request.getParameter("password"); return "req1 user: " + user + " pwd: " + password; } }
根据上面暴露的接口,咱们测试的case就很简单了app
http://127.0.0.1:8080/webs/demo/req1?user=小灰灰Blog&password=123456 ## 输出 req1 user: 小灰灰Blog pwd: 123456 http://127.0.0.1:8080/webs/demo/req1?user=小灰灰Blog ## 输出 req1 user: 小灰灰Blog pwd: null
说明curl
这是一个最基本的获取参数的方式,get,post请求都适用的,一般在filter,intercepter中也是能够经过HttpServletRequest
对象来获取请求参数ide
除了获取常见的请求参数以外,HttpServletRequest
能够获取请求头的完整信息
在一次请求的生命周期内,能够经过下面的方式获取Request对象(固然也能够获取response对象)
HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
直接给出case, 这个方法依然是放在上面的DemoController下面的
@RequestMapping(path = "req2") public String req2(String user, String password) { return "req2 user: " + user + " pwd: " + password; }
请求验证
http://127.0.0.1:8080/webs/demo/req2?user=%E5%B0%8F%E7%81%B0%E7%81%B0Blog&password=123456 ## 输出: req2 user: 小灰灰Blog pwd: 123456 http://127.0.0.1:8080/webs/demo/req2?password=123456 ## 输出: req2 user: null pwd: 123456 http://127.0.0.1:8080/webs/demo/req2?password=123456&User=blog ## 输出: req2 user: null pwd: 123456
注意:
一个疑问
上面的demo中Controller的方法参数都是String还好,若是将password改为int,会出现什么状况
代码稍做修改
@RequestMapping(path = "req2") public String req2(String user, int password) { return "req2 user: " + user + " pwd: " + password; }
实际测试
# case1 http://127.0.0.1:8080/webs/demo/req2?password=123456&user=blog ## 输出: req2 user: blog pwd: 123456 # case 2 http://127.0.0.1:8080/webs/demo/req2?password2=123456&user=blog ## 输出: 报错, Optional int parameter 'password' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type # case 3 http://127.0.0.1:8080/webs/demo/req2?password=abc&user=blog ## 输出:报错, "Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "abc""
结果说明
经过@RequestParam
注解获取参数的方式和上面的一种比较相似,case以下
@RequestMapping(path = "req3", method = RequestMethod.GET) public String req3(@RequestParam("user") String username, @RequestParam("password") String pwd) { return "req3 user: " + username + " pwd: " + pwd; }
测试case
# case1 http://127.0.0.1:8080/webs/demo/req3?password=123456&user=blog ## 输出: req3 user: blog pwd: 123456 # case2 http://127.0.0.1:8080/webs/demo/req3?password=123456 ## 输出:报错, Required String parameter 'user' is not presen
说明
@RequestParam(name = "user", required = false) String username
对于请求参数比较复杂的状况下,我比较喜欢这种使用姿式,管理起来方便简单
@Data public static class UserDO { String user; String password; } @RequestMapping(path = "req4", method = RequestMethod.GET) public String req4(UserDO userDO) { return "req4 userDO: " + userDO; }
测试case
# case1 http://127.0.0.1:8080/webs/demo/req4?password=123456&user=%E5%B0%8F%E7%81%B0%E7%81%B0Blog ## 输出: req4 userDO: DemoController.UserDO(user=小灰灰Blog, password=123456) # case2 http://127.0.0.1:8080/webs/demo/req4?password=123456 ## 输出: req4 userDO: DemoController.UserDO(user=null, password=123456)
说明
@ModelAttribute注解的方法,会优于Controller以前执行,通常更常见于向视图传输数据使用,此处不详细展开,正常来说,专门的获取参数不太会用这这种方式来玩
Path参数,专指的是请求路径的参数,如
http://127.0.0.1:8080/webs/demo/req4?password=123456
上面这个url中,password是咱们传统意义上的请求参数,其中path参数则是指其中 req4
, demo
这种path路径中的一环;对此,最多见的一个case就是常见的博客中,如开源中国的一个博客连接
https://my.oschina.net/u/566591/blog/1601400
通常path参数的获取方式以下
@RequestMapping(path = "req6/{user}/info") public String req6(@PathVariable(name = "user") String user) { return "req6 user: " + user; }
测试case
# case1 http://127.0.0.1:8080/webs/demo/req6/blog/info?user=haha ## 输出:req6 user: blog # case2 http://127.0.0.1:8080/webs/demo/req6/blog?user=haha ## 输出: 404 # case3 http://127.0.0.1:8080/webs/demo/req6/info?user=haha ## 输出: 404
注意:
POST请求参数,更多的是看提交表单参数是否能够获取到,以及如何获取,主要的手段依然是上面几种方式,下面验证下是否ok
测试case,能够借助curl来实现post请求
# case1 curl -d "user=小灰灰Blog&password=123456" "http://127.0.0.1:8080/webs/demo/req1" ## 输出: req1 user: 小灰灰Blog pwd: 123456 # case2 curl -d "user=小灰灰Blog" "http://127.0.0.1:8080/webs/demo/req1?password=123456" ## 输出:req1 user: 小灰灰Blog pwd: 12345 # case3 curl -d "user=小灰灰Blog" "http://127.0.0.1:8080/webs/demo/req1?user=greyBlog" ## 输出:req1 user: greyBlog pwd: null
curl也能够换成js请求测试方式
var formData = new FormData(); formData.append("user", "小灰灰Blog"); $.ajax({ url: 'http://127.0.0.1:8080/webs/demo/req1?password=123456', type: 'post', cache: false, data: formData, processData: false, contentType: false });
说明
几个测试demo以下
# case 1 curl -d "user=小灰灰Blog&password=123456" "http://127.0.0.1:8080/webs/demo/req2" ## 输出: req2 user: 小灰灰Blog pwd: 123456 # case 2 curl -d "password=123456" "http://127.0.0.1:8080/webs/demo/req2" ## 输出:req2 user: null pwd: 123456 # case 3 curl -d "password=123456" "http://127.0.0.1:8080/webs/demo/req2?user=blog" ## 输出: req2 user: blog pwd: 123456
基本上使用姿式和get没什么区别
# case 1 curl -d "password=123456&user=blog" "http://127.0.0.1:8080/webs/demo/req3" ## 输出: req3 user: blog pwd: 123456 # case 2 curl -d "password=123456" "http://127.0.0.1:8080/webs/demo/req3?user=blog" ## 输出: req3 user: blog pwd: 123456 # case 3 curl -d "password=123456&user=blog" "http://127.0.0.1:8080/webs/demo/req3?password=900" ## 输出:req3 user: blog pwd: 900,123456
注意
## case1 curl -d "password=123456&user=blog" "http://127.0.0.1:8080/webs/demo/req4?password=900" ## 输出 req4 userDO: DemoController.UserDO(user=blog, password=900,123456) ## case2 curl -d "password=123456&user=blog" "http://127.0.0.1:8080/webs/demo/req4" ## 输出 req4 userDO: DemoController.UserDO(user=blog, password=123456) ## case3 curl -d "password=123456" "http://127.0.0.1:8080/webs/demo/req4" ## 输出 req4 userDO: DemoController.UserDO(user=null, password=123456)
这种方式不区分get,post,因此彻底复杂的交互接口,彻底能够考虑用bean的方式来定义请求参数
这个无法玩...
上传文件的支持,对于传统的spring-mvc来讲,可能须要一些添加一些相关配置,不在本文的范畴内,下面默认已经配置好
@RequestMapping(path = {"wx/upload", "wx/wx/upload"}, method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.OPTIONS}) @ResponseBody public String upload(HttpServletRequest request) { MultipartFile file = null; if (request instanceof MultipartHttpServletRequest) { file = ((MultipartHttpServletRequest) request).getFile("image"); } if (file == null) { throw new IllegalArgumentException("图片不能为空!"); } return "success"; }
简单来讲,主要是利用HttpServletRequest
来获取上传的文件
注意:
MultipartHttpServletRequest
, 此时调用方若是不传参数,会被异常拦截(能够经过@ControllerAdvice来拦截全局异常)((MultipartHttpServletRequest) request).getFile(xxx)
来获取指定名的上传文件方式 | 注意事项 |
---|---|
HttpServletRequest获取参数 | 最多见通用 |
方法参数与请求参数同名 | 注意参数名统一,注意类型一致,尽可能不用非包装基本类型 |
@RequestParam注解 | 同上,可注解内指定http参数名 |
Bean方式 | 定义一个bean,会将同名的http参数赋值进去,推荐 |
@PathVariable 注解 | 请求url参数 |
使用MultipartHttpServletRequest
来获取上传的文件,固然也能够获取基本的请求参数
尽信书则不如,已上内容,纯属一家之言,因本人能力通常,看法不全,若有问题,欢迎批评指正