文档章节

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

architect刘源源
 architect刘源源
发布于 06/20 00:10
字数 1715
阅读 114
收藏 3

 

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<Employee> getAll() {
		Collection<Employee> emps = employeeDao.getAll();
;		return emps;
	}
}

只是写一个<a href = "testJson">测试json</a>

然后再springmvc.xml中开启注解驱动<mvc:annotation-driven/>

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	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">

	<context:component-scan base-package="com.atguigu"></context:component-scan>
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/view/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<mvc:default-servlet-handler/>
	
	<mvc:annotation-driven />
	
	<!-- 
		处理文件,将客户端上传的File文件,处理为MultipartFile
		注意:文件解析器的bean中id必须设置为multipartResolver
	 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设置文件解析的编码,注意:一定要和页面的pageEncoding保持一致 -->
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 设置最大上传文件大小 -->
		<property name="maxUploadSize" value="88888888"></property>
	</bean>

	<mvc:interceptors>
		<!-- 默认拦截所有请求 -->
		<bean class="com.atguigu.interceptor.FirstInterceptor"></bean>
		<bean class="com.atguigu.interceptor.SecondInterceptor"></bean>
		<!-- 此方式要求拦截器类上必须加注解@Component -->
		<!-- <ref bean="firstInterceptor"/> -->
		
		<!-- 设置自定义拦截方式 -->
		<!-- <mvc:interceptor>
			<bean></bean>
			<mvc:mapping path=""/>
			<mvc:exclude-mapping path=""/>
		</mvc:interceptor> -->
	</mvc:interceptors>

</beans>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SpringMVC04</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <filter>
  	<filter-name>CharacterEncodingFilter</filter-name>
  	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>UTF-8</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>CharacterEncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- The front controller of this Spring Web application, responsible for handling all application requests -->
	<servlet>
		<servlet-name>springDispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springMVC.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- Map all requests to the DispatcherServlet for handling -->
	<servlet-mapping>
		<servlet-name>springDispatcherServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>
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 的执行顺序大致为:

  1. 请求到达 DispatcherServlet
  2. DispatcherServlet 发送至 Interceptor ,执行 preHandle
  3. 请求达到 Controller
  4. 请求结束后,postHandle 执行

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

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

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

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

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

 

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

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

 HandlerMapping的基础抽象类AbstractHandlerMapping中:

我们看到,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<byte[]> 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<byte[]> entity = new ResponseEntity<byte[]>(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";
	}
	
}

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

© 著作权归作者所有

architect刘源源

architect刘源源

粉丝 169
博文 564
码字总数 941209
作品 0
浦东
程序员
私信 提问
深入学习SpringMVC以及学习总结

一、优点: 1.SpringMVC简化web程序开发; 2.SpringMVC效率很好(单例模式); 3.SpringMVC提供了大量扩展点,方便程序员自定义功能; 如果想学习Java工程化、高性能及分布式、深入浅出。微服...

编程SHA
01/22
24
0
Spring Boot学习笔记

多模块开发 [SpringBoot学习]-IDEA创建Gradle多Module结构的SpringBoot项目 RabbitMQ RabbitMQ 安装 linux安装RabbitMQ详细教程 Ubuntu 16.04 RabbitMq 安装与运行(安装篇) ubantu安装...

OSC_fly
2018/07/26
0
0
SpringMVC+Spring+Mybatis整合应用(3)

实现图片上传 需求:在用户注册页面实现上传图片作为用户头像 1. springmvc中对多部件类型请求数据解析:在页面form中提交enctype="multipart/form-data"的数据时,需要springmvc对multipart...

江左煤郎
2018/12/03
32
0
Java个人技术知识点总结(框架篇)

框架篇 Struts1的运行原理 在启动时通过前端总控制器ActionServlet加载struts-config.xml并进行解析,当用户在jsp页面发送请求被struts1的核心控制器ActionServlet接收,ActionServlet在用户...

java架构
2018/11/08
0
0
在Spring-Boot中实现通用Auth认证的几种方式

前言 最近一直被无尽的业务需求淹没,没时间喘息,终于接到一个能让我突破代码舒适区的活儿,解决它的过程非常曲折,一度让我怀疑人生,不过收获也很大,代码方面不明显,但感觉自己抹掉了 ...

枕边书
2018/07/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

在Linux下使用linuxdeployqt发布Qt程序

目录 一、简介 二、安装linuxdeployqt 三、配置 qt 的环境变量 四、打包应用程序 五、编写linux桌面图标启动(可选步骤) 六、编写开机脚本 runApp.sh 七、打包成deb包 八、扩展 回到顶部 一...

shzwork
25分钟前
4
0
Linux进程管理

计算机硬件层面之上是操作系统,狭义的操作系统主要指系统内核,内核有以下作用:进程管理、文件系统、网络管理、内存管理、驱动程序、安全功能。内核可以将用户无法操作的底层硬件接口进行抽...

lhdzw
昨天
4
0
Java13的新特性

Java语言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的新特性 Java10的新特性 Java11的新特性 Java12的新特性 Java13的新特性 Java14的新特性 序 本文主要讲述...

go4it
昨天
7
0
IDEA 配置Springboot项目热部署

实现的方式概述 注意以下的热部署方式在IDEA是默认没有打开自动编译的,手动编译需要快捷键(Ctrl+Shift+F9),自动编译的修改配置如下:(注意刷新不要太快,会有1-2秒延迟) File-Settings-C...

小强的进阶之路
昨天
10
0
免费数据分析工具:secsoso

前段时间思考了理想数据分析平台,之后我们根据这个思路开发了spl语言并提供了一个数据分析平台,这个平台主要用在搜索ES,数据库索引中的数据。但后来发现对文件的事后处理也是个非常重要的...

赛克蓝德
昨天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部