springmvc拦截器对请求参数解密_Spring MVC温故而知新 – 参数绑定、转发与重定向、异常处理、拦截器...

请求参数绑定

当用户发送请求时,根据Spring MVC的请求处理流程,前端控制器会请求处理器映射器返回一个处理器,然后请求处理器适配器之心相应的处理器,此时处理器映射器会调用Spring Mvc 提供的参数绑定组件将请求的key/value 数据绑定到Controller处理器方法对应的形参上。Spring MVC使用Converter转换器可以进行各种类型的转换,也可自定义Converter转换器,Spring MVC默认转换器支持的类型有HttpServletRequest、HttpServletResponse、HttpSession、Model、ModelMap。其中Model是一个接口,ModelMap是一个接口实现,作用是将model数据填充到request。

简单类型,自定义类型

//localhost:8080/springMvcNext/product/infoa?id=1

@RequestMapping("infoa")publicString productInfoa(Model model, Integer id) {

model.addAttribute("message", "productid:" +id);return "product/info";

}

备注:如果url中参数名不是id,则不会绑定成功,需要通过使用注解RequestParam绑定参数

自定义类型传递,使用pojo传递(Product)

@RequestMapping(value="infob",method =RequestMethod.POST)publicString productInfob(Model model, Product product) {

model.addAttribute("message", "product-price:" + product.getPrice()+"product-name:" +product.getProductName());return "product/info";

}

使用注解绑定参数

通过RequestParam注解绑定参数形参名与入参不一致的参数,RerquestParam有三个参数属性,value参数名,指定要绑定的入参名,required是否必须,默认为false,defaultValue属性,用于没有传递时赋默认值。

//http://localhost:8080/springMvcNext/product/info?productId=1&name=fgsg

@RequestMapping("info")public String productInfo(Model model, @RequestParam(name = "name", defaultValue = "test") String productName,

@RequestParam(required= true) Integer productId) {

model.addAttribute("message", "name:" + productName + " productid:" +productId);return "product/info";

}

通过RequestHeader注解获取请求头的信息,RequestHeader同样有三个参数属性value,required,defaultvalue

// http://localhost:8080/springMvcNext/product/info2//输出产品信息:browser:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36 language:zh-CN,zh;q=0.9

@RequestMapping("info2")public String productInfo2(Model model, @RequestHeader("User-Agent") String browser,

@RequestHeader(value= "Accept-Language", required = false, defaultValue = "null") String language) {

model.addAttribute("message", "browser:" + browser + " language:" +language);return "product/info";

}

通过CookieValue注解获取请求头的信息

//http://localhost:8080/springMvcNext/product/info3//输出:产品信息:JSESSIONID:0FD3AFA5E445DADACBC1F07568970FEC

@RequestMapping("info3")public String productInfo3(Model model, @CookieValue("JSESSIONID") String cookie) {

model.addAttribute("message", "JSESSIONID:" +cookie);return "product/info";

}

通过HttpServletRequest获取参数

使用HttpServletRequest获取请求参数,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息,HttpServletRequest可以用于参数解析,Cookie读取,http请求字段,文件上传

@RequestMapping("info4")publicString productInfo(String houseUnitInfo, HttpServletRequest request, HttpServletResponse response)throwsIOException {

String requestStr=charReader(request);

System.out.println(requestStr);return "product/info";

}private String charReader(HttpServletRequest request) throwsIOException {

BufferedReader br=request.getReader();

String str, wholeStr= "";while ((str = br.readLine()) != null) {

wholeStr+=str;

}//System.out.println(wholeStr);

returnwholeStr;

}

测试:

结果:

Action返回值

返回ModelAndView

返回ModelAndView可以指定视图名和model数据,ModelAndView提供的addObject方法来给这个模型添加数据,添加的是一个键值对的数据

@RequestMapping("info5")publicModelAndView productInfo5() {

ModelAndView modelAndView= newModelAndView();

modelAndView.setViewName("product/detail");

modelAndView.addObject("message", "return modelandview");//modelAndView.addObject("xxx", "yyy");

returnmodelAndView;

}

返回void,Map,Model

返回void,Map,Model 时,返回对应的逻辑视图名称就是请求url,仍然遵循:prefix前缀+视图名称 +suffix后缀组成

//1.返回Map//访问视图: /springMvcNext/WEB-INF/view/product/detail.jsp

@RequestMapping("detail")public Mapdetail2313() {

Map map = new HashMap();

map.put("message", "product detail");returnmap;

}//2.返回void//返回void时,则响应的视图页面对应为访问地址

//访问视图: /springMvcNext/WEB-INF/view/product/info6.jsp

@RequestMapping("info6")public voidproductInfo6() {

}

但输出流中存在输出内容时,则不会去查找视图,而是将输入流中的内容直接响应到客户端,响应的内容类型是纯文本

@RequestMapping("info7")public void productInfo7(HttpServletResponse response) throwsIOException {

response.getWriter().write("

void method

");//直接相应结果

}

@RequestMapping("info8")public void productInfo8(HttpServletResponse response) throwsIOException {

response.sendRedirect("detail"); //重定向 访问:http://localhost:8080/springMvcNext/product/detail

}

//3.返回Model model对象会用于页面渲染,视图路径使用方法名,与void类似。示例代码如下:

@RequestMapping("info9")publicModel productInfo9(Model model) {

model.addAttribute("message", "product detail");returnmodel;

}

返回String(视图名)

返回视图名:Controller类方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

@RequestMapping("info10")publicString productInfo10(Model model)

{

model.addAttribute("message", "productInfo10");return "product/detail";

}

Spring MVC转发与重定向

使用 标签转发

Spring MVC中对与WEB-INF目录下面的JSP页面,不能直接通过URL访问。需要通过转发的方式,而我们一般都是在控制器中做转发映射,对应一些我们不需要其他操作的JSP页面,我们可以使用来配置,这样就可以不用再控制器中再去做转发映射。

访问:http://localhost:8080/springMvcNext/order/info 和 http://localhost:8080/springMvcNext/home 不经过处理器

使用forward或者redirect进行视图转发与重定

重定向:Spring mvc中可以在返回的结果前加上一个前缀“redirect:”,可以重定向到一个指定的页面也可以是另一个action

转发:Springmvc中返回结果前加“foword”前缀,注意:转发是一次请求(相同的request),地址栏的URL不会改变

//重定向//访问:http://localhost:8080/springMvcNext/product/redirecttest 时Url将跳转http://localhost:8080/springMvcNext/product/info10?redirectparas=test+redirect

@RequestMapping("redirecttest")publicString redirecttest(Model model) {

model.addAttribute("redirectparas", "test redirect"); //带参数跳转

return "redirect:/product/info10";

}//转发//访问http://localhost:8080/springMvcNext/product/forwardtest url不会跳转

@RequestMapping("forwardtest")publicString forwardtest(Model model){

model.addAttribute("forwardparas", "test forward"); //带参数跳转

return "forward:/product/info10";

}

异常处理

Spring MVC中通过使用@controlleradvice + @ ExceptionHandler 两个注解可以实现全局的异常捕捉。

@ExceptionHandler注解的作用是当出现其定义的异常时进行处理的方法,其可以使用springmvc提供的数据绑定,比如注入HttpServletRequest等,还可以接受一个当前抛出的Throwable对象

@ControllerAdvice 注解可以把异常处理器应用到所有控制器 @Controller ,而不是@Controller注解的单个控制器,该异常处理器对当前控制器的所有方法有效;如果单独某个控制器需要自定义处理异常,不用顶层的异常处理器,可以在当前控制器内用 @ExceptionHandler 注解 ,这样当前控制器的异常处理就在当前类中。

备注:使用ControllerAdvice注解类里面的异常的处理的优先级低于直接定义在处理方法的类中

实现一个异常处理器:

@ControllerAdvicepublic classExceptionHandlers {

@ExceptionHandler({ArithmeticException.class})publicModelAndView toException(Exception e){

ModelAndView mv= new ModelAndView("home");

System.out.println("gobal handler exception");//虽然不能使用Map往request中存值,但是可以使用下面的方法

mv.addObject("error", e);

System.out.println(e);returnmv;

}

}

控制器

@Controller

@RequestMapping("exception")public classExceptionController {//示例1

@RequestMapping("test")publicModelAndView test() {

System.out.println(10/0); //抛异常

return new ModelAndView("order/info", "message", "test exception");

}

}

拦截器

Spring MVC提供了Interceptor拦截机制,用于请求的预处理和后处理。在Spring MVC中定义一个拦截器有两种方法:第一种是实现HandlerInterceptor接口,或者继承实现了HandlerInterceptor接口的类例如(HandlerInterceptorAdapter);第二种方法是实现Spring的WebRequestInterceptor接口(该接口是针对请求的拦截器接口,接口方法参数中没有response),或者继承实现了WebrequestInterceptor的类。两种方式都是在Handler的执行周期内进行拦截操作。

如果要实现HandlerInterceptor接口,需要实现三个方法,preHandle、postHandle、afterCompletion

preHandle方法在执行Handler方法之前执行,返回false表示拦截请求,不在执行后续逻辑,可以用来做权限,日志等。

postHandle方法在执行Handler方法之后,返回modelAndView之前执行,由于该方法会在DispatcherServlet进行返回视图渲染之前被调用,所以此方法多被用于同一处理返回视图,例如将公用的模型数据添加到视图,或者根据其他情况制定公用的视图。

afterCompletion方法在执行完Handler之后执行,由于是在Controller方法执行完毕后执行该方法,所以该方法适合进行统一的异常或者日志处理操作。

实现HandlerInterceptor接口之后需要在Spring的类加载配置文件中配置拦截器实现类,才能使拦截器起到拦截的效果。HandlerInterceptor类加载配置有两种方式,分别是”针对HandlerMapping配置”和 全局配置。

针对HandlerMapping配置需要在某个处理器映射器配置中将拦截器作为参数配置进去,之后通过此处理器映射器的handler就会使用配置好的拦截器,配置如下:

全局配置,springmvc框架将配置的全局拦截器注入到每个HandlerMapping中。

实现一个拦截器:

@Componentpublic class TestInterceptor implementsHandlerInterceptor {/*** 当目标方法执行之前,执行此方法,返回false,则不再执行后续逻辑postHandle、afterCompletion*/

public booleanpreHandle(HttpServletRequest request,

HttpServletResponse response, Object handler)throwsException {

System.out.println("First preHandle 最先执行..");return true;

}/*** 执行目标方法之后,渲染视图之前调。 在转向jsp页面之前, 可以对请求域中的属性,或者视图进行修改*/

public voidpostHandle(HttpServletRequest request,

HttpServletResponse response, Object handler,

ModelAndView modelAndView)throwsException {

System.out.println("First postHandle 执行目标方法之后,渲染视图之前调。 在转向jsp页面之前,");

}/*** 在渲染视图之后被调用,可以进行日志处理*/

public voidafterCompletion(HttpServletRequest request,

HttpServletResponse response, Object handler, Exception ex)throwsException {

System.out.println("First afterCompletion 渲染视图之后调用");

}

}

运行controller则可以看到拦截器执行记录。

如果定义多个拦截器,则执行顺序如下:

1. preHandle是按配置文件中的顺序执行的

2. postHandle是按配置文件中的倒序执行的

3. afterCompletion是按配置文件中的倒序执行的

测试验证:

拦截器的指定范围:配置拦截器时可以根据需要制定拦截器作用范围,针对特定处理器或方法进行拦截。

 表示针对该Path不拦截 ,  表示针对该Path拦截,Path可以使用通配符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值