1.1. 请求路径映射
实际项目中我们要借助@RequestMapping注解定义映射路径。其注解应用位置
类定义处: 提供初步的请求映射信息。
方法定义处: 提供进一步的细分映射信息
@Controller
@RequestMapping("/")//spring-mvc-v1的/ 借助此注解定义映射关系,找到映射就能动态执行方法
public class HelloController {
public HelloController() {
System.out.println("HelloController.HelloController()");
}
@RequestMapping("doSayHello")//url对应的方法对象会存储到map
public ModelAndView doSayHello(){
//1.构建ModelAndView对象(作用:封装响应数据和视图信息)
ModelAndView mv=new ModelAndView();
//2.封装客户端页码要呈现的数据
mv.addObject("message","I'm Spring MVC");
//3.封装要呈现的页面视图信息
mv.setViewName("index");//此名字会交给视图解析器进行解析
return mv;//mvc底层会将modelandView中的model对象存储在请求作用域request.setAttribute()
}
}
1.1.1. 普通url映射
@RequestMapping(value={"/doSayHello", "/user/doSayWelcome"}):
多个URL路径可以映射到同一个处理器的功能处理方法。(多个url映射同一个方法)
@Controller
@RequestMapping("/req/")
public class RequestHandleController {
/**
* @RequestMapping告诉springmvc将方法返回值以字符串形式呈现
*
* @return
*/
@RequestMapping("doReqUrlMap01")
@ResponseBody
public String doReqUrlMap01(){
return "request url mapping请求url映射";
}
}
控制层写方法,do开头或with开头
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
*
* @author Administrator
*
*/
@Controller
@RequestMapping("/req/")
public class RequestHandleController {
/**
* @RequestMapping告诉springmvc将方法返回值以字符串形式呈现
*
* @return
*/
@RequestMapping({"doReqUrlMap01","widthReqUrlMap"})
@ResponseBody
public String doReqUrlMap01(){
return "request url mapping,请求url映射";
}
}
1.1.2. Rest风格url映射
REST即表述性状态传递(英文:Representational State Transfer,简称REST),是一种新的软件架构编码风格,是基于网络应用进行设计和开发的编码方式。可以降低开发的复杂度,提高程序的可伸缩性。例如:
@RequestMapping("/msg/{xxx}")
大括号里的内容相当于一个变量
只要前面/msg/一样,后面什么都行
请求的URL可以是“/msg/hello”或“/msg/welcome”
@RequestMapping("/msg/{id}/create"):
请求的URL可以是“/users/1/create”。
@RequestMapping("/msg/{mId}/topics/{tId}")
这样也是可以的,请求的URL可以是“/users/10/topics/12”。
说明:通过@PathVariable可以提取URI模板模式中的{×××}中的×××变量。
http://localhost:8080/项目名/doUpdate/1.do
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
*
* @author Administrator
*
*/
@Controller
@RequestMapping("/req/")
public class RequestHandleController {
/**
* Rest风格url映射
* 表述性状态传递
* @return
*/
@RequestMapping("doReqRestUrlMap{map}")
@ResponseBody
public String doReqRestUrlMap02(){
return "request rest url mapping";
}
}
2.1. 请求方式映射
2.1.1 请求方式限定
项目中Controller层对象的每个方法默认可以处理任意方式的请求,假如要指定控制层方法只能处理GET或只能处理POST请求,那该如何实现呢?
借助@RequestMapping注解中的method属性指定具体的请求处理方式,例如
@RequestMapping(value=”doSaveObj”,
method=RequestMethod.POST)
public String doSaveObject(Object obj){….}
知识点扩展:
1)@GetMapping 注解应用(定义的映射只能处理get请求)
2)@PostMapping 注解应用(定义的映射只能处理post请求)
2.1.2 请求方式组合
项目中还可在控制层方法上借助@RequestMapping注解中的method属性指定使用哪几种方式处理请求。
@RequestMapping(value=”doSaveObj”,
method={RequestMethod.POST,
RequestMethod.GET})
public String doSaveObject(Object obj){….}
<mvc:annotation-driven/>需要配置
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
*
* @author Administrator
*
*/
@Controller
@RequestMapping("/req/")
public class RequestHandleController {
/**
* 请求方式映射:如get,post请求等
* @return
*/
@RequestMapping(value="doReqMethodMap01",method={RequestMethod.POST,RequestMethod.GET})
@ResponseBody
public String doReqMethodMap01(){
return "requset rest method mapping";
}
@GetMapping("doReqMethodMap02")
@ResponseBody
public String doReqMethodMap02(){
return "requset rest get method mapping";
}
@PostMapping("doReqMethodMap03")
@ResponseBody
public String doReqMethodMap03(){
return "requset rest post method mapping";
}
}
3.1. 请求参数映射(重点)
3.1.1. 标准Servlet API(了解)
请求映射方法中可以直接使用ServletAPI 中的对象获取参数数据,例如
HttpServletRequest,HttpSession对象等,例如:
@RequestMapping(value="withRequest",method=RequestMethod.GET)
@ResponseBody
public String withRequest(HttpServletRequest request){
System. out .println(request.getRequestURI());
return "Obtainer 'foo' query parameter value
'"+request.getParameter("gid")+"'";
}
@RequestMapping("doReqParam01")
@ResponseBody
public String doReqParam01(HttpServletRequest request){
return "obtain parameter's value is "+request.getParameter("pageCurrent");
}
访问路径:http://localhost/spring-mvc-v1/req/doReqParam01.do?pageCurrent=2
提示:@ResponseBody注解作用:该注解作用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,使用情况:返回的数据不是Html标签的页面,而是其他数据格式的数据时,(如Json、xml,普通文本等)使用;
3.1.2 直接量对象(重点)
SpringMVC 请求一个控制层资源时,可以在对应方法中直接使用参数变量接收参数数据,但参数变量的类型建议为对象类型。
/**直接量(八种对象类型+String+Date)参数的获取*/
//此方法由DispatcherServlet调用
//此方法通过反射调用
//此方法调用参数时如何注入?SpringMVC底层基于参数名进行值的注入
@RequestMapping("doReqParam02")
@ResponseBody
public String doReqParam02(Integer pageCurrent){
return "obtain parameter's value is "+pageCurrent;
}
访问地址http://localhost/spring-mvc-v1/req/doReqParam02.do?pageCurrent=3
如果用int替换Integer那么不传值会报500
@RequestMapping("doReqParam02")
@ResponseBody
public String doReqParam02(@RequestParam Integer pageCurrent){
return "obtain parameter's value is "+pageCurrent;
}
注解修饰的变量必须给值不然会报400(客户端传递参数不对,不符合服务器端要求,服务器拒收)
@RequestMapping("doReqParam02")
@ResponseBody
public String doReqParam02(@RequestParam("page") Integer pageCurrent){
return "obtain parameter's value is "+pageCurrent;
}
http://localhost/spring-mvc-v1/req/doReqParam02.do?page=2
@RequestMapping("doReqParam02")
@ResponseBody
public String doReqParam02(@RequestParam(value="page",required=false) Integer pageCurrent){
return "obtain parameter's value is "+pageCurrent;
}
默认是true,false不写参数不会报400 http://localhost/spring-mvc-v1/req/doReqParam02.do
@RequestMapping("doReqParam02")
@ResponseBody
public String doReqParam02(@RequestParam(value="page",required=true) Integer pageCurrent){
return "obtain parameter's value is "+pageCurrent;
}
如果required=true,http://localhost/spring-mvc-v1/req/doReqParam02.do会报400
@RequestMapping("doReqParam02")
@ResponseBody
public String doReqParam02(String name,@RequestParam(value="page",required=false) Integer pageCurrent){
//spring mvc帮我们进行了字符转换
return "obtain parameter's value is "+pageCurrent+", name is "+name;
}
http://localhost/spring-mvc-v1/req/doReqParam02.do?page=3&name=liu
<mvc:annotation-driven/>需要配置
@RequestMapping("doReqParam03")
@ResponseBody
public String doReqParam03(Date birthday){
//请求可以直接将日期字符串注入给此对象
//springMVC默认可以处理的日期格式:yyyy/MM/ddd
return "obtain parameter's value is "+birthday;
}
http://localhost/spring-mvc-v1/req/doReqParam03.do?birthday=2008/12/12
@RequestMapping("doReqParam03")
@ResponseBody
public String doReqParam03(@DateTimeFormat(pattern="yyyy-MM-dd")Date birthday){
//请求可以直接将日期字符串注入给此对象
//springMVC默认可以处理的日期格式:yyyy/MM/ddd
//springMVC可以借助@DateTimeFormat注解处理指定格式,假如客户端请求中传递的日期格式不匹配,会出现400异常
return "obtain parameter's value is "+birthday;
}
http://localhost/spring-mvc-v1/req/doReqParam03.do?birthday=2008-12-12
<mvc:annotation-driven/>需要配置
@RequestMapping("doReqParam04")
@ResponseBody
//可变参数
public String doReqParam04(Integer...ids){
return "obtain parameter's value is "+ids;
}
http://localhost/spring-mvc-v1/req/doReqParam04.do?ids=1,2,3,4,5,6
运行结果
obtain parameter's value is [Ljava.lang.Integer;@f0e01f2
@RequestMapping("doReqParam04")
@ResponseBody
//可变参数
public String doReqParam04(Integer... ids){
//客户端传参数形式ids=200,222,302
return "obtain parameter's value is "+Arrays.toString(ids);
}
http://localhost/spring-mvc-v1/req/doReqParam04.do?ids=200,222,302
运行结果
obtain parameter's value is [200, 222, 302]
省去了如下代码
String str=request.getParameter("ids");
String []arr=str.split(",");
Integer[] it=new Integer[arr.length];
for(int i=0;i<arr.length;i++){
it[i]=Integer.parseInt(arr[i]);
}
3.1.3. Java bean对象(重点)
当请求中多个参数时可以通过在方法中定义多个参数接收参数数据,也可以利用一个javabean对象接收多个参数数据以简化多个参数变量的定义。使用对象接收数据,页面上传参数的值需要和实体类里属性的set方法一致。
package entity;
import java.io.Serializable;
import java.util.Date;
/**
* POJO:日志实体对象 封装系统的日志信息 实现序列化接口,便于网络传输
*/
public class SysLog implements Serializable {
private static final long serialVersionUID = -496934815638734874L;
private Integer id;
/**
* 操作用户
*/
private String username;
/**
* 执行的操作
*/
private String operation;
/**
* 执行这个操作的方法
*/
private String method;
/**
* 调用方法传入的参数
*/
private String params;
/**
* 方法的执行时间
*/
private Long time;
/**
* 用户的ip地址
*/
private String ip;
/**
* 这个日志的创建时间
*/
private Date createdTime;
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 getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
@Override
public String toString() {
return "SysLog [id=" + id + ", username=" + username + ", operation=" + operation + ", method=" + method
+ ", params=" + params + ", time=" + time + ", ip=" + ip + ", createdTime=" + createdTime + "]";
}
}
spring中任何一个对象都可看成javabean
/**使用javabean(VO-valueobject-值对象:封装值的,提供了getter、setter方法的;pojo持久化对象)接收数据*/
@RequestMapping("doReqParam05")
@ResponseBody
public String doReqParam05(SysLog log){
//请求中的参数要与pojo对象的set方法一致
return "obtain parameter's value is "+log.toString();
}
http://localhost/spring-mvc-v1/req/doReqParam05.do?id=10&username=zhangsan&operation=update
运行结果
obtain parameter's value is SysLog [id=10, username=zhangsan, operation=update, method=null, params=null, time=null, ip=null, createdTime=null]
3.1.4. 集合Map对象对象(了解)
说明: 通过map接收页面参数时,必须使用@RequestParam注解声明,否则map将拿不到数据
提示:假如方法参数时map类型,而使用@RequestParam注解进行修饰,此时的map一般是用来封装响应数据的一个对象。
@RequestMapping("doReqParam06")
@ResponseBody
public String doReqParam06(@RequestParam Map<String,Object>map){
//请求中的参数要与pojo对象的set方法一致
return "obtain parameter's value is "+map.toString();
}
http://localhost/spring-mvc-v1/req/doReqParam06.do?id=100&title=a
运行结果
obtain parameter's value is {id=100, title=a}
3.1.6. Rest url数据(重点)
SpringMVC请求资源路径的URL可以通过{XXX}形式指定动态的URL,动态URL中的这个可变参数的值可以直接注入到方法对应的参数中。
@RequestMapping("doReqParam07/{id}")
@ResponseBody
//参数的值来自请求中的url
public String doReqParam07(@PathVariable Integer id){
//请求中的参数要与pojo对象的set方法一致
return "obtain parameter's value is "+id;
}
http://localhost/spring-mvc-v1/req/doReqParam07/168.do
运行结果
obtain parameter's value is 168
@RequestMapping("doReqParam07/{var}/{name}")
@ResponseBody
//参数的值来自请求中的url
public String doReqParam07(@PathVariable("var") Integer id,@PathVariable String name){
//请求中的参数要与pojo对象的set方法一致
//从reset风格url中获取请求数据,需要使用@PathVariable注解对参数进行修饰
return "obtain parameter's value is "+id+" name is "+name;
}
http://localhost/spring-mvc-v1/req/doReqParam07/168/zhang.do
运行结果
obtain parameter's value is 168 name is zhang
3.1.7. 请求头数据(了解)
当服务端要获取客户端请求头中数据信息时,可通过@RequestHeader即可将请求头中
的属性值绑定到处理方法的入参中,例如获取请求中Accept属性的值,然后传入到对应方法的参数中。
@RequestMapping("doReqHeader01")
@ResponseBody
//参数的值来自请求中的url
public String doReqHeader01(@RequestHeader String Accept){
return "obtain parameter's value is Accept= "+Accept;
}
http://localhost/spring-mvc-v1/req/doReqHeader01.do
运行结果
obtain parameter's value is Accept= text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
@RequestMapping("doReqHeader01")
@ResponseBody
//参数的值来自请求中的url
public String doReqHeader01(@RequestHeader("Accept-Encoding") String AcceptEncoding){
return "obtain parameter's value is AcceptEncoding= "+AcceptEncoding;
}
http://localhost/spring-mvc-v1/req/doReqHeader01.do
运行结果
obtain parameter's value is AcceptEncoding= gzip, deflate
@RequestMapping("doReqCookie01")
@ResponseBody
public String doReqCookie01(
@CookieValue String JSESSIONID) {
return "obtain COOKIE value is JSESSIONID " + JSESSIONID + "";
}
http://localhost/spring-mvc-v1/req/doReqCookie01.do
运行结果
obtain COOKIE value is JSESSIONID DF4E61FA6FDC9C1C0AC614334A29993B
提示:方法中的参数名需要与请求头参数中某个参数名相同,具体请求头相关信息可以在浏览器控制台查看。
当应用中要获取请求中所有数据时可以在请求方法中定义一个HttpEntity<String>参数,通过此参数获取请求头及请求体中数据,例如
@RequestMapping(value="doReqEntity01", method=RequestMethod.POST)
public @ResponseBody String doReqEntity01(
HttpEntity<String> entity) {
return "Posted request body " + entity.getBody() + " headers = " + entity.getHeaders();
}
<form action="http://localhost/spring-mvc-v1/req/doReqEntity01.do" method="POST">
<input type="text" name="user">
<input type="submit">
</form>
Posted request body user=good headers = {host=[localhost], user-agent=[Mozilla/5.0 (Windows NT 6.1; WOW64; rv:61.0) Gecko/20100101 Firefox/61.0], accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8], accept-language=[zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2], accept-encoding=[gzip, deflate], referer=[http://localhost/spring-mvc-v1/doSayHello.do], content-type=[application/x-www-form-urlencoded], content-length=[9], cookie=[JSESSIONID=108236BEF06FFBECBD0F953655F2EA29], connection=[keep-alive], upgrade-insecure-requests=[1]}