1、无论是哪种请求(GET、POST、PUT、DELETE)都能通过如下方式获取携带在URL上的参数

URL:host:port/webapp/address?param=value&..
Map<String, String[]> requestParameterMap = request.getParameterMap();

这种获取参数的方式而且可以获取多次,也就是在调用Service之前或者之后都可以调用 request的方法获取参数,而且参数的值是和以前完全一样的。

 

2、POST、PUT 请求方式是通过请求体发送参数的,所以我们如何想要获取请求体中的参数使用request.getParameterMap(); 是不可行的,它只能获取 URL上的参数,如何获取请求体的参数呢,请求体的参数都是放在request的输入流当中,只要读流,同样输入流里也不会有URL携带的参数,使用如下方式:

try{
if(request.getMethod().toLowerCase().equals("put")){
InputStream is = request.getInputStream();
byte[] buffer = new byte[1024];
StringBuffer rs = new StringBuffer();
int len;
while ( (len = is.read(buffer)) != -1 ){
rs.append(new String(buffer,0,len));
}
System.out.println(rs);
}
}catch (Exception e){
e.printStackTrace();
}

但是他有一个很大的缺陷就是流只能读一次,因为读流的过程中index一直在移动,然而又不能reset,所以读完了之后就没有了,而且读完之后再去读都可能是 stream is closed. 所以一般如果是手动通过流的方式获取参数,得到参数之后应该把它放在 request.setAttribute 里面,方便下次获取,当然也可以使用 ThreadLocal,这样就可以到处使用。

 

3、Spring @RequestBody 可以帮我们从流中获取参数,但是他不会从URL中获取参数,如果需要从URL中获取参数应该是 @Param , 如果是 URL的address中有参数,如 webapp/{item}/list 需要获取 item这个参数的值应该是 @PathVariable 。

 

4、因为系统中不想有太多的代码,所以我们都是使用 request.getParameterMap(); 来替代 @Param但是 request.getParameterMap(); 有个很大的缺点,那就是获取的值的数据类型都是字符串,理论上URL携带的参数都应该都是字符串。可是如果你使用Spring的注解则可以自动转换对应的参数,尤其是使用 @RequestBody Map<String,Object> params 的时候,里面的参数类型是自动判断的,比如前端传来的 {"status":1} 和 {"status":"1"} 二者是不同的,前者被解析为Integer,后者则是 String,那么在我们使用Java 的 equals 方法时要注意,因为 首先判断的就是数据类型。