java 拦截器 json_springmvc java对象转json,上传下载,拦截器Interceptor以及源码解析...

package com.atguigu.my.controller;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import com.atguigu.my.bean.Employee;

import com.atguigu.my.dao.EmployeeDao;

@Controller

public class JsonController {

@Autowired

private EmployeeDao employeeDao;

@RequestMapping(value = "/testJson")

@ResponseBody

public Collection getAll() {

Collection emps = employeeDao.getAll();

;return emps;

}

}

68a4c7f197a5cd7a4495054f68a48e0b.png

只是写一个测试json

然后再springmvc.xml中开启注解驱动

然后需要印如jackson的三个jar包,jackson是阿里巴巴产品,能够自动将java对象转为json对象

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

SpringMVC04

index.jsp

CharacterEncodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

CharacterEncodingFilter

/*

springDispatcherServlet

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath:springMVC.xml

1

springDispatcherServlet

/

package com.atguigu.interceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

@Component

public class FirstInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

System.out.println("First:preHandle");

return true;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

System.out.println("First:postHandle");

}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

throws Exception {

System.out.println("First:afterCompletion");

}

}

package com.atguigu.interceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

@Component

public class SecondInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

System.out.println("Second:preHandle");

//统计请求耗时

long startTime = System.currentTimeMillis();

request.setAttribute("startTime", startTime);

return true;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

System.out.println("Second:postHandle");

long startTime = (Long)request.getAttribute("startTime");

long endTime = System.currentTimeMillis();

long executeTime = endTime - startTime;

//modified the exisitng modelAndView

modelAndView.addObject("executeTime",executeTime);

}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

throws Exception {

System.out.println("Second:afterCompletion");

}

}

package com.atguigu.test;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class TestInterceptorController {

/**

* 当有多个拦截器时,

* preHandle:按照拦截器数组的正向顺序执行

* postHandle:按照拦截器数组的反向顺序执行

* afterCompletion:按照拦截器数组的反向顺序执行

*

* 当多个拦截器的preHandle有不同的值时

* 第一个返回false,第二个返回false:只有第一个preHandle会执行

* 第一个返回true,第二个返回false:两个(全部)拦截器的preHandle都会执行

* 但是(全部)postHandle都不会执行,而afterCompletion只有第一个(返回false的拦截器之前的所有afterCompletion)会执行

* 第一个返回false,第二个返回true:只有第一个的preHandle会执行

*/

@RequestMapping("/testInterceptor")

public String testInterceptor() {

return "success";

}

}

拦截器(Interceptor)和过滤器(Filter)的区别

Spring的Interceptor(拦截器)与Servlet的Filter有相似之处,比如二者都是AOP编程思想的体现,都能实现权限检查、日志记录等。不同的是:

Filter

Interceptor

Summary

Filter 接口定义在 javax.servlet 包中

接口 HandlerInterceptor 定义在org.springframework.web.servlet 包中

Filter 定义在 web.xml 中

Filter在只在 Servlet 前后起作用。Filters 通常将 请求和响应(request/response) 当做黑盒子,Filter 通常不考虑servlet 的实现。

拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性。允许用户介入(hook into)请求的生命周期,在请求过程中获取信息,Interceptor 通常和请求更加耦合。

在Spring构架的程序中,要优先使用拦截器。几乎所有 Filter 能够做的事情, interceptor 都能够轻松的实现

Filter 是 Servlet 规范规定的。

而拦截器既可以用于Web程序,也可以用于Application、Swing程序中。

使用范围不同

Filter 是在 Servlet 规范中定义的,是 Servlet 容器支持的。

而拦截器是在 Spring容器内的,是Spring框架支持的。

规范不同

Filter 不能够使用 Spring 容器资源

拦截器是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如 Service对象、数据源、事务管理等,通过IoC注入到拦截器即可

Spring 中使用 interceptor 更容易

Filter 是被 Server(like Tomcat) 调用

Interceptor 是被 Spring 调用

因此 Filter 总是优先于 Interceptor 执行

interceptor 的执行顺序大致为:

请求到达 DispatcherServlet

DispatcherServlet 发送至 Interceptor ,执行 preHandle

请求达到 Controller

请求结束后,postHandle 执行

adddbdeab7f2c159ba72ca709fae1009.png

首先我们看下拦截器的如何被调用的。

Web请求被DispatcherServlet截获后,会调用DispatcherServlet的doDispatcher方法。

f356749fc2ccdfe249ac7e682bddf49d.png

00a45ae56d8480afad220b2bd1d434f5.png

很明显地看到,在HandlerAdapter处理之后,以及处理完成之后会调用HandlerExecutionChain的方法。

HandlerExecutionChain的applyPreHandle、applyPostHandle、triggerAfterCompletion方法如下:

59bb6014a067a7409db8516466d86803.png

eeec107d8adbfd729d23ff5bb3b68a6d.png

fb0d7b147663acbe05d41ade9916a123.png

很明显,就是调用内部实现HandlerInterceptor该接口集合的各个对应方法。

下面我们看下HandlerExecutionChain的构造过程。

HandlerExecutionChain是从HandlerMapping接口的getHandler方法获取的。

HandlerMapping的基础抽象类AbstractHandlerMapping中:

fa0547b400aba53199a404699952b2ff.png

559db6b0890e92c7fe955ab095140fd7.png

我们看到,HandlerExecutionChain的拦截器是从AbstractHandlerMapping中的adaptedInterceptors和mappedInterceptors属性中获取的。

package com.atguigu.test;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.UUID;

import javax.servlet.http.HttpSession;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.multipart.MultipartFile;

@Controller

public class TestUploadAndDownController {

@RequestMapping("/down")

public ResponseEntity down(HttpSession session) throws IOException{

//获取下载文件的路径

String realPath = session.getServletContext().getRealPath("img");

String finalPath = realPath + File.separator + "2.jpg";

InputStream is = new FileInputStream(finalPath);

//available():获取输入流所读取的文件的最大字节数

byte[] b = new byte[is.available()];

is.read(b);

//设置请求头

HttpHeaders headers = new HttpHeaders();

headers.add("Content-Disposition", "attachment;filename=zzz.jpg");

//设置响应状态

HttpStatus statusCode = HttpStatus.OK;

ResponseEntity entity = new ResponseEntity(b, headers, statusCode);

return entity;

}

@RequestMapping(value="/up", method=RequestMethod.POST)

public String up(String desc, MultipartFile uploadFile, HttpSession session) throws IOException {

//获取上传文件的名称

String fileName = uploadFile.getOriginalFilename();

String finalFileName = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf("."));

String path = session.getServletContext().getRealPath("photo") + File.separator + finalFileName;

File file = new File(path);

uploadFile.transferTo(file);

return "success";

}

@RequestMapping(value="/up_old", method=RequestMethod.POST)

public String up_old(String desc, MultipartFile uploadFile, HttpSession session) throws IOException {

//获取上传文件的名称

String fileName = uploadFile.getOriginalFilename();

String path = session.getServletContext().getRealPath("photo") + File.separator + fileName;

//获取输入流

InputStream is = uploadFile.getInputStream();

//获取输出流

File file = new File(path);

OutputStream os = new FileOutputStream(file);

/*int i = 0;

while((i = is.read()) != -1) {

os.write(i);

}*/

/*int i = 0;

byte[] b = new byte[1024];

while((i = is.read(b)) != -1) {

os.write(b, 0, i);

}*/

os.close();

is.close();

return "success";

}

}

158328dc72a6b7345b76804e7404541e.png

这个和操作系统有关系,最好加一个/, 血泪史啊

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值