SpringMVC总结二:映射请求、模型处理

HTTP请求

    由于SpringMVC是通过HTTP进行访问的,需要了解一些HTTP有关的知识,简单记录一下HTTP请求。
    我们知道HTTP是一种无状态的请求—响应协议,大致工作原理如下:

  1. 客户与服务器建立连接
  2. 客户向服务器提出请求
  3. 服务器接受请求,并根据请求返回相应的文件作为应答
  4. 客户与服务器关闭连接

    HTTP请求其实是发送一段符合HTTP协议标准的数据,就是HTTP报文。

HTTP请求报文格式:

    请求行 - 【通用信息头 - 请求头 - 实体头】(这三部分一般称为请求头或报文头) - 报文主体

    请求行以方法字段开始,后面分别是 URL 字段HTTP 协议版本字段,并以 CRLF 结尾。SP 是分隔符。除了在最后的 CRLF 序列中 CF 和 LF 是必需的之外,其他都可以不要。

  • 通用头标:即可用于请求,也可用于响应,是作为一个整体而不是特定资源与事务相关联。
  • 请求头标:允许客户端传递关于自身的信息和希望的响应形式。
  • 实体头标:定义被传送资源的信息。即可用于请求,也可用于响应。
    **加粗样式图中的报文头部分就包括了通用信息头、请求头、实体头,还注意到报文头和报文体中间有一个空格,报文体就是我们真实要传输的数据。

HTTP响应报文格式:

响应行- 响应头- 报文主体

    响应行由报文协议及版本、状态码及状态描述组成。状态码元由3位数字组成,表示请求是否被理解或被满足。下面图片中的响应头
在这里插入图片描述

@RequestMapping

请求映射

    在总结一中的HelloWorld程序中使用了@RequestMapping注解来映射请求。
在这里插入图片描述
    在helloworld中可以看到使用请求URL映射请求,还可以用请求方法请求参数请求头映射请求。
    @RequestMapping 的 valuemethodparamsheads 分别表示请求 URL请求方法请求参数请求头的映射条 件,他们之间是与的关系,联合使用多个条件可让请求映射 更加精确化,@RequestMapping如果不指定参数,默认就是使用value即URL映射方式。

    params 和 headers支持简单的表达式:

  • param1: 表示请求必须包含名为 param1 的请求参数
  • !param1: 表示请求不能包含名为 param1 的请求参数
  • param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
  • {“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1
	@RequestMapping(
	 value = "testParamsAndHeaders", 
	 params = { "username", "age!=10" },
	 headers = {"Accept-Language=zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-CN;q=0.3,en;q=0.2" })

    @RequestMapping支持 Ant 风格的 URL。

    Ant 风格资源地址支持 3 种匹配符:

  • ?:匹配文件名中的一个字符
  • *:匹配文件名中的任意个数字符
  • **:匹配多层路径
/user/*/createUser: 匹配 – /user/aaa/createUser、/user/bbb/createUser 等 URL 
/user/**/createUser: 匹配 – /user/createUser、/user/aaa/bbb/createUser 等 URL 
/user/createUser??: 匹配 – /user/createUseraa、/user/createUserbb 等 UR、

@RequestMapping 除了修饰方法, 还可来修饰类

  • 类定义处: 提供初步的请求映射信息。相对于 WEB 应用的根目录
  • 方法处: 提供进一步的细分映射信息。 相对于类定义处的 URL。若类定义处未标注 @RequestMapping,则方法处标记的 URL相对于 WEB 应用的根目录
参数映射

    使用 @PathVariable@RequestParam@RequestHeader 等注解,Spring MVC 框架会将 HTTP 请求的信息绑定到相应的方法入参 中。

@PathVariable 映射 URL 绑定的占位符

    通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中。

	@RequestMapping("/testPathVariable/{id}")
	public String testPathVariable(@PathVariable("id") Integer id) {
		System.out.println("SpringMVCTest.testPathVariable:" + id);
		return SUCCESS;
	}

@RequestParam 绑定请求参数值

该注解有三个属性:

  • value:参数名
  • required:是否必须。默认为 true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常
  • defaultValue: 如果URL中没有该请求参数时,赋值给变量的值
	@RequestMapping("/testRequestParam")
	public String testRequestParam(@RequestParam(value = "username") String un,
			@RequestParam(value = "age", required = false, defaultValue = "0") int age) {
		System.out.println("SpringMVCTest.testRequestParam:username=" + un + ",age=" + age);
		return SUCCESS;
	}

@RequestHeader 绑定请求报头的属性值

    请求头包含了若干个属性,服务器可据此获知客户端的信•息,通过 @RequestHeader 即可将请求头中的属性值绑 定到处理方法的入参中。属性同 @RequestParam

	@RequestMapping("/testRequestHeader")
	private String testRequestHeader(@RequestHeader(value = "Accept-Language") String al) {
		System.out.println("SpringMVCTest.testRequestHeader,Accept-Language:" + al);
		return SUCCESS;
	}

使用 @CookieValue 绑定请求中的 Cookie 值

    @CookieValue 可让处理方法入参绑定某个 Cookie 。属性同 @RequestParam

	@RequestMapping("/testCookieValue")
	public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {
		System.out.println("testCookieValue: sessionId: " + sessionId);
		return SUCCESS;
	}

使用 POJO(Plain Ordinary Java Object,简单的Java对象,实际就是普通对象,一般指没有业务逻辑方法的对象)绑定请求参数值
    Spring MVC 会按请求参数名和 POJO 属性名进行自动匹 配,自动为该对象填充属性值。支持级联属性。 如:dept.deptId、dept.address.tel

	@RequestMapping("/testPojo")
	public String testPojo(User user) {
		System.out.println("testPojo: " + user);
		return SUCCESS;
	}

使用 Servlet API 作为入参

    可以使用 Serlvet 原生的 API 作为目标方法的参数 具体支持以下类型

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • java.security.Principal
  • Locale InputStream
  • OutputStream
  • Reader
  • Writer
	@RequestMapping("/testServletAPI")
	public void testServletAPI(HttpServletRequest request,
			HttpServletResponse response, Writer out) throws IOException {
		System.out.println("testServletAPI, " + request + ", " + response);
		out.write("hello springmvc");
	}

模型处理

    所谓模型数据我理解的就是含有@RequestMapping的方法的返回值就是个模型,这个模型包含了视图信息和数据信息。在进行视图解析和渲染的时候要使用的数据就是模型数据。

    Spring MVC 提供了以下几种途径输出模型数据:

  • ModelAndView: 处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据
  1. 添加模型数据
    MoelAndView addObject(String attributeName, Object attributeValue)
    ModelAndView addAllObject(Map<String, ?> modelMap)–
  2. 设置视图:
    void setView(View view)
    void setViewName(String viewName)j
	控制器处理方法的返回值如果为 ModelAndView, 则其既包含视图信息,也包含模型数据信息。 
	
	@RequestMapping("/testModelAndView")
	public ModelAndView testModelAndView(){
		String viewName = SUCCESS;
		ModelAndView modelAndView = new ModelAndView(viewName);
		
		//添加模型数据到 ModelAndView 中.
		modelAndView.addObject("time", new Date());
		
		return modelAndView;
	}
  • Map 及 Model: 入参为org.springframework.ui.Modelorg.springframework.ui. ModelMapjava.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。
  1. Spring MVC 在内部使用了一个 org.springframework.ui.Model 接口存储模型数据
    具体步骤:
        Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
         如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据.
	@RequestMapping("/testMap")
	public String testMap(Map<String, Object> map){
		System.out.println(map.getClass().getName()); 
		map.put("names", Arrays.asList("Tom", "Jerry", "Mike"));
		return SUCCESS;
	}
  • @SessionAttributes: 将模型中的某个属性暂存到 HttpSession 中,以便多个请求之间可以共享这个属性 , 注意: 该注解只能放在类的上面. 而不能修饰放方法.
  1. 若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes, Spring MVC 将在模型中对应的属性暂存到 HttpSession 中
  2. @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
    — @SessionAttributes(types=User.class) 会将隐含模型中所有类型为 User.class 的属性添加到会话中。
    — @SessionAttributes(value={“user1”, “user2”})
    — @SessionAttributes(types={User.class, Dept.class})
    — @SessionAttributes(value={“user1”, “user2”}, types={Dept.class}
	@SessionAttributes(value={"user"}, types={String.class})注意这个注解是加在类上的
	我是为了记录所以才剪切了过来。
	
	public String testSessionAttributes(Map<String, Object> map){
		User user = new User("Tom", "123456", "tom@atguigu.com", 15);
		map.put("user", user);
		map.put("school", "atguigu");
		return SUCCESS;
	}
  • @ModelAttribute: 方法入参标注该注解后, 入参的对象就会放到数据模型
        这个使用方法太多,放在本文章中过于冗余,我会单独写一篇文章记录——@ModelAttritbute的用法,还有上面提到了Controller类的方法返回为String、Model、Map等类型的时候的情况,在这篇文章中我也会记录一下关于Controller类的各种返回值的不同处理方式。

最后来谈一下关于@SessionAttributes引发的异常的问题。
    如果在处理类定义处标注了 @SessionAttributes(“xxx”),则会尝试从会话中获取该属性,并将其赋给该入参,然后再用请求消息填充该入参对象。如果在会话中找不到对应的属 性,则抛出 HttpSessionRequiredException 异常.
    一般用@ModelAttribute注解来向隐含模型中添加一个@SessionAttribute所要获取的对象来避免此异常的发生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值