积羽沉舟网

SpirngMVC获取请求参数

SpirngMVC获取请求参数

目录

1. 原生Servlet获取请求参数

2. 通过控制器方法的取请求参形参获取请求参数

3. @RequestParam

4. @ReuqestHeader

5. @CookieValue

6. 通过POJO获取请求参数

7. 解决获取请求参数的乱码问题


1. 原生Servlet获取请求参数

这里我们创建一个控制器,以及一个用于跳转成功的取请求参页面

@RequestMapping("/param")public String param(){ 	return "test_param";}
测试请求参数

测试请求参数

测试使用servletAPI获取请求参数
@Controllerpublic class ParamController { 		@RequestMapping("/testServletAPI")	// 形参位置的request表示当前请求	public String testServletAPI(HttpServletRequest request){ 		String username = request.getParameter("username");		String password = request.getParameter("password");		System.out.println("username:"+username+",password:"+password);		return "success";	}}

一开始去访问http://localhost:8080/springMVC/param这个地址,然后跳转到test_param页面,取请求参点击里面的取请求参超链接,携带参数跳转到success页面,取请求参这是取请求参用ServletAPI做到的,但是取请求参我们在SpringMVC中基本是不用这种方式来实现。

注:

我们在使用SpringMVC的取请求参时候,能不用原生API就不用,取请求参因为我们当前操作的取请求参数据,SpringMVC就已经帮助我们获取过了,取请求参而且它还会给我们提供更简单的取请求参方式让我们获取,没有必要使用原生的取请求参ServletAPI


2. 通过控制器方法的形参获取请求参数

既然我们不适用原生ServletAPI进行获取参数,当然,取请求参SpringMVC也有自己获取请求参数的取请求参方式

前端代码还是这样:

测试获取请求参数-->/testParam
@RequestMapping("/testParam")public String testParam(String username, String password){     System.out.println("username:"+username+",password:"+password);    return "success";}

那么我们还有一种情况,当前传过来有多个同名的请求参数,这个时候又要如何处理?

用户名: 
密码:
爱好: a b c
@RequestMapping("/testParam")public String testParam(String username,String password,String[] hobby){ 	System.out.println("username:"+username+",password:"+password+",hobby:"+ Arrays.toString(hobby));	return "success";}

这时候我们是用一个表单里面有爱好来测试多个同名的请求参数,这个是字符串数组形式的输出结果


现在我们来测试用字符串输出结果

@RequestMapping("/testParam")public String testParam(String username,String password,String hobby){ 	System.out.println("username:"+username+",password:"+password+",hobby:"+ hobby);	return "success";}

3. @RequestParam

我们之前是在方法里面的设置形参,然后让形参跟前端的请求参数名进行匹配,最终获得参数,但是如果前端的参数值和形参名不匹配会发生什么?

这时候我们把username改成user_name

用户名: 
密码:
爱好: a b c

方法这边的形参名还是用username来接收

@RequestMapping("/testParam")public String testParam(String username,String password,String hobby){ 	System.out.println("username:"+username+",password:"+password+",hobby:"+ hobby);	return "success";}

可以看到username并没有获取到,也就是说只要是请求参数名和形参名不一致,那就没办法获取值,那么此时就要用到一个注解——@RequestParam。

@RequestMapping("/testParam")public String testParam(      @RequestParam("user_name") String username,      String password,      String hobby){    System.out.println("username:"+username+",password:"+password+",hobby:"+ hobby);   return "success";}

这个注解的用处就是将请求参数和形参建立映射关系,那么这里就是将请求参数user_name和形参username对应,此时就可以获取到值了


4. @ReuqestHeader

这里要注意:@RequestParam、@ReuqestHeader、@CookieValue这三个注解所拥有的属性基本都是一模一样的,这三个注解都拥有value、required、defaultValue这三个属性,作用是一样的,只不过这三个属性所操作的内容不一样,比如说@RequestParam是将请求参数和形参进行建立映射关系,而@ReuqestHeader是将请求头信息与形参建立映射关系,@CookieValue是将Cookie与形参进行建立映射关系。


请求头信息也是键值对,所以这里可以通过@RequestHeader然后指定一个请求头的键,然后就可以将指定的请求头信息和形参进行绑定

@RequestMapping("/testParam")public String testParam(		@RequestParam(value = "user_name",required = false,defaultValue = "hehe") String username,		String password,		String hobby,		@RequestHeader("Host") String host		){ 	System.out.println("username:"+username+",password:"+password+",hobby:"+ hobby);	System.out.println("host:"+host);	return "success";}

那么此时会把请求头信息打印出来。

当然,里面还有required和defaultValue属性,当required为false时,如果没有请求头信息,则不处理,赋null值,如果为true则进行报错。

defaultValue属性,当没有请求头信息时,自动设置为我们自己设置的默认值。  

@RequestMapping("/testParam")public String testParam(		@RequestParam(value = "user_name",required = false,defaultValue = "hehe") String username,		String password,		String hobby,		@RequestHeader(value = "sayHaha",required = true,defaultValue = "Haha") String host		){ 	System.out.println("username:"+username+",password:"+password+",hobby:"+ hobby);	System.out.println("host:"+host);	return "success";}


5. @CookieValue

当去调用getSession方法的时候,就会创建一个键JSESSIONID的cookie。

@RequestMapping("/testServletAPI")// 形参位置的request表示当前请求public String testServletAPI(HttpServletRequest request){ 	HttpSession session = request.getSession();	String username = request.getParameter("username");	String password = request.getParameter("password");	System.out.println("username:"+username+",password:"+password);	return "success";}

由于是会话技术,生命周期是浏览器开启到浏览器关闭,所以只要是浏览器不关闭,cookie将一直存在。

由于我们是第一次访问getSession方法,Cookie是存在于当前的响应报文中

第一次执行getSession方法的时候,会去检测请求报文中是否携带JSESSIONID的Cookie,如果没有就说明在这一次的会话中,是第一次创建Session对象,所以就会去创建一个Session对象,然后将Session放在服务器所维护的Map集合中,并且去创建一个Cookie,这个Cookie的键是固定的,是JSESSIONID,值则是一个随机序列,然后还会将这个HttpSession对象存储到当前的服务器所维护的Map集合中,以JSESSIONID的Cookie的值,也就是这个随机序列,作为Map集合的键,把Session对象作为Map的值进行存储,存储在服务器内部,这时候再把Cookie响应到浏览器。所以说第一次去访问浏览器getSession方法的时候,JSESSIONID是会存在于响应报文中,从此之后将存在于请求报文中,因为Cookie就是这个工作原理。 

第一次JESSIONID存在于响应报文中

我们对页面进行刷新,这时候响应报文中已经没有了,存在于请求报文中。


此时的请求报文中也有携带Cookie

@RequestMapping("/testParam")public String testParam(      @RequestParam(value = "user_name",required = false,defaultValue = "hehe") String username,      String password,      String hobby,      @RequestHeader(value = "sayHaha",required = true,defaultValue = "Haha") String host,      @CookieValue("JSESSIONID") String JSESSIONID      ){    System.out.println("username:"+username+",password:"+password+",hobby:"+ hobby);   System.out.println("host:"+host);   System.out.println("JSESSIONID:"+JSESSIONID);   return "success";}

6. 通过POJO获取请求参数

有时候请求参数很多,比如说添加和修改功能等,将数据添加到数据库,那我们这些添加的数据就要对应数据库字段,而数据库同样对应实体类对象,所以说在页面中添加的数据,跟实体类对象属性也是一一对应。

这个时候SpringMVC又为我们提供了一种很简单的方式,也就是当表单里面的name跟实体类里面的属性对应,那么我们可以在形参位置去写实体类的形参,这个时候只要保证请求参数的名字,跟实体类中的属性名保持一致,就可以自动通过实体类对象收集这些请求参数。

用户名:
密码:
性别:男女
年龄:
邮箱:
public class User { 		private Integer id;	private String username;	private String password;	private Integer age;	private String sex;	private String email;	public User(Integer id, String username, String password, Integer age, String sex, String email) { 		this.id = id;		this.username = username;		this.password = password;		this.age = age;		this.sex = sex;		this.email = email;	}	public User() { 	}	public Integer getId() { 		return id;	}	public void setId(Integer id) { 		this.id = id;	}	public String getUsername() { 		return username;	}	public void setUsername(String username) { 		this.username = username;	}	public String getPassword() { 		return password;	}	public void setPassword(String password) { 		this.password = password;	}	public Integer getAge() { 		return age;	}	public void setAge(Integer age) { 		this.age = age;	}	public String getSex() { 		return sex;	}	public void setSex(String sex) { 		this.sex = sex;	}	public String getEmail() { 		return email;	}	public void setEmail(String email) { 		this.email = email;	}	@Override	public String toString() { 		return "User{ " +				"id=" + id +				", username='" + username + '\'' +				", password='" + password + '\'' +				", age=" + age +				", sex='" + sex + '\'' +				", email='" + email + '\'' +				'}';	}}
@RequestMapping("/testbean")public String testBean(User user){ 	System.out.println(user);	return "success";}

可以看到我们确实是接受到了,但是sex是乱码,出现乱码原因就是因为字符编码不一致而造成的


7. 解决获取请求参数的乱码问题

在我们设置编码之前,已经获取了请求参数,再设置编码,这样是没有任何作用的,那么处理这种请求参数乱码的问题有2种,一种是GET请求,一种是POST请求

我们先尝试一下将表单的method设置为get

可以看到,用GET请求并不会出现乱码的问题,这个问题是Tomcat造成的,也就是说GET请求造成的乱码是由Tomcat来处理的,我们需要去找Tomcat那边去找个配置文件server.xml

这里要注意,Tomcat8以上是不需要改的,没有URIEncoding="UTF-8"也会解析为这个编码。


那么我们前面也说了,如果是已经获取完请求参数,再设置编码,是没有用的,DispatcherServlet里面已经获取了请求参数,所以我们应该在DispatcherServlet获取请求参数之前设置编码 

那么是什么组件比Servlet执行更早的呢?

服务器中三大组件:监听器,过滤器,Servlet

监听器执行最早,然后是过滤器,最后是Servlet。
但是监听器是监听作用,监听ServletContext创建和销毁,所以这两个方法都是只执行一次。


过滤器,只要我们设置了过滤路径,访问的请求地址满足过滤路径,都会被过滤器进行过滤。 

通过过滤器设置编码,每一次请求都要经过过滤器进行处理,再交给DispatcherServlet处理,当然,这个过滤器我们也不用写,因为SpringMVC已经为我们提供好了。  

CharacterEncodingFilterorg.springframework.web.filter.CharacterEncodingFilterencodingUTF-8forceResponseEncodingtrueCharacterEncodingFilter/*

那么过滤器配置完了,我们再来试一下POST请求参数还会不会出现乱码问题

这时候不会出现了。  

未经允许不得转载:积羽沉舟网 » SpirngMVC获取请求参数