springmvc图片上传之后无法立刻查看_框架学习:SpringMvc学习(二)

一、请求转发与重定向

1、请求转发是一次请求,转发之后地址栏不发生改变 
2、重定向是两次请求,地址栏会发生改变         
3、重定向时的网址可以是任何网址,转发的网址必须是本站点的网址
4、当两个资源文件之间需要传递数据的时候,使用转发
当两个资源文件不需要传递数据的时候,使用重定向

代码说明

//后端控制器
@Controller  //该注解表明将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用,类体的可以省略
public class MyController{
	@RequestMapping("/hello")//方法体注解
	public ModelAndView hello(@RequestParam("username")String name, int age){
		ModelAndView mav = new ModelAndView();
		mav.addObject("username",name);
		mav.addObject("age", age);
		//mav.setViewName("NewFile");请求转发
		mav.setViewName("redirect:hello1");//重定向到另一个服务器方法
		return mav;
	}

二、文件上传:

导入jar包:
com.springsource.org.apache.commons.fileupload-1.2.0.jar
com.springsource.org.apache.commons.io-1.4.0.jar
修改jsp页面:
 注意:
	form表单中的enctype属性就是encodetype就是编码类型的意思
	默认情况下,enctype的值是application/x-www-form-urlencoded,不能用于文件上传,只有使用了multipart/form-data,才能完整的传递文件数据。
<!-- 注册视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       	<property name="prefix" value="/jsp/"></property><!-- 前缀 -->
       	<property name="suffix" value=".jsp"></property>
</bean>

1、springMvc.xml

<?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"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
        
       <!--注册后端控制器  -->
       <!-- <bean id="/my.do" class="com.sxt.handlers.MyController"></bean> -->
       <!-- 注册组件扫描器   base-package="所在包名"-->
       <context:component-scan base-package="com.sxt.handlers"></context:component-scan>
       <!-- 注册视图解析器 -->
       <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       		<property name="prefix" value="/jsp/"></property><!-- 前缀 -->
       		<property name="suffix" value=".jsp"></property>
       </bean>
       <!-- 注解驱动 -->
       <mvc:annotation-driven/>
       <!-- 注册文件上传解析器  id名字不能随意起要用multipartResolver前端控制器会调用multipartResolver去查找bin -->
       <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
       		<property name="defaultEncoding" value="UTF-8"/><!-- 解决乱码问题 -->
       </bean>
       <!-- 静态资源无法释放第二种解决方案 -->
      <!--  <mvc:default-servlet-handler/> -->
       <!-- 静态资源无法释放第二种解决方案 -->
       <mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
    
</beans>

2、单上传:

1)、jsp

<form action="springmvc/fileUpload" method="post" enctype="multipart/form-data">
			名称:<input type="file" name="img"><br/>
			<input type="submit" value="上传">
</form>

2)、controller

//后端控制器
@Controller  //该注解表明将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用,类体的可以省略
public class MyController{
	@RequestMapping("/fileUpload")//方法体注解
	public ModelAndView fileUpload(MultipartFile img){
		ModelAndView mav = new ModelAndView();
		String fileName = img.getOriginalFilename();//获取源文件名
		String path = "D:/";//路径
		File file = new File(path,fileName);
		try {
			img.transferTo(file);//文件上传
		} catch (IllegalStateException e) {	
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		mav.setViewName("NewFile");
		return mav;	
	}
}

3、多文件上传

1)、jsp

<form action="springmvc/fileUpload" method="post" enctype="multipart/form-data">
			<input type="file" name="imgs"><br/>
			<input type="file" name="imgs"><br/>
			<input type="file" name="imgs"><br/>
			<input type="submit" value="上传">
</form>

2)、controller

//后端控制器
@Controller  //该注解表明将当前类交给spring容器管理
@Scope("prototype")
@RequestMapping("/springmvc") //该注解起到限定范围的作用,类体的可以省略
public class MyController{
	@RequestMapping("/fileUpload")//方法体注解
	public String fileUpload(@RequestParam MultipartFile [] imgs,HttpSession session){
		System.out.println("ok");
		String 	path = session.getServletContext().getRealPath("/");//获取根路径
		for (MultipartFile img : imgs) {
			String fileName = img.getOriginalFilename();//获取源文件名
			File file = new File(path,fileName);
			try {
				img.transferTo(file);//文件上传
			} catch (IllegalStateException e) {	
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return "NewFile";
	}
}

三、文件下载

1、流程

1)、指定下载文件

2)、获取流预估文件的字节数

3)、创建字节数组,并设置数组大小为流预估的文件字节数

4)、将输入流中字符存储到缓存数组中

5)、获取下载文件名,并解决中文乱码问题

6)、设置Http响应信息

7)、设置Http响应状态信息

2、代码实现

@RequestMapping("/fileDownload")//方法体注解
	public  ResponseEntity<byte []> download() throws Exception{
		//指定下载文件
		File file = new File("D:/Springmvc运行流程.png");
		//获取流预估的文件字节数
		FileInputStream is = new FileInputStream(file);
		//创建字节数组,并设置数组大小为流预估的文件字节数
		byte [] body= new byte[is.available()];
		//将输入流中字符存储到缓存数组中
		is.read(body);
		//获取下载文件名,并解决中文乱码问题
		String name = file.getName();
		String downloadName = new String(name.getBytes("UTF-8"),"ISO-8859-1");
		//设置Http响应信息,
		HttpHeaders httpHandlers = new HttpHeaders();
		httpHandlers.add("Content-Disposition","attchment;filename="+downloadName );
		//设置Http响应状态信息
		HttpStatus status = HttpStatus.OK;
		ResponseEntity<byte[]> entity = new ResponseEntity<> (body,httpHandlers,status);	
		return entity;
	}	

四、自定义拦截器

1、创建前端控制器。
2、创建后端控制器。
3、创建jsp,form表单提交地址为后端控制器。

4、创建类,实现HandlerInterceptor接口,重写未实现方法。
   		接口内定义的方法:
			preHandle,在处理器执行之前会触发这个postHandle拦截器的执行。该方法的返回值是boolean类型,如果返回结果为false,
则说明拦截,如果为true,则preHandle可以继续往下执行后端处理器方法。
			postHandle,在处理器方法执行之后会触发这个preHandle拦截器的执行。该方法无返回值。
			afterCompletion,在所有方法完成之后会触发afterCompletion拦截器的执行,
按SpringMVC流程来说应该是在要响应给浏览器的时候触发这个拦截器的执行。该方法无返回值。
5、在SpringMVC的配置文件中进行注册。

配置

<!-- 注册拦截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
 				<!-- 拦截所有-->
				<mvc:mapping path="/**" />
				<!-- 不包括/springmvc/hello2-->
				<mvc:exclude-mapping path="/springmvc/hello2"/>
				<!-- 只拦截/springmvc/hello2 -->
                          <!-- <mvc:mapping path="/springmvc/hello2" /> -->
		<!-- 注册自定义拦截器 -->			
		<bean id="handelInterceptor" class="com.interceptor.HandelInterceptor"></bean>
	</mvc:interceptor>

自定义拦截器类(注意需实现HandlerInterceptor接口)

//自定义拦截器
public class FirstInterceptor implements HandlerInterceptor {

	//该方法执行时机,所有工作处理完成之后,响应给浏览器客户端之前
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("afterCompletion执行");
	}
	//该方法执行时机,处理器方法执行之后
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("postHandle执行");
		
	}
	//该方法执行时机,处理器方法执行之前
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
	System.out.println("执行preHandle()方法");
		return true;//返回false不能向下继续执行,返回true
	}
}

多个自定义拦截器执行顺序(注意与在springmvc中的配置顺序有关)

代码:

<!-- 注册拦截器 -->
       <mvc:interceptors>
       		<mvc:interceptor>
       			<mvc:mapping path="/**"/><!-- 拦截所有 -->
       			<bean id="" class="com.sxt.interceptor.FirstInterceptor"></bean>
       		</mvc:interceptor>
       		<mvc:interceptor>
       			<mvc:mapping path="/**"/><!-- 拦截所有 -->
       			<bean id="" class="com.sxt.interceptor.SecondInterceptor"></bean>
       		</mvc:interceptor>
       </mvc:interceptors>

06271a74cf2b777ae5d96a1d13e5b492.png

结果

fbfe0d7f8a9fe6bec54191497aee5050.png
preHandle源码:
1、找到applyPreHandle方法。
2、方法内部,getInterceptors()获得所有的拦截器,然后判断拦截器是否为空,如果不为空,则执行循环。
目前是两个拦截器,那么执行for循环,for循环中i目前为0,小于2个拦截器的长度,执行for循环。
在for循环中将i=0赋值给interceptor。继续执行if语句。
if语句,第一个拦截器中的preHandle方法,目前返回为true,但是取反就是false,那么if语句就不再执行,跳出if语句,将i赋值给临时变量interceptorIndex。

当循环到i++=2的时候,判断条件就不成立了,就跳出循环,此时的interceptorIndex=1;
也就是说preHandle执行顺序,先执行第一个,然后执行第二个,最后返回为true。

Spring和SpringMVC关系:

在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的。
而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系。
目前最常见的一种场景就是在一个项目中引入Spring和SpringMVC这两个框架,那么它其实就是两个容器,Spring是父容器,SpringMVC是其子容器,
并且在Spring父容器中注册 的Bean对于SpringMVC容器中是可见的,而在SpringMVC容器中注册的Bean对于Spring父容器 中是不可见的,
也就是子容器可以看见父容器中的注册的Bean,反之就不行。

f7cf020ef3b7e5ad904651f5c4349785.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值