SpringMVC(二)

SpringMVC(二)

@RequestMapping相关属性

Value属性

  • 用来设置请求路径
  • 值是一个字符串数组
  • 可以设置多个路径共同访问对应方法

示例

<a href="${pageContext.request.contextPath}/first.action">第一个请求</a>
<a href="${pageContext.request.contextPath}/second.action">第二个请求</a>
@RequestMapping(value = {"first","second"})
public String testquest(){
	System.out.println("testquest--------------");
	return "/result.jsp";
}

method属性

  • 用来设置映射的请求方式
  • 值是RequestMethod类型的数组
  • 如果没有写,则没有限制,post与get都可以请求到对应的方法
  • 如果指定了请求类型,则必须得是相应的请求才能访问到对应的方法

示例

<form action="${pageContext.request.contextPath}/testMethod" method="post">
    <input type="submit" value="测试testMethod">
</form>
@RequestMapping(
    value = {"testMethod"},
    method = {RequestMethod.POST,RequestMethod.GET}
)
public String testrestDELETE(Model model){
	model.addAttribute("msg","请求"+id);
	return "/result.jsp";
}

params属性

  • 必须设置对应的请求参数和请求值才能访问到对应的内容

示例

<a href="${pageContext.request.contextPath}/testMethod.action?name=le&age=22" method="post">请求
</a>
@RequestMapping(
    value = {"testMethod"},
    method = {RequestMethod.POST,RequestMethod.GET},
    params={"name=le","age!=2"}
)
public String testrestPOST(Model model){
	model.addAttribute("msg","请求"+id);
	return "/result.jsp";
}

headers属性

  • ​ 发送的请求头必须要与设置的请求相同时,才能够访问到对应的方法

示例​

@RequestMapping(
    value = {"testMethod"},
    method = {RequestMethod.POST,RequestMethod.GET},
    params = {"name=le","age!=2"},
    headers = {"Host=localhost:8080","Referer:http://localhost:8080/index.jsp"}
)
public String testrestPOST(Model model){
	model.addAttribute("msg","请求"+id);
	return "/result.jsp";
}

Ant风格地址

Ant风格

​ 请求路径的一种匹配方法

通配符

?

​ 一个?匹配一个字符

<a href="${pageContext.request.contextPath}/ant/a/testAnt.action" method="post">请求ant路径
</a>
@RequestMapping("/ant/?/testAnt")
public String testAnt(Model model){
	return "/result.jsp";
}

<a href="${pageContext.request.contextPath}/ant/ab/testAnt.action" method="post">请求ant路径
</a>
@RequestMapping("/ant/??/testAnt")
public String testAnt(Model model){
	return "/result.jsp";
}
*

​ 匹配任意字符

<a href="${pageContext.request.contextPath}/ant/abc/testAnt.action" method="post">请求ant路径
</a>
@RequestMapping("/ant/*/testAnt")
public String testAnt(Model model){
	return "/result.jsp";
}
**

​ 匹配多重路径

<a href="${pageContext.request.contextPath}/ant/a/b/ccc/testAnt.action" method="post">请求ant路径
</a>
@RequestMapping("/ant/**/testAnt")
public String testAnt(Model model){
	return "/result.jsp";
}

@PathVariable

rest风格

  • 资源定位及资源操作的风格
  • 不是协议,可以遵循,也可以不遵循

REST风格请求

  • REST 即 Representational State Transfer (资源)表现层状态转化
  • 用URL定位资源,用HTTP描述操作
  • 是目前最流行的一种互联网软件架构
  • 它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用
  • 使用POST, DELETE, PUT, GET 分别对应 CRUD
  • Spring3.0 开始支持 REST 风格的请求

传统的操作资源

restful操作资源

使用@PathVariable接收RestFul风格参数

<a href="${pageContext.request.contextPath}/restful/2.action" method="post">请求ant路径
</a>
@RequestMapping("/restful/{id}")
public String testRestful(@PathVariable int id){
	System.out.println(id);
	return "/result.jsp";
}

发送put与delete请求

  • 默认情况下Form表单是不支持PUT请求和DELETE请求的
  • spring3.0添加了一个过滤器HiddenHttpMethodFilter
  • 可以将post请求转换为PUT或DELETE请求

配置过滤器

  • HiddenHttpMethodFilter必须作用于dispatcher前,所以在web.xml中配置HiddenHttpMethodFilter
Spring MVC过滤器-HiddenHttpMethodFilter
介绍
  • HiddenHttpMethodFilter的父类是OncePerRequestFilter,它继承了父类的doFilterInternal方法,工作原理是将jsp页面的form表单的method属性值在doFilterInternal方法中转化为标准的Http方法,即GET,、POST、 HEAD、OPTIONS、PUT、DELETE、TRACE
  • 然后到Controller中找到对应的方法。
  • 例如,在使用注解时我们可能会在Controller中用于@RequestMapping(value = "list", method = RequestMethod.PUT),所以如果你的表单中使用的是< form method="put" >,那么这个表单会被提交到标了Method="PUT"的方法中。
问题
  • 浏览器form表单只支持GET与POST请求,而对DELETE、PUT等method请求并不支持
  • spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求,该过滤器为HiddenHttpMethodFilter
<filter>
	<filter-name>hiddenmethod</filter-name>
	<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
	<filter-name>hiddenmethod</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 配置SpringMVC前端控制器 -->
<servlet>
	<servlet-name>mySpringMVC</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<!-- 指定SpringMVC配置文件 -->
	<!-- SpringMVC的配置文件的默认路径是/WEB-INF/${servlet-name}-servlet.xml -->
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:springmvc.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>mySpringMVC</servlet-name>
	<!-- 拦截所有,不包括jsp,包含.js .png.css     建议使用  -->
	<url-pattern>/</url-pattern>
</servlet-mapping>

发送请求

<form action="${pageContext.request.contextPath}/restful/1.action" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="测试testRestForm">
</form>

服务器接收处理(必须重定向,否则会报错;视图渲染返回的时候,由于不支持这两种方法,就会报出异常页面)

@RequestMapping(value = "/restful/{id}",method = RequestMethod.PUT)
public String testRestful(@PathVariable int id){
	System.out.println(id);
	return "redirect:/result.action";
}

@RequestMapping("result")
public String re(){
	System.out.println(id);
	return "/result.jsp";
}

注意事项

  • 从tomcat8开始,如果直接返回jsp页面,会报405错误 JSPs only permit GET POST or HEAD
  • 使用重定向的形式跳转到对应jsp
  • 或者是直接把对应jsp的 isErrorPage="true"
  • 在tomcat8上面是不支持delete和post请求的,因此以上只能在tomcat7上面执行
  • tomcat8运行时可以进入到相应的控制器,但是视图渲染返回的时候,由于不支持这两种方法,就会报出异常页面

过滤器HiddenHttpMethodFilter源码分析

@RequestHeader

作用

  • 在方法中接收请求头当中的信息

示例

@RequestMapping("testHeader")
public String testHeader(
	@RequestHeader("Host") String host,
	@RequestHeader("Referer") String referer,
	@RequestHeader("Cookie") String cookie){
	System.out.println(host);
	System.out.println(referer);
	System.out.println(cookie);
	return "/result.jsp";
}

@CookieValue

作用

  • 用来接收浏览发送过来的cookies值

示例

@RequestMapping("testHeader")
public String testHeader(
	@CookieValue("JSESSIONID") String sessionid){
	System.out.println(sessionid);
	return "/result.jsp";
}

传值方式

ModelMap

  • ModelMap对象主要用于传递控制方法处理数据到结果页面
  • 也就是说我们把结果页面上需要的数据放到ModelMap对象中即可
  • request对象的setAttribute方法的作用: 用来在一个请求过程中传递处理的数据。
  • 使用方法与model一样

Model

  • Model 和 ModelMap 的实例都是spirng mvc框架来自动创建并作为控制器方法参数传入,用户无需自己创建
  • 可以简单地将model的实现类理解成一个Map
  • Request级别的模型数据
  • Model 是一个接口, 其实现类为ExtendedModelMap,继承了ModelMap类

方法介绍

@RequestMapping("testModel")
public String testModel(Model model){
	//Model addAttribute(String attributeName, Object attributeValue);
	//添加键值属性对
	model.addAttribute("name","le");
	
	//Map<String, Object> asMap();
	//将当前的model转换成Map
	System.out.println(model.asMap());
	
	User user = new User();
	user.setName("le");
	
	//Model addAttribute(Object attributeValue);
	//以属性的类型为键添加属性
	model.addAttribute(user);
	System.out.println("以属性的类型为键添加属性后:"+model.asMap());
	
	Map map = new HashMap();
	map.put("name","le");
	
	//Model addAllAttributes(Map<String, ?> attributes);
	//将attributes中的内容复制到当前的model中
	//如果当前model存在相同内容,会被覆盖
	model.addAllAttributes(map);
	System.out.println("在addAllAttributes中添加map后:"+model.asMap());
	
	ArrayList collection = new ArrayList<>();
	collection.add("le001");
	collection.add("le001");
	collection.add(123);
	
	//Model addAllAttributes(Collection<?> attributeValues);
	//以集合中数据的类型做为key
	//将所提供的Collection中的所有属性复制到这个Map中
	//如果有同类型会存在覆盖现象
	model.addAllAttributes(collection);
	System.out.println("在addAllAttributes中添加collection后:"+model.asMap());
	
	//Model mergeAttributes(Map<String, ?> attributes);
	//将attributes中的内容复制到当前的model中
	//如果当前model存在相同内容,不会被覆盖
	model.mergeAttributes(map);
	System.out.println("mergeAttributes后"+model.asMap());
	
	//boolean containsAttribute(String attributeName);
	//判断当前model是否存在属性名为attributeName的属性
	//存在返回true,否则返回false
	System.out.println(model.containsAttribute("le"));
	
	return "/result.jsp";
}

ModelAndView

  • 需要自己创建
  • 既包含模型也包含视图

@SessionAttributes注解

  • 将模型中的某个属性暂存到 HttpSession 中,以便多个请求之间可以共享这个属性
  • value(把model当中key为指定值的模型数据存到session域当中)
  • type(把model当中指定的属性类型的模型数据放到session域当中 )
@Controller
//value 把model当中key为name存到session
//types 把model当中的指定类型全部写到session
//@SessionAttributes(value = {"name","name2"})
//@SessionAttributes(types = String.class)
//@SessionAttributes(types = {User.class,Product.class},value={“attr1”,”attr2”})
@SessionAttributes(value = "sessionGoodsKey")
public class MyController {
    @RequestMapping("testModelandView")
	public ModelAndView testModelandView(){
		ModelAndView modelAndView = new ModelAndView();
		//把数据写到request域
		modelAndView.addObject("name","le");
		modelAndView.setViewName("result.jsp");
		return modelAndView;
    }
}

使用@SessionAttribute来访问预先存在的全局会话属性

@Controller
@SessionAttributes(value = {"user"})
public class MyController {
	//使用@SessionAttribute来访问预先存在的全局会话属性
	//如果不存在,则报错
    @RequestMapping("testModel")
	public String testModel(@SessionAttributes("user") User user){
		System.out.println("user = "+user);
		return "/result.jsp";
    }
}

@ModelAttribute

作用

  • 修改处理方法的参数时,自动把该参数放到model当中
  • key值为@ModelAttribute("modelGoods")当中的参数
  • 在方法定义上使用 @ModelAttribute 注解,Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法
//此注释会将此方法在对应的RequestMapping映射方法执行之前自动调用
@ModelAttribute
public String testModelAttribute(){
	System.out.println("ModelAttribute执行了");
	return "result.jsp";
}

//会自动的对应的模型存放在model
@RequestMapping("testFormModel")
public String testModelAttribute(@ModelAttribute("modelGoods") Goods mygoods,Model model){
	System.out.println(model.asMap());
	return "result.jsp";
}

//会自动的对应的模型存放在model
//传入参数后,参数会自动传入model当中
//key值为类型名,但是要首字母小写
@RequestMapping("testFormModel2")
public String testModelAttribute2(Goods mygoods){
	System.out.println(model.asMap());
	return "result.jsp";
}

数据的访问过程

  1. 浏览器
  2. 学习接收参数
  3. 前端控制器
  4. 写数据到页面(通过Model)
  5. JSP
posted @ 2019-05-25 11:07  海韵༒听心  阅读(246)  评论(0编辑  收藏  举报