Restful:约定俗成的一种风格,便于规范开发
使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作
分别对应 添加、 删除、修改、查询
传统方式操作资源 使用RESTful操作资源
http://127.0.0.1/item/queryItem.action?id=1 查询,GET http://127.0.0.1/item/1 查询,GET 1是查询指定id为1的信息
http://127.0.0.1/item/saveItem.action 新增,POST http://127.0.0.1/item 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST http://127.0.0.1/item/1 删除,DELETE 1是需要删除的指定id,
http://127.0.0.1/user/1,2,3 删除id为1,2,3的user 当删除多个id是使用,连接
1)由于浏览器表单只支持 GET 和 POST 请求,为了实现 DELETE 和 PUT 请求,
Spring 为我们提供了一个过滤器org.springframework.web.filter.HiddenHttpMethodFilter,
可以为我们将 GET 和 POST 请求通过过滤器转化成 DELETE 和 PUT 请求。
2)在 web.xml 中配置过滤器
tips:过滤器链按照顺序执行,所以例如防止中文乱码之类的过滤器放在前面,让其优先执行避免出现中文乱码问题
<!--restful风格-->
<!-- 配置hiddenHttpMethodFilter过滤器可以将POST请求 转化为DELETE,PUT请求-->
<filter>
<filter-name>restful</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>restful</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3)jsp页面相关配置
由于浏览器表单无法发送 DELETE 和 PUT 请求,所以为了让 HiddenHttpMethodFilter 识别请求的方法,
需要在表单中添加一个隐藏域,名字为 _method 值为 DELETE 或 POST 或PUT或GET
<input type="hidden" name="_method" value="DELETE"/>
<input type="hidden" name="_method" value="POST "/>
<input type="hidden" name="_method" value="PUT"/>
<input type="hidden" name="_method" value="GET"/>
为什么name一定要为_method,是因为在配置filter时,HiddenHttpMethodFilter该类具有一个_method的属性用来接收代表传递方式的参数。
页面代码例: controller层代码例:
!-- 删除id为1的user --> <%-- 后台公用一个删除的方法 采用 /user/001,002,003 的方式,前台进行字符串凭借--%>
@ResponseBody
<form id="delete" action="/user/1" method="post"> @RequestMapping(value ="/{id}",method = RequestMethod.DELETE)
<input type="hidden" name="_method" value="DELETE"/> public String delete(@PathVariable("id")String[] cardid){
<input type="submit" value="Test Rest DELETE"/> 业务逻辑层代码
</form> return "";}
注意的是,在controller层也可以将删除方法分别写成单删和批删两种方法,传递方式同为DELETE,
但是方法名不同,且@RequestMapping地址不同,批删的地址 @RequestMapping(value ="",method = RequestMethod.DELETE),直接用数组的方式用属性名进行接收,单删同理
tips:
1.@PathVariable是获取url上数据的。@RequestParam获取请求参数的(包括post表单提交)
2.如果@RequestMapping中表示为”user/{id}”,id和形参名称一致,@PathVariable不用指定名称。
如果不一致,例如”user/{ItemId}”则需要指定名称@PathVariable(“itemId”)。而且@PathVariable必须标明。和@Requsetparam不同
3.如果加上@ResponseBody注解,就不会走视图解析器,不会返回页面,目前返回的json数据。如果不加,就走视图解析器,返回页面
拦截器
public class MyInterceptor1 implements HandlerInterceptor {
//在Controller方法执行后被执行,三个方法中最后被执行
//处理异常、记录日志
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("MyInterceptor1.afterCompletion.....");
}
//在Controller方法执行后,返回ModelAndView之前被执行,三个方法中第二个被执行
//设置或者清理页面共用参数等等
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("MyInterceptor1.postHandle.....");
}
//在Controller方法执行前被执行,三个方法中最先执行
//登录拦截、权限认证等等
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("MyInterceptor1.preHandle.....");
//返回true放行,false拦截
return true;!!!这里很重要,如果在拦截的目标下,返回值为false则不进行放行,无法进入controller类中
}
}
拦截器配置
3.1.2配置拦截器
<!-- 拦截器定义 -->
<mvc:interceptors>
<!-- 定义一个拦截器 -->
<mvc:interceptor>
<!-- path配置</**>拦截所有请求,包括二级以上目录,</*>拦截所有请求,不包括二级以上目录 --> /a.ction /user/a.action
<mvc:mapping path="/**"/>
<bean class="com.itheima.springmvc.interceptor.MyInterceptor1" />
</mvc:interceptor>
<!-- 定义一个拦截器 -->
<mvc:interceptor>
<!-- path配置</**>拦截所有请求,包括二级以上目录,</*>拦截所有请求,不包括二级以上目录 -->
<mvc:mapping path="/**"/>
<!-- 配置不拦截请求的地址 -->
<!-- <mvc:exclude-mapping path="指定路径"/> exclude: vt. 排斥; 排除,不包括;
<bean class="com.itheima.springmvc.interceptor.MyInterceptor2" />
</mvc:interceptor>
</mvc:interceptors>