1.1通过ServletAPI获取
SpringMVC封装的就是原生的servlet
我们进行测试如下所示:
package com.rgf.controller.service; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request){ String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:"+username+",password:"+password); return "success"; } }
我们的登陆页面如下所示:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>index.html</h1> <a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br> <a th:href="@{/abc}">测试@RequestMapping注解的value属性</a> <form th:action="@{/hello}" method="post"> <input type="submit" value="测试@RequestMapping注解的method属性"> </form> <a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br> <a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br> <a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br> <br> <form th:action="@{/param/servletAPI}" method="post"> 用户名: <input type="text" name="username"><br> 密码: <input type="password" name="password"><br> 提交: <input type="submit" value="登录"><br> </form> <a th:href="@{/param/servletAPI}"></a> </body> </html>
点击登录之后,即会跳转到成功界面。
同时我们的控制台会进行输出:username:admin,password:123456
1.2通过控制器方法的形参获取请求参数和@RequestParam的使用
我们的页面如下所示:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>index.html</h1> <a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br> <a th:href="@{/abc}">测试@RequestMapping注解的value属性</a> <form th:action="@{/hello}" method="post"> <input type="submit" value="测试@RequestMapping注解的method属性"> </form> <a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br> <a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br> <a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br> <br> <form th:action="@{/param}" method="post"> 用户名: <input type="text" name="username"><br> 密码: <input type="password" name="password"><br> 提交: <input type="submit" value="登录"><br> </form> <a th:href="@{/param/servletAPI}"></a> </body> </html>
package com.rgf.controller.service; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request){ String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:"+username+",password:"+password); return "success"; } @RequestMapping("/param") public String getParam(String username,String password){ return "success"; } }
我们进行如下界面:
我们点击登陆之后,会跳转到成功界面, 此时控制台会进行输出:
username:root,password:123456
当请求参数的名字和控制器方法的形参名字不一致的时候,如果继续获取的话,控制台会输出为null.面对这种情况,我们需要进行手动添加。
我们需要利用@RequestParam标签:其下有三个属性
我们将界面修改如下所示:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>index.html</h1> <a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br> <a th:href="@{/abc}">测试@RequestMapping注解的value属性</a> <form th:action="@{/hello}" method="post"> <input type="submit" value="测试@RequestMapping注解的method属性"> </form> <a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br> <a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br> <a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br> <br> <form th:action="@{/param}" method="post"> 用户名: <input type="text" name="name"><br> 密码: <input type="password" name="password"><br> 提交: <input type="submit" value="登录"><br> </form> <a th:href="@{/param/servletAPI}"></a> </body> </html>
此时找不到,我们将匹配的方法修改如下所示:
package com.rgf.controller.service; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request){ String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:"+username+",password:"+password); return "success"; } @RequestMapping("/param") public String getParam(@RequestParam("userName") String username, String password){ return "success"; } }
此时即可匹配上。
我们查看required这个属性:
package com.rgf.controller.service; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request){ String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:"+username+",password:"+password); return "success"; } /** * required默认为true,即value所对应的参数必须传输 * @param username * @param password * @return */ @RequestMapping("/param") public String getParam(@RequestParam(value = "userName",required = true) String username, String password){ return "success"; } }
当我们不传username,如下所示:
则会报错400.
如果required属性为false的话,则不会报错。
而对于最后一个属性:defaultValue,如果required默认值为true,但是没有传入进来,则会使用此时设置的defaultValue=hello的值。
我们继续采用拼接的网址:
我们发现此时不会报错,查看控制台输出的信息为如下:
username:Hello,password:123
此时无论required的值为true或者false都不影响跳转到成功界面,如果传了,则值为传输过来的值,如果未传,则值为默认值。
总结如下所示:
package com.rgf.controller.service; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * 3.@RequestParam:将请求参数和控制器的方法的形参绑定 * @RequestParam注解的三个属性:value、required、defaultValue * value:设置和形参绑定的请求参数的名字 * required:设置是否必须传输value所对应的请求参数, * 默认值为true,表示value所对应的请求参数必须传输,否则页面报错: * 400 -Required String parameter 'xxx' is not present * 若设置为false,则表示value所对应的请求参数不是必须传输,若未传输。则形参值为null * defaultVaule:设置当没有传输value所对应的请求参数时,为形参设置的默认值,此时和required属性值无关 * */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request){ String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:"+username+",password:"+password); return "success"; } /** * required默认为true,即value所对应的参数必须传输 * @param username * @param password * @return */ @RequestMapping("/param") public String getParam(@RequestParam(value = "userName",required = true,defaultValue = "Hello") String username, String password){ return "success"; } }
1.3@RequestHeader和@CookieValue
我们查看该页面的referer如下所示:
我们利用如下所示:
package com.rgf.controller.service; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * 3.@RequestParam:将请求参数和控制器的方法的形参绑定 * @RequestParam注解的三个属性:value、required、defaultValue * value:设置和形参绑定的请求参数的名字 * required:设置是否必须传输value所对应的请求参数, * 默认值为true,表示value所对应的请求参数必须传输,否则页面报错: * 400 -Required String parameter 'xxx' is not present * 若设置为false,则表示value所对应的请求参数不是必须传输,若未传输。则形参值为null * defaultVaule:设置当没有传输value所对应的请求参数时,为形参设置的默认值,此时和required属性值无关 *4.@RequestHeader:将请求头信息和控制器方法的形参绑定 *5.@CookieValue:将cookie数据和控制器方法的形参绑定 */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:" + username + ",password:" + password); return "success"; } /** * required默认为true,即value所对应的参数必须传输 * * @param username * @param password * @return */ @RequestMapping("/param") public String getParam( @RequestParam(value = "userName", required = true, defaultValue = "Hello") String username, String password, @RequestHeader(value = "referer",required = true,defaultValue = "www.baidu.com") String referer ) { System.out.println("referer:" + referer); System.out.println("username:" + username + ",password:" + password); return "success"; } }
我们进行测试如下所示:
我们在网页输入为username:root,password:123。
我们进行提交请求的时候会携带请求头信息。
发现控制台输出为:
referer:http://localhost:63342/
username:root,password:123
如果其上没有进行提交,则输出referer:www.baidu.com
我们发现@RequestHeader的属性如下所示,与@RequestMapping的一致。
我们进行查看cookievalue.
如果我们使用原生的servlet,则会获取cookie的时候,使用request.getcookies,先获取所有的cookie对象,返回值是一个数组,我们需要进行 之后再通过getname获取键,再通过getValue获取值。如果要获取一个指定的cookie的值,再判断name是否相等。
如何创建一个cookie.
第一次获取session的时候,使用request.getsession来获取的。这个时候我们会检测我们当前的请求报文是否携带了一个jsessionid的cookie,如果没有的话,则在服务器中会创造一个jsessionID的cookie,并且会创造一个httpsession对象。然后把我们当前的session对象,把他们存储在服务器所维护的map集合里面。map集合用jsessionID作为键。jsessionID的cookie的值就是一个随机序列,把他作为键,sessionID作为值。再把cookie响应到浏览器。之后每一次发送请求向服务器的话,每次都会携带jsessionid的cookie。有了cookie之后,就可以获取cookie的值,也就是一个随机序列。在服务器所维护的map集合中,然后以随机序列作为键,来获取map的值。
我们通过如下方法进行测试:
package com.rgf.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * 1.@RequestMapping注解的位置 * @RequestMapping标识一个类:设置映射请求的请求路径的初始信息 * @RequestMapping标识一个方法:设置映射请求请求路径的具体信息 * 2.@RequestMapping注解的value属性 * 作用:通过请求的请求路径匹配请求 * value属性是数组类型,即当前浏览器所发送请求的请求路径匹配value属性中的任何一个值 * 则当前请求就会被注解所标识的方法进行处理 * 3.@RequestMapping注解的method属性 * 作用:通过请求的请求方式匹配请求 * method属性是RequestMethod类型的数组,即当前浏览器所发送请求的请求方式匹配method属性中的任何一种请求方式 *则当前请求就会被注解所标识的方法进行处理 * 若浏览器所发送的请求的请求路径和@RequestMapping注解value属性匹配,但是请求方式不匹配,此时页面报错:405-Request method 'XXX' not supported * 在@RequestMapping的基础上,结合请求方式的派生注解: * @GetMapping,@PostMapping,@DeleteMapping,@PutMapping * 派生注解没有method属性,仍然有value属性。 * 4.@RequestMapping注解的params属性(value和method匹配其中一个就可以,但是params必须携带且匹配,若为携带,则会报错400, * 意为当前请求的参数与真实的参数不匹配) * 作用:通过请求的请求参数匹配请求,即浏览器发送的请求的请求参数必须满足params属性的设置 * params可以使用四种表达式: * "param":表示当前所匹配请求的请求参数中必须携带param参数 * "!param":表示当前所匹配请求的请求参数中一定不能携带param参数 * "param=value":表示当前所匹配请求的请求参数中必须携带param参数且值必须为value * "param!=value":表示当前所匹配请求的请求参数中可以不携带param参数,若携带值一定不能为value * 若浏览器所发送的请求的请求路径和@RequestMapping注解value属性匹配,但是请求参数不匹配,此时页面报错: * 400-Parameter conditions "username" not met for actual request parameters; * 5.@RequestMapping注解的headers属性 * 作用:通过请求的请求头信息匹配请求,即浏览器发送的请求的请求头信息满足headers属性的设置 * 若浏览器所发送的请求的请求路径和@RequestMapping注解value属性匹配,但是请求头信息不匹配,此时页面报错:404-; * 6.SpringMVC支持ant风格的路径 * 在@RequestMapping注解的value属性值中设置一些特殊字符 * ?:表示任意的单个字符(不包括?) * *:任意个数的任意字符(不包括?和/) * **:任意层数的任意目录,注意使用方式只能将**写在双斜线中,前后不能有任何的其他字符 */ //@RequestMapping("/test") @Controller public class TestRequestMappingController { //此时控制器方法所匹配的请求的请求路径为/test/hello @RequestMapping(value = {"/hello","/abc"}, method ={RequestMethod.POST,RequestMethod.GET}, params = {"username","!password","age=20","gender!=男"}, headers={"referer"} ) public String hello(){ return "index"; } @RequestMapping("/a?a/test/ant") public String testAnt(){ return "success"; } @RequestMapping( "/a*a/test/ant") public String testAnttwo(){ return "success"; } @RequestMapping( "/**/test/ant") public String testAntthree(){ return "success"; } @RequestMapping("/param/servletAPI") public String getParamByServletAPI(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"; } }
我们利用该注解如下所示:
package com.rgf.controller.service; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * 3.@RequestParam:将请求参数和控制器的方法的形参绑定 * @RequestParam注解的三个属性:value、required、defaultValue * value:设置和形参绑定的请求参数的名字 * required:设置是否必须传输value所对应的请求参数, * 默认值为true,表示value所对应的请求参数必须传输,否则页面报错: * 400 -Required String parameter 'xxx' is not present * 若设置为false,则表示value所对应的请求参数不是必须传输,若未传输。则形参值为null * defaultVaule:设置当没有传输value所对应的请求参数时,为形参设置的默认值,此时和required属性值无关 *4.@RequestHeader:将请求头信息和控制器方法的形参绑定 *5.@CookieValue:将cookie数据和控制器方法的形参绑定 */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:" + username + ",password:" + password); return "success"; } /** * required默认为true,即value所对应的参数必须传输 * * @param username * @param password * @return */ @RequestMapping("/param") public String getParam( @RequestParam(value = "userName", required = true, defaultValue = "Hello") String username, String password, @RequestHeader(value = "referer",required = true,defaultValue = "www.baidu.com") String referer, @CookieValue(value = "JSESSIONID",required = true,defaultValue = "") String jsessionId ) { System.out.println("referer:" + referer); System.out.println("jsessionId:" + jsessionId); System.out.println("username:" + username + ",password:" + password); return "success"; } }
我们需要先访问创建session的方法。我们访问:localhost:8080/SpringMVC/param/servletAPI.
访问成功之后,会出现setCookie.JSESSIONID=XXXXXXXX;Path=/SpringMVC;HttpOnly
访问成功之后,我们再访问界面将名字和密码输入,之后查看控制台所输出的:
referer:http://localhost:63342/
JSESSIONID:XXXxxxxx
username:root,password:123456
从此就会携带JSESSIONID的cookie.
1.4通过pojo获取请求参数
在控制器方法的形参位置设置一个实体类类型的形参,只要保证实体类中的属性和我们的请求参数的名字一样,我们就可以直接把我们当前的请求参数的值封装到实体类类型的形参中。
我们创建pojo包下面的User类:
如下所示:
package com.rgf.pojo; public class User { private Integer id; private String username; private String password; 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 User(Integer id, String username, String password) { this.id = id; this.username = username; this.password = password; } public User() { } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; } }
我们创建我们的画面路径:(index.html)
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>index.html</h1> <a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br> <a th:href="@{/abc}">测试@RequestMapping注解的value属性</a> <form th:action="@{/param/pojo}" method="post"> 用户名: <input type="text" name="username"><br> 密码: <input type="password" name="password"><br> 提交: <input type="submit" value="登录"><br> </form> <a th:href="@{/param/servletAPI}"></a> </body> </html>
我们在控制器方法里面进行如下所示:
package com.rgf.controller.service; import com.rgf.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * 3.@RequestParam:将请求参数和控制器的方法的形参绑定 * @RequestParam注解的三个属性:value、required、defaultValue * value:设置和形参绑定的请求参数的名字 * required:设置是否必须传输value所对应的请求参数, * 默认值为true,表示value所对应的请求参数必须传输,否则页面报错: * 400 -Required String parameter 'xxx' is not present * 若设置为false,则表示value所对应的请求参数不是必须传输,若未传输。则形参值为null * defaultVaule:设置当没有传输value所对应的请求参数时,为形参设置的默认值,此时和required属性值无关 *4.@RequestHeader:将请求头信息和控制器方法的形参绑定 *5.@CookieValue:将cookie数据和控制器方法的形参绑定 */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:" + username + ",password:" + password); return "success"; } /** * required默认为true,即value所对应的参数必须传输 * * @param username * @param password * @return */ @RequestMapping("/param") public String getParam( @RequestParam(value = "userName", required = true, defaultValue = "Hello") String username, String password, @RequestHeader(value = "referer",required = true,defaultValue = "www.baidu.com") String referer, @CookieValue(value = "JSESSIONID",required = true,defaultValue = "") String jsessionId ) { System.out.println("referer:" + referer); System.out.println("jsessionId:" + jsessionId); System.out.println("username:" + username + ",password:" + password); return "success"; } @RequestMapping("/param/pojo") public String getParamByPojo(User user){ System.out.println(user); return "success"; } }
我们此时在如下框输入:
我们点击登录之后会在控制台发现输出如下所示:
User{id=null,username='admin',password='123456'}
获取请求参数总结如下所示:
package com.rgf.controller.service; import com.rgf.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * 3.@RequestParam:将请求参数和控制器的方法的形参绑定 * @RequestParam注解的三个属性:value、required、defaultValue * value:设置和形参绑定的请求参数的名字 * required:设置是否必须传输value所对应的请求参数, * 默认值为true,表示value所对应的请求参数必须传输,否则页面报错: * 400 -Required String parameter 'xxx' is not present * 若设置为false,则表示value所对应的请求参数不是必须传输,若未传输。则形参值为null * defaultVaule:设置当没有传输value所对应的请求参数时,为形参设置的默认值,此时和required属性值无关 *4.@RequestHeader:将请求头信息和控制器方法的形参绑定 *5.@CookieValue:将cookie数据和控制器方法的形参绑定 *6.通过控制器方法的实体类类型的形参获取请求参数,需要在控制器方法的形参位置设置实体类类型的形参, *要保证实体类中的属性的属性名和咱们的请求参数的名字一致,可以通过实体类类型的形参获取请求参数 */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:" + username + ",password:" + password); return "success"; } /** * required默认为true,即value所对应的参数必须传输 * * @param username * @param password * @return */ @RequestMapping("/param") public String getParam( @RequestParam(value = "userName", required = true, defaultValue = "Hello") String username, String password, @RequestHeader(value = "referer",required = true,defaultValue = "www.baidu.com") String referer, @CookieValue(value = "JSESSIONID",required = true,defaultValue = "") String jsessionId ) { System.out.println("referer:" + referer); System.out.println("jsessionId:" + jsessionId); System.out.println("username:" + username + ",password:" + password); return "success"; } @RequestMapping("/param/pojo") public String getParamByPojo(User user){ System.out.println(user); return "success"; } }
1.5解决获取请求参数的乱码问题
解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须在web.xml中进行注册。
不可以使用request.servletAPI的这种方法,因为当前设置编码的代码有一种要求,在设置编码之前一定不能够获取任意的请求参数。只要获取,设置的编码就没有任何功能。
我们输入如下所示:
我们进行登录之后发现在控制台输出如下所示:
User{id=null,username='???',password='123456'} ,当前的请求方式为post.
我们将其修改为get:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>index.html</h1> <a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br> <a th:href="@{/abc}">测试@RequestMapping注解的value属性</a> <form th:action="@{/param/pojo}" method="get"> 用户名: <input type="text" name="username"><br> 密码: <input type="password" name="password"><br> 提交: <input type="submit" value="登录"><br> </form> <a th:href="@{/param/servletAPI}"></a> </body> </html>
此时点击登录之后我们查看控制台输出的:
User{id=null,username='张三',password='123456'},此时不再为乱码。
tomcat1.7,get的请求方式出现乱码的解决方法:
我们打开tomcat里面的conf文件夹下面的server.xml,找到设置端口号的地方如下:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
在tomcat7.0里面get和post都会有乱码,但是配置如下之后:
URIEncoding="UTF-8"。(get出现乱码的解决方法)
如果删掉之后,get也会出现乱码。
tomcat8.5里面,get方法是不会出现乱码的。
post方法出现乱码的解决办法:
我们在web.xml文件里面进行配置如下所示:
<!--配置Spring的编码过滤器 CharacterEncodingFilter 编码过滤器 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
我们来进行查看源码如下所示:
当前类的结构如下所示:
我们从中发现没有doFilter方法,在当前继承的过程中,我们对当前的doFilter方法进行了重写,重写之后调用了另外一个方法来实现了过滤。即为:doFilterInternal 。
我们从filter进行查看:
里面有doFilter方法,往上我们来看:
此时发现里面有doFilter.
我们发现此时已经进行了重写:
我们进行查看该方法:
protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String encoding = getEncoding(); if (encoding != null) { if (isForceRequestEncoding() || request.getCharacterEncoding() == null) { request.setCharacterEncoding(encoding); } if (isForceResponseEncoding()) { response.setCharacterEncoding(encoding); } } filterChain.doFilter(request, response); }
里面获取的encoding为:
这就是为什么我们在配置过滤器的时候设置的初始化参数为encoding。
同时我们进行查看forceEncoding。
public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) { Assert.hasLength(encoding, "Encoding must not be empty"); this.encoding = encoding; this.forceRequestEncoding = forceRequestEncoding; this.forceResponseEncoding = forceResponseEncoding; }
根据doFilterInternal方法,我们可以发现如果我们进行设置了encoding和forceEncoding,则会设置为我们所设置的编码方式。如果不进行设置的话,则会直接放行,仍然为默认的编码方式。同时,(如果只设置encoding初始化参数的时候,只会去设置请求的编码,不会去设置响应的编码)。如果全部要进行设置的话,则要将encoding和forceEncoding全部在配置文件里面进行设置。此种方式即可解决配置乱码。
本章总结如下:
package com.rgf.controller.service; import com.rgf.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; /** * 1.获取请求参数的方式: * 1.通过servletAPI获取 * 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数 * 2.通过控制器方法的形参获取 * 只需要在控制器方法的形参位置,设置一个形参,形参的名字要和请求参数的名字一致即可。 * 3.@RequestParam:将请求参数和控制器的方法的形参绑定 * @RequestParam注解的三个属性:value、required、defaultValue * value:设置和形参绑定的请求参数的名字 * required:设置是否必须传输value所对应的请求参数, * 默认值为true,表示value所对应的请求参数必须传输,否则页面报错: * 400 -Required String parameter 'xxx' is not present * 若设置为false,则表示value所对应的请求参数不是必须传输,若未传输。则形参值为null * defaultVaule:设置当没有传输value所对应的请求参数时,为形参设置的默认值,此时和required属性值无关 *4.@RequestHeader:将请求头信息和控制器方法的形参绑定 *5.@CookieValue:将cookie数据和控制器方法的形参绑定 *6.通过控制器方法的实体类类型的形参获取请求参数,需要在控制器方法的形参位置设置实体类类型的形参, *要保证实体类中的属性的属性名和咱们的请求参数的名字一致,可以通过实体类类型的形参获取请求参数 * 7.解决获取请求此参数的乱码问题 * 在web.xml中配置Spring的编码过滤器CharacterEncodingFilter */ @Controller public class TestParamController { @RequestMapping("/param/servletAPI") public String getParamByServlet(HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:" + username + ",password:" + password); return "success"; } /** * required默认为true,即value所对应的参数必须传输 * * @param username * @param password * @return */ @RequestMapping("/param") public String getParam( @RequestParam(value = "userName", required = true, defaultValue = "Hello") String username, String password, @RequestHeader(value = "referer",required = true,defaultValue = "www.baidu.com") String referer, @CookieValue(value = "JSESSIONID",required = true,defaultValue = "") String jsessionId ) { System.out.println("referer:" + referer); System.out.println("jsessionId:" + jsessionId); System.out.println("username:" + username + ",password:" + password); return "success"; } @RequestMapping("/param/pojo") public String getParamByPojo(User user){ System.out.println(user); return "success"; } }