SpringMVC原理、介紹及配置


SpringMVC

  Spring MVC是Spring提供的一個強大而靈活的web框架。借助於注解,Spring MVC提供了幾乎是POJO的開發模式,使得控制器的開發和測試更加簡單。這些控制器一般不直接處理請求,而是將其委托給Spring上下文中的其他bean,通過Spring的依賴注入功能,這些bean被注入到控制器中。

  Spring MVC主要由DispatcherServlet、處理器映射、處理器(控制器)、視圖解析器、視圖組成。\

兩個核心:

  處理器映射:選擇使用哪個控制器來處理請求.

  視圖解析器:選擇結果應該如何渲染.

Servlet有哪些功能:

  1. 根據URL 找到Servlet : 解析請求 -----> 找到對應的Servlet

  2. 處理請求 : 獲取請求的頭信息 獲取請求的數據

  3. 響應 : JSP HTML JSON Servlet:

    1. 將JSP內容,根據格式渲染HTML頁面

    2. 將HTML內容,直接渲染成HTML頁面

    3. JSON數據解析 : 字符串 resp.setContentType ("text/json;charset=UTF-8") :封裝了JSON對象 Javascript對象

    4. Servlet解析,調用
      解析:解析
      渲染:告訴瀏覽器 數據格式
     Servlet :

      1.解析URL
      2.處理請求
      3.處理數據
      4.渲染視圖

  盡可能職能是單一的,但是此時Servlet自身職能相對較多. 地址 各種if

  其二,本身Servlet 每個只能處理一個請求 。Service,當請求多時,需要定義多個Servlet

  對象多,代碼復用性降低,性能也會降低。

基於Servlet可能存在的問題:

  Servlet調用Service:AService  BService : 業務處理.

  Spring對Servlet進行了封裝:SpringMVC,這個框架只充當控制層.

SpringMVC原理圖

springMVC架構流程:

​ 1. 用戶發送請求到前端控制器DispatcherServlet

​ 2. DispatcherServlet 收到請求調用 HanderMapping 處理器映射器

​ 3. 處理器映射器根據請求 URL 找到具體的處理器,生成處理器對象及處理器攔截器(若有則生成)一並返回給 DispatcherServlet

​ 4. DispatcherServlet 通過 HandlerAdapter 處理器適配器調用處理器

​ 5. 執行處理器 Controller (也叫后端控制器)

​ 6. Controller 執行完成后返回 ModeAndView

​ 7. HandlerAdapter 將 controller 執行結果 ModeAndView 返回給 DispatcherServlet

​ 8. DispatcherServlet 將 ModeAndView 傳給 ViewReslover 視圖解析器

​ 9. ViewReslover 解析后返回具體 View

  1. DispatcherServlet 對 View 進行渲染視圖(即將模型數據填充至視圖中)

  2. DispatcherServlet 響應用戶

springmvc 的三大組件

  處理器映射器(HanderMapping)處理器適配器(HandlerAdapter)視圖解析器(ViewReslover)

springMVC流程原理:
  客戶端(瀏覽器)發送請求到DispatcherServlet(調度器),DispatcherServlet(調度器)收到請求后,根據請求調用HandlerMapping(處理器映射器),HandlerMapping(處理器映射器)根據請求的URL找到具體的處理器,處理器生成處理器對象返回給DispatcherServlet(調度器),DispatcherServlet(調度器)通過HandlerAdapter(處理器適配器)調用Handler(處理器),Handler(處理器)處理相應的Service(業務層)業務邏輯,Handler(處理器)處理完成后找到ModelAndView(模型視圖處理器)對象(Model是返回的數據對象(解析數據),View是一個邏輯上的View)傳給ViewResolver(視圖映射器)查找對應的View(邏輯視圖)進行視圖渲染(實際視圖),DispatcherServlet(調度器)把返回的Model傳給View,通過View響應給客戶端(瀏覽器)。

1. DispatcherServlet接口:

  Spring提供的前端控制器,所有的請求都有經過它來統一分發。在DispatcherServlet將請求分發給Spring Controller之前,需要借助於Spring提供的HandlerMapping定位到具體的Controller。

2. HandlerMapping接口:

  能夠完成客戶請求到Controller映射。

3. Controller接口:

  需要為並發用戶處理上述請求,因此實現Controller接口時,必須保證線程安全並且可重用。

  Controller將處理用戶請求,這和Struts Action扮演的角色是一致的。一旦Controller處理完用戶請求,則返回ModelAndView對象給DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和視圖(View)。

  從宏觀角度考慮,DispatcherServlet是整個Web應用的控制器;從微觀考慮,Controller是單個Http請求處理過程中的控制器,而ModelAndView是Http請求過程中返回的模型(Model)和視圖(View)。

4. ViewResolver接口:

  Spring提供的視圖解析器(ViewResolver)在Web應用中查找View對象,從而將相應結果渲染給客戶。

SpringMVC使用

  1. 下載相關jar包,由於SpringMVC是Spring提供的框架,Spring的jar中,,包含SpringMVC相關jar包
spring-web-4.3.24.RELEASE.jar
spring-webmvc-4.3.24.RELEASE.jar
  1. 配置DispatcherServlet,讓這個Servlet處理所有請求
<!-- 配置DispatcherServlet  調度器 -->
<servlet>
  	<servlet-name>springmvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<!-- 配置SpringMVC的映射器需要的文件 -->
  	<init-param>
  		<!-- 處理器映射器文件屬性名 -->
  		<param-name>contextConfigLocation</param-name>
  		<!-- 具體的處理器文件 -->
  		<param-value>classpath:spring-mvc.xml</param-value>
  	</init-param>
  	<!-- 配置啟動時機 -->
  	<load-on-startup>1</load-on-startup>
</servlet>
  
<servlet-mapping>
  	<servlet-name>springmvc</servlet-name>
  	<url-pattern>*.do</url-pattern>
</servlet-mapping>
  1. 定義處理器Handler

方式一:

package com.sxt.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.HttpRequestHandler;

public class Controller01 implements HttpRequestHandler   {
	@Override
	public void handleRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setAttribute("name", "Hello  Spring MVC");
		//跳轉到 info.jsp
		request.getRequestDispatcher("info.jsp").forward(request, response);
	}

}

方式二:

package com.sxt.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class Controller02 implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		ModelAndView modelAndView = new ModelAndView();
		// 設置model數據
		modelAndView.addObject("name", "Hello Spring MVC");
		// 設置視圖地址
		modelAndView.setViewName("info.jsp");
		return modelAndView;
	}

}
  1. 配置處理器,讓調度器通過處理器映射器找到處理器
<?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:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 處理器的配置文件 -->
	<!-- 注冊處理器 -->
	<bean name="/controller01.do" class="com.sxt.controller.Controller01"></bean>
	<bean name="/controller02.do" class="com.sxt.controller.Controller02"></bean>
	<!-- 掃描注解 -->
	<context:component-scan base-package="com.sxt"></context:component-scan>
	<!-- 讓 mvc 注解生效  -->	
	<mvc:annotation-driven></mvc:annotation-driven>
</beans>
  1. 請求
http://127.0.0.1:8080/springmvc/controller01.do

注解版

注解方式:

<!-- 掃描注解 -->
<context:component-scan base-package="com.sxt"></context:component-scan>
<!-- 讓 mvc 注解生效  -->	
<mvc:annotation-driven></mvc:annotation-driven>

定義處理器

package com.sxt.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Controller03 {

	@RequestMapping("/hello.do")
	public void hello(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
		req.setAttribute("name", "Hello Spring MVC");
		req.getRequestDispatcher("info.jsp").forward(req, resp);
	}
	
	@RequestMapping("/hello1.do")
	public ModelAndView hello1()  {
		ModelAndView  modelAndView = new ModelAndView();
		modelAndView.addObject("name",  "Hello Spring MVC");
		modelAndView.setViewName("info.jsp");
		return modelAndView;
	}
	
	
	@RequestMapping("/hello2.do")
	public String hello2(Model model)  {
		model.addAttribute("name",  "Hello Spring MVC");
		return "info.jsp";
	}
}

SpringMVC初始化流程:

DispatcherServlet : ---  init

DispatcherServlet 中沒有init 方法
	|--- DispatcherServlet的父類:FrameworkServlet
			|--- FrameworkServlet 沒有init方法 : FrameworkServlet的父類
				|--- HttpServletBean 中init方法 :   initServletBean () :
					|--- FrameworkServlet.initServletBean()
							|--- FrameworkServlet:initWebApplicationContext()
									|---FrameworkServlet.createWebApplicationContext() : 加載  springmvc的配置文件,且初始化handler對象
									|--- FrameworkServlet.onRefresh() : DispatcherServlet.onRefresh(WebApplicationContext)
									|--- DispatcherServlet.initStrategies(ApplicationContext) : 初始化DispatcherServlet 從DispatcherServlet.properties 進行默認的配置

@RequestMapping

@GetMapping/@PostMapping

value/path : 映射地址:

  該注解可以使用在類上面,也可以使用在方法上面.映射地址,是按照類上面該注解的value/path屬性值與方法上面value/path屬性進行拼接,組成URL路徑.

method : 支持的請求方式.若不寫,則默認GET和POST請求都支持.

在Spring新的版本中,使用 @PostMapping代理method為post,@GetMapping代替了method為get

params:限定請求中必須含有的參數

headers:限定請求中必須包含的請求頭信息

consumes:限定請求的數據格式

produces:限定返回的數據格式

數據綁定-獲取請求參數

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="user/add.do">
	<p>用戶名:<input type="text"  name="userName1"/></p>
	<p>密碼:<input type="text"  name="password"/></p>
	<p>年齡:<input type="text"  name="age"/></p>
	<input type="submit" value="提交">
</form>
<hr>
<form action="user/add2.do">
	<p>用戶名:<input type="text"  name="userName"/></p>
	<p>密碼:<input type="text"  name="password"/></p>
	<p>年齡:<input type="text"  name="age"/></p>
	<input type="submit" value="提交">
</form>
<hr>
<form action="user/add3.do">
	<p>用戶名:<input type="text"  name="userName1"/></p>
	<p>密碼:<input type="text"  name="password1"/></p>
	<p>年齡:<input type="text"  name="age1"/></p>
	<input type="submit" value="提交">
</form>
<hr>
<form action="user/add4.do">
	<p>用戶名:<input type="text"  name="userName1"/></p>
	<p>密碼:<input type="text"  name="password1"/></p>
	<p>年齡:<input type="text"  name="age1"/></p>
	<input type="submit" value="提交">
</form>
<h2>map</h2>
<form action="user/add5.do">
	<p>用戶名:<input type="text"  name="userName1"/></p>
	<p>密碼:<input type="text"  name="password1"/></p>
	<p>年齡:<input type="text"  name="age1"/></p>
	<input type="submit" value="提交">
</form>
<h2>list</h2>
<form action="user/add6.do">
	<p>愛好:
		<input type="checkbox"  name="like" value="籃球"/>
		<input type="checkbox"  name="like" value="足球"/>
		<input type="checkbox"  name="like" value="羽毛球"/>
		<input type="checkbox"  name="like" value="乒乓球"/>
	</p>
	<input type="submit" value="提交">
</form>
<h2>格式化</h2>
<form action="user/add7.do">
	<p>用戶名:<input type="text"  name="userName"/></p>
	<p>密碼:<input type="text"  name="password"/></p>
	<p>生日:<input type="text"  name="age"/></p>
	<input type="submit" value="提交">
</form>
<h2>格式化</h2>
<form action="user/add8.do">
	<p>用戶名:<input type="text"  name="userName"/></p>
	<p>密碼:<input type="text"  name="password"/></p>
	<p>生日:<input type="text"  name="age"/></p>
	<input type="submit" value="提交">
</form>
</body>
</html>
package com.sxt.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.sun.xml.internal.ws.client.RequestContext;
import com.sxt.pojo.User;

@Controller
@RequestMapping("/user")
public class UserController {

	/**
	 *  簡單的數據類型綁定
	 * 	在SpringMVC中,獲取請求參數參數,只需要方法中形式參數的名稱與請求的數據的name屬性值一致,就可以自動的綁定相關參數 且簡單數據類型可以自動進行數據轉換.
	 * @param userName
	 * @param password
	 * @param age
	 * @return: void
	 */
	@RequestMapping("/add.do")
	public void add(String userName,String password,Integer age) {
		System.out.println(userName);
		System.out.println(password);
		System.out.println(age);
	}
    
	/**
	 *  獲取請求的參數,且將其封裝到對象中
	 * 		1. 創建對象
	 * 		2.屬性注入 根據set方法進行屬性注入
	 * @param user
	 * @return: void
	 */
	@RequestMapping("/add2.do")
	public void add(User user)  {
		System.out.println(user);
	}
	
	/**
	 * 請求參數名稱和形式參數名稱不一致時  可以使用@RequestParam 別名
	 * @param userName
	 * @param password
	 * @param age
	 * @return: void
	 */
	@RequestMapping("/add3.do")
	public void add3(@RequestParam("userName1")String userName,@RequestParam("password1")String password,@RequestParam("age1")Integer age)  {
		System.out.println(userName);
		System.out.println(password);
		System.out.println(age);
	}
	
	/**
	 * name/value  參數別名
	 * required : 是否是必須傳遞的參數  默認是true
	 * defaultValue : 當這個參數沒有的時候的默認值				
	 * @param userName
	 * @param password
	 * @param age
	 * @return: void
	 */
	@RequestMapping("/add4.do")
	public void add4(@RequestParam(name="userName1",required = false,defaultValue = "我是默認值")String userName,@RequestParam("password1")String password,@RequestParam("age1")Integer age)  {
		System.out.println(userName);
		System.out.println(password);
		System.out.println(age);
	}
	/**
	 * 使用Map接收請求參數
	 * @param map
	 * @return: void
	 */
	@RequestMapping("/add5.do")
	public void add4(@RequestParam Map<String,Object> map)  {
		System.out.println(map);
	}
	/**
	 * 接收數組格式的參數
	 * @RequestParam("參數名稱")
	 * @param like
	 * @return: void
	 */
	@RequestMapping("/add6.do")
	public void add6(@RequestParam("like")List<String> like)  {
		System.out.println(like);
	}
	/**
	 * 將字符串格式化 時間對象
	 * @param userName
	 * @param password
	 * @param age
	 * @return: void
	 */
	@RequestMapping("/add7.do")
	public void add6(String userName,String password,@DateTimeFormat(pattern = "yyyy-MM-dd")Date age)  {
		System.out.println(userName);
		System.out.println(password);
		System.out.println(age);
	}
	
	@RequestMapping("/add8.do")
	public void add6(User user)  {
		System.out.println(user);
	}
	/**
	 * 內置對象的注入
	 * @return: void
	 */
	@RequestMapping("/httpObj.do")
	public void httpObj(HttpServletRequest req,HttpServletResponse resp,HttpSession session,Model mode) {
		System.out.println(mode);
		System.out.println(req);
		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes req1 = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		System.out.println(req1.getRequest().getServletContext());
		System.out.println(requestAttributes);
		System.out.println(resp);
		System.out.println(session);
	}
}

WebUtil

package com.sxt.util;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class WebUtil {
	
	/**
	 * 獲取當前請求對象
	 * @return
	 * @return: HttpServletRequest
	 */
	public HttpServletRequest getRequest() {
		ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
		return servletRequestAttributes.getRequest();
	}
	/**
	 * 獲取當前Session
	 * @return
	 * @return: HttpSession
	 */
	public HttpSession getSession() {
		return getRequest().getSession();
	}
	/**
	 *  獲取當前ServletContext 容器
	 * 	當項目直接啟動時,可能需要向ServletContext 設置全局參數
	 * 	如果直接使用 request.getServletContext() 會空指針異常
	 *  所以需要根據WebApplicationContext 獲取
	 * @return
	 * @return: ServletContext
	 */
	public ServletContext ServletContext() {
		HttpServletRequest request = getRequest();
		// 若當前請求存在 則直接從當前請求中獲取ServletContext
		if(request != null) {
			return request.getServletContext();
		}else {
			// 若不存在則根據WebApplicationContext 獲取當前ServletContext
			return ContextLoader.getCurrentWebApplicationContext().getServletContext();
		}
	}
}

編碼過濾器

<filter>
  	<filter-name>charset</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>charset</filter-name>
  	<!-- 此時配置 只過濾 springmvc請求 -->
  	<servlet-name>springmvc</servlet-name>
</filter-mapping>

關於SpringMVC跳轉

 SpringMVC中,默認是使用內部轉發.

 如果需要使用重定向:redirect:地址

package com.sxt.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/user")
public class UserController {
	/**
	 * springmvc 默認是使用內部轉發
	 * @return
	 * @return: String
	 */
	@RequestMapping("list.do")
	public String list() {
		return "/list.jsp";
	}
    
	/**
	 * 若想使用 重定向 :
	 * 		redirect: 地址
	 * @return
	 * @return: String
	 */
	@RequestMapping("list2.do")
	public String list2() {
		return "redirect:/list.jsp";
	}
	
	@RequestMapping("list3.do")
	public ModelAndView list3() {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("/list.jsp");
		return modelAndView;
	}
	
	@RequestMapping("list4.do")
	public ModelAndView list4() {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("redirect:/list.jsp");
		return modelAndView;
	}
	
}

配置視圖解析器

<!-- 配置視圖解析器 -->
<!-- 
	配置 SpringMVC視圖解析器時 
	 	其前后綴 只對 內部轉發生效
 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<!-- 配置視圖解析器前綴 -->
	<property name="prefix" value="/WEB-INF/jsp"></property>
	<!-- 配置視圖解析器后綴 -->
	<property name="suffix" value=".jsp"></property>
</bean>

springmvc返回json數據

package com.sxt.controller;

import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/user")
public class UserController {
	/**
	 * @Title: list
	 * @author: Mr.T   
	 * @date: 2019年11月26日 下午2:35:12 
	 * @Description: 在springmvc中,方法返回的字符串,默認會當做路徑處理.springmvc 默認會解析該路徑,
	 * 		因為springmvc 提供了注解 @ResponseBody, 表示該方法返回的是字符,阻止springmvc 當做路徑處理
	 * 		默認是用  @ResponseBody 時  中文亂碼, 需要設置編碼格式  數據格式
	 * @return
	 * @return: String
	 * @throws JSONException 
	 */
	@RequestMapping(value ="/list.do",produces = "text/json;charset=UTF-8" )
	@ResponseBody
	public String  list() throws JSONException {
		System.out.println("==============");
		String msg = "{'name':'張三','age':18}";
		JSONObject json = new JSONObject();
		json.put("name", "張三");
		json.put("age", 18);
		System.out.println(json.toString());
		msg = json.toString();
		return msg;
	}

}

@RestController

  RestController 繼承了Controller和ResponseBody,當controller類被RestController修飾時,其下面所有的方法,返回的結果,都會當做字符串輸出瀏覽器. 等價於,在一個類上面定義Controller和ResponseBody.

  一般若用於接口開發,都使用RestController ,若controller不需要進行頁面跳轉,則可以直接使用RestController。否則(若controller需要頁面跳轉),只能使用@Controller。

@ResponseBody

  @ResponseBody: 可以作用於方法上和類上面,若作用於方法上,則該方法的返回值,當做字符串輸出給客戶端.若作用於類上面,則該類中的所有方法的返回值,當做字符串輸出給客戶端.

springmvc返回json對象

  在springmvc中,默認是使用jackson進行數據解析,進行返回.若返回的結果是一個json對象.可以直接返回.

但是需要導入jackson的相關jar包.

jackson-annotations-2.9.9.jar
jackson-core-2.9.9.jar
jackson-databind-2.9.9.jar
@RequestMapping("/list.do")
public Object list() throws JSONException {
	Map<String,Object> map = new HashMap<String,Object>();
	map.put("name", "韓梅梅");
	return map;
}

@RequestMapping("/list3.do")
public Object list3() throws JSONException {
	User user = new User(1, "韓梅梅", 18);
	return user;
}

文件上傳和下載

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="file/upload.do" method="post" enctype="multipart/form-data">
		文本:<input type="text" name="userName" /><br>
		文件:<input type="file" name="fileName" /><br>
			<input type="submit" value="提交" />
	</form>
</body>
</html>

spring-mvc.xml

<!-- 配置解析二進制數據解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

文件上傳

package com.lyang.controller;

import java.io.File;
import java.io.IOException;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

@Controller
@RequestMapping("/file")
public class FileUploadController {

	@RequestMapping("/upload.do")
	public void upload(@RequestParam("fileName")MultipartFile file,String userName) throws IOException {
		// 獲取提交的 input name的屬性值
		System.out.println(file.getName());
		// 獲取文件真實名稱
		System.out.println(file.getOriginalFilename());
		// 獲取數據的格式
		System.out.println(file.getContentType());
		// 獲取文件的輸入流
		System.out.println(file.getInputStream());
		// 獲取文件的大小(字節)
		System.out.println(file.getSize());
		// 文件進行保存
		file.transferTo(new File("D:\\uploadTest.jpg"));
	}

}

文件下載

package com.lyang.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/file")
public class FileDownloadController {

	@RequestMapping("/download.do")
	public void downLoad(HttpServletResponse resp) {
		// 找到需要被下載的文件
		File file = new File("D:\\download.jpg");
		// 創建輸入流 讀取文件
		FileInputStream fis = null;
		// 輸出流
		OutputStream ops = null;
		// 設置數據格式為二進制輸數據流,讓瀏覽器不要進行解析
		resp.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
		try {
			// 設置響應頭信息 告訴瀏覽器 文件的相關信息 文件的名稱 漢字時 容易出現亂碼不識別問題 需要 編碼
			String fileName = URLEncoder.encode("下載.jpg", "UTF-8");
			resp.addHeader("Content-Disposition", "form-data;name=\"img\";filename=\"" + fileName + "\"");
			// 輸入流綁定需要讀取的文件!
			fis = new FileInputStream(file);
			// 獲取與客戶端綁定的數據流
			ops = resp.getOutputStream();
			byte[] data = new byte[1024];
			int len = -1;
			while ((len = fis.read(data)) != -1) {
				// 向客戶端輸出
				ops.write(data, 0, len);
				ops.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fis.close();
				ops.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	@RequestMapping("download2.do")
	public ResponseEntity<byte[]> downLoad2(){
		// 找到需要被下載的文件
		File file = new File("D:\\download.jpg");
		// 存儲文件數據的容器
		byte[] fileByte = null;
		ResponseEntity<byte[]> entity = null;
		try {
			// 將文件一次性讀到內存中
			fileByte = FileUtils.readFileToByteArray(file);
			// 創建響應頭
			HttpHeaders headers = new HttpHeaders();
			// 設置MediaType  為二進制 避免瀏覽器解析
			headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			// 設置文件的名稱	 如果名稱是中文,需要進行轉碼
			String fileName = URLEncoder.encode("下載.jpg", "UTF-8");
			headers.setContentDispositionFormData("filename", fileName);
			entity = new ResponseEntity<byte[]>(fileByte, headers, HttpStatus.OK);
		} catch (IOException e) {
			e.printStackTrace();
		} 
		return entity;
	}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM