文章目錄
- 項目源碼地址
- 回顧-MVC
- 什么是MVC?
- MVC各部分組成
- 回顧-Servlet
- Maven創建Web項目
- 1、創建Maven父工程pom,并導入依賴
- 2、用Maven新建一個Web Module
- 3、代碼:HelloServlet.java
- 3、代碼-hello.jsp
- 3、代碼-web.xml
- 4、配置Tomcat
- 5、瀏覽器測試
- Maven創建jar項目,并手動添加web依賴
- 初識SpringMVC
- SpringMVC的基礎知識
- DispatcherServlet:中心控制器
- SpringMVC執行原理
- 第一個SpringMVC程序
- xml配置實現
- 1、在上述父工程下,創建一個Web Module
- 2、配置web.xml,注冊DispatchServlet
- 3、編寫Spring MVC的配置文件【不同】
- 4、編寫操作業務Controller【不同】
- 5、編寫要跳轉的jsp頁面
- 6、啟動測試
- annotation注解實現
- 1、在上述父工程下,創建一個Web Module
- 2、配置web.xml,注冊DispatchServlet
- 3、編寫Spring MVC的配置文件【不同】
- 4、編寫操作業務Controller【不同】
- 5、編寫要跳轉的jsp頁面
- 6、啟動測試
- 控制器:Controller
- 控制器的作用
- 控制器實現
- 項目Module名稱
- 實現--接口定義
- 實現--注解實現
- 總結
- 注解:@RequestMapping
- 作用
- 示例
- RestFul風格
- 什么是RestFul?
- RestFul
- 資源和資源操作
- 資源操作方法對比
- 示例
- 代碼
- 應用:@PathVariable
- 應用:method屬性
- 應用:@GetMapping、......
- 數據處理及跳轉
- 項目Module名稱
- 結果跳轉
- ModelAndView
- ServletAPI
- SpringMVC-無需視圖解析器
- SpringMVC-有視圖解析器
- 數據處理-提交到后端的數據
- 數據處理-數據顯示到前端
- 亂碼處理
- 方法1-springMVC-過濾器
- 方法2-Tomcat修改配置文件
- 方法3-自定義過濾器
- 總結
- Json
- 項目Module名稱
- 什么是Json?
- 概念
- 語法格式
- Json和JavaScript的區別
- Json和JavaScript的相互轉換
- Controller返回Json數據:jackson
- Module準備
- Controller核心代碼
- 統一處理亂碼問題
- Controller返回Json數據:fastjson
- Module準備
- fastjson三大核心類
- 數據類型相互轉換
- Ajax
- 攔截器:Interceptor
- 什么是攔截器?
- 概念
- 過濾器和攔截器的區別
- 攔截器使用
- 文件上傳和下載
- Module準備
- 核心代碼展示
- 前端頁面
- Controller
項目源碼地址
GitHub | https://github.com/Web-Learn-GSF/Java_Learn_Examples |
---|---|
父工程 | Java_Framework_SpringMVC |
回顧-MVC
什么是MVC?
MVC是(Model、View、Controller的縮寫)一種軟件設計規范,將業務邏輯、數據、顯示三者分離開來組織代碼
MVC主要作用是降低了視圖與業務邏輯間的雙向耦合
MVC各部分組成
模塊 | 組成 |
---|---|
Model(模型) | 提供要展示的數據,可以認為是領域模型或JavaBean組件(包含數據和行為) |
View(視圖) | 負責進行模型的展示,一般就是我們見到的用戶界面,客戶想看到的東西 |
Controller(控制器) | 接收用戶請求,委托給模型進行處理(狀態改變),處理完畢后把返回的模型數據返回給視圖,由視圖負責展示。也就是說控制器做了個調度員的工作 |
回顧-Servlet
這一章將講述兩種創建Web項目的方法來回顧servlet:
-
Maven創建web項目,運行servlet
-
Maven創建jar項目,手動添加框架依賴,運行servlet**(還沒調試通順,后續有空繼續整)**
同時也將講述Tomcat9和Tomcat10在servlet包依賴上的不同
Maven創建Web項目
1、創建Maven父工程pom,并導入依賴
- 若Tomcat版本為10,依賴導入
<dependencies><!-- 沒有爭議的依賴 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.0.9</version></dependency><!-- 有版本爭議的依賴:servlet、jsp--><!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-servlet-api --><dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-servlet-api</artifactId><version>10.0.4</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jsp-api --><dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jsp-api</artifactId><version>10.0.4</version></dependency></dependencies>
- 若Tomcat版本為9,依賴導入
<dependencies><!-- 沒有爭議的依賴 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.0.9</version></dependency><!-- 有版本爭議的依賴:servlet、jsp--><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency>
</dependencies>
Tomcat9及以前,servlet依賴包名是 javax.servlet;Tomcat10之后,servlet依賴包名是 jakarta.servlet
如若不注意版本匹配,啟動Tomcat會爆出404問題
2、用Maven新建一個Web Module
Module名字:Demo-01-ServletReview-MavenWebCreate
Module內容解釋:
- pom文件里面的packaging標簽是war
整體結構及后續代碼
- Maven創建的web項目,webapp在main目錄下,跟手動添加web依賴所在的目錄不一樣
3、代碼:HelloServlet.java
Tomcat版本為10的代碼
package GSF.Example.Servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//取得參數String method = req.getParameter("method");if ("add".equals(method)){req.getSession().setAttribute("msg","執行了add方法");}if ("delete".equals(method)){req.getSession().setAttribute("msg","執行了delete方法");}//業務邏輯:暫無//視圖跳轉req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
Tomcat版本為9的代碼
package GSF.Example.Servlet;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//取得參數String method = req.getParameter("method");if ("add".equals(method)){req.getSession().setAttribute("msg","執行了add方法");}if ("delete".equals(method)){req.getSession().setAttribute("msg","執行了delete方法");}//業務邏輯:暫無//視圖跳轉req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
區別:包的名字
- Tomcat10:jakarta.servlet
- Tomcat9:javax.servlet
3、代碼-hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head><title>Kuangshen</title>
</head>
<body>
${msg}
</body>
</html>
- web2.4之后,默認禁止el表達式,即${}不會從session域中獲取數據
- 通過添加上邊的第二行代碼:
<%@ page isELIgnored="false" %>
,可以關閉對el表達式的禁止,實現從session域中獲取數據
3、代碼-web.xml
Maven創建web項目,默認的web.xml文件內容
- 頭文件不太對勁,但是能用
- 有空再探討具體有啥區別
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>GSF.Example.Servlet.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/user</url-pattern></servlet-mapping></web-app>
若是手動添加框架依賴,創建的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>GSF.Example.Servlet.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/user</url-pattern></servlet-mapping></web-app>
4、配置Tomcat
- 暫不清楚為啥要選這個,也不知道選不帶有war exploded的會有啥問題
5、瀏覽器測試
- localhost:8080/user?method=add
- localhost:8080/user?method=delete
Maven創建jar項目,并手動添加web依賴
暫時沒調試通順
初識SpringMVC
SpringMVC的基礎知識
Spring MVC是Spring Framework的一部分,是基于Java實現MVC的輕量級Web框架
官方文檔:https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web
Spring MVC特點
- 輕量級,簡單易學
- 高效 , 基于請求響應的MVC框架
- 與Spring兼容性好,無縫結合
- 約定優于配置
- 功能強大:RESTful、數據驗證、格式化、本地化、主題等
- 簡潔靈活
Spring的web框架圍繞DispatcherServlet [ 調度Servlet ] 設計。
DispatcherServlet的作用是將請求分發到不同的處理器。從Spring 2.5開始,使用Java 5或者以上版本的用戶可以采用基于注解形式進行開發,十分簡潔。
DispatcherServlet:中心控制器
Spring的web框架圍繞DispatcherServlet設計:
- DispatcherServlet的作用是將請求分發到不同的處理器
- 從Spring 2.5開始,使用Java 5或者以上版本的用戶可以采用基于注解的controller聲明方式
Spring MVC框架像許多其他MVC框架一樣, 以請求為驅動 , 圍繞一個中心Servlet分派請求及提供其他功能,DispatcherServlet是一個實際的Servlet (它繼承自HttpServlet 基類)
SpringMVC執行原理
實現部分:表示框架已經幫忙完成;虛線部分:表示需要我們手動編寫的地方
步驟1:
- DispatcherServlet表示前置控制器,是整個SpringMVC的控制中心。用戶發出請求,DispatcherServlet接收請求并攔截請求
- 假設請求的url為 : localhost:8080/SpringMVC/hello
- web.xml中定義,攔截所有請求
<servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--關聯一個springmvc的配置文件:【servlet-name】-servlet.xml--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-servlet.xml</param-value></init-param><!--啟動級別-1--><load-on-startup>1</load-on-startup></servlet><!--/ 匹配所有的請求;(不包括.jsp)--><!--/* 匹配所有的請求;(包括.jsp)--><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
步驟2:
- HandlerMapping為處理器映射,被DispatcherServlet調用
- HandlerMapping根據請求url查找Handler
- springmvc-servlet.xml中注冊HandlerMapping的bean
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
步驟3:
- HandlerExecution表示具體的Handler,其主要作用是根據url查找控制器
- 如上url被查找控制器為:hello
步驟4:
- HandlerExecution將解析后的信息傳遞給DispatcherServlet
- 解析后的信息:處理器對象及處理器攔截器
步驟5:
- HandlerAdapter表示處理器適配器,其按照特定的規則去執行Handler
- springmvc-servlet.xml中注冊HandlerAdapter的bean
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
步驟6:
- Handler讓具體的Controller執行
- springmvc-servlet.xml中注冊Handler的bean
<bean id="/hello" class="GSF.Example.Controller.HelloController"/>
步驟7:
- Controller將具體的執行信息返回給HandlerAdapter
- 返回的信息如:ModelAndView
步驟8:
- HandlerAdapter將視圖邏輯名或模型傳遞給DispatcherServlet
步驟9:
- DispatcherServlet調用視圖解析器(ViewResolver)來解析HandlerAdapter傳遞的邏輯視圖名
- springmvc-servlet.xml中注冊bean,并完成相關配置
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"><!--前綴--><property name="prefix" value="/WEB-INF/jsp/"/><!--后綴--><property name="suffix" value=".jsp"/>
</bean>
步驟10:
- 視圖解析器將解析的邏輯視圖名傳給DispatcherServlet
步驟11:
- DispatcherServlet根據視圖解析器解析的視圖結果,調用具體的視圖
步驟12:
- 最終視圖呈現給用戶
第一個SpringMVC程序
xml配置實現
1、在上述父工程下,創建一個Web Module
Module名字:Demo-02-SpringMVC-xml
整體結構圖及后續寫入代碼
2、配置web.xml,注冊DispatchServlet
- web.xml
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--1.注冊DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--關聯一個springmvc的配置文件:【servlet-name】-servlet.xml--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-servlet.xml</param-value></init-param><!--啟動級別-1--><load-on-startup>1</load-on-startup></servlet><!--/ 匹配所有的請求;(不包括.jsp)--><!--/* 匹配所有的請求;(包括.jsp)--><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>
3、編寫Spring MVC的配置文件【不同】
- springmvc-servlet.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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/><!--視圖解析器:DispatcherServlet給他的ModelAndView--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"><!--前綴--><property name="prefix" value="/WEB-INF/jsp/"/><!--后綴--><property name="suffix" value=".jsp"/></bean><!--Handler--><bean id="/hello" class="GSF.Example.Controller.HelloController"/></beans>
4、編寫操作業務Controller【不同】
- HelloController.java
package GSF.Example.Controller;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;//注意:這里我們先導入Controller接口
public class HelloController implements Controller {public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {//ModelAndView 模型和視圖ModelAndView mv = new ModelAndView();//封裝對象,放在ModelAndView中。Modelmv.addObject("msg","HelloSpringMVC!");//封裝要跳轉的視圖,放在ModelAndView中mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jspreturn mv;}
}
- 在springmvc-servlet.xml中注冊該實現類的bean
5、編寫要跳轉的jsp頁面
- hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head><title>Kuangshen</title>
</head>
<body>
${msg}
</body>
</html>
6、啟動測試
- localhost:8080/hello
annotation注解實現
1、在上述父工程下,創建一個Web Module
Module名稱:Demo-02-SpringMVC-annotation
整體結構圖及后續寫入代碼
2、配置web.xml,注冊DispatchServlet
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--1.注冊servlet--><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:springmvc-servlet.xml</param-value></init-param><!-- 啟動順序,數字越小,啟動越早 --><load-on-startup>1</load-on-startup></servlet><!--所有請求都會被springmvc攔截 --><servlet-mapping><servlet-name>SpringMVC</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>
3、編寫Spring MVC的配置文件【不同】
- springmvc-servlet.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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 自動掃描包,讓指定包下的注解生效,由IOC容器統一管理 --><context:component-scan base-package="GSF.Example.Controller"/><!-- 讓Spring MVC不處理靜態資源 --><mvc:default-servlet-handler /><!--支持mvc注解驅動在spring中一般采用@RequestMapping注解來完成映射關系要想使@RequestMapping注解生效必須向上下文中注冊DefaultAnnotationHandlerMapping和一個AnnotationMethodHandlerAdapter實例這兩個實例分別在類級別和方法級別處理。而annotation-driven配置幫助我們自動完成上述兩個實例的注入。--><mvc:annotation-driven /><!-- 視圖解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"id="internalResourceViewResolver"><!-- 前綴 --><property name="prefix" value="/WEB-INF/jsp/" /><!-- 后綴 --><property name="suffix" value=".jsp" /></bean></beans>
4、編寫操作業務Controller【不同】
package GSF.Example.Controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("/HelloController")
public class HelloController {//真實訪問地址 : 項目名/HelloController/hello@RequestMapping("/hello")public String sayHello(Model model){//向模型中添加屬性msg與值,可以在JSP頁面中取出并渲染model.addAttribute("msg","hello, SpringMVC");//web-inf/jsp/hello.jspreturn "hello";}
}
- 通過注解掃描,實現自動注入bean
5、編寫要跳轉的jsp頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head><title>你好</title>
</head>
<body>
${msg}
</body>
</html>
6、啟動測試
- localhost:8080/HelloController/hello
控制器:Controller
控制器的作用
控制器復雜提供訪問應用程序的行為,通常通過接口定義或注解定義兩種方法實現。
控制器負責解析用戶的請求并將其轉換為一個模型。
在Spring MVC中一個控制器類可以包含多個方法
在Spring MVC中,對于Controller的配置方式有很多種
控制器實現
項目Module名稱
Demo-03-SpringMVC-Controller_Restful
實現–接口定義
package GSF.Example.Controller;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ui.Model;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;public class HelloController_Interface implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView mv = new ModelAndView();mv.addObject("msg", "hello, SpringMVC, Controller_Interface");mv.setViewName("hello");return mv;}
}
實現–注解實現
package GSF.Example.Controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("/controller")
public class HelloController_Annotation {//真實訪問地址 : 項目名/controller/hello@RequestMapping("/annotation")public String sayHello(Model model){//向模型中添加屬性msg與值,可以在JSP頁面中取出并渲染model.addAttribute("msg","hello,SpringMVC, Controller_Annotation");//web-inf/jsp/hello.jspreturn "hello";}
}
總結
注解開發會更頻繁,且高效
兩個方法的跳轉指向同一個jsp頁面,視圖復用,可以看出控制器和視圖之間是弱耦合關系
注解:@RequestMapping
作用
用于映射url到控制器類或一個特定的處理程序方法
可用于類或方法上:
- 用于類上,表示類中的所有響應請求的方法都是以該地址作為父路徑
- 用于方法上,表示可以通過該路徑,訪問到該方法
示例
// 僅注解在方法上:localhost:8080 / 項目名 / h1@Controller
public class TestController {@RequestMapping("/h1")public String test(){return "test";}
}
// 既注解在類上,也注解在方法上:localhost:8080 /項目名/ admin / h1@Controller
@RequestMapping("/admin")
public class TestController {@RequestMapping("/h1")public String test(){return "test";}
}
RestFul風格
什么是RestFul?
RestFul
Restful就是一個資源定位及資源操作的風格,不是標準也不是協議,只是一種風格
基于這個風格設計的軟件可以更簡潔,更有層次,更易于實現緩存等機制
資源和資源操作
- 資源:互聯網所有的事物都可以被抽象為資源
- 資源操作:
- 使用POST、DELETE、PUT、GET對資源進行操作
- 分別對應對資源的增、刪、改、查(查單一、查全部)操作
資源操作方法對比
操作 | Restful | 傳統 |
---|---|---|
增 | http://127.0.0.1/item,POST方法 | http://127.0.0.1/item/saveItem.action,POST方法 |
刪 | http://127.0.0.1/item/1,DELETE方法 | http://127.0.0.1/item/deleteItem.action?id=1,GET方法或POST方法 |
改 | http://127.0.0.1/item,PUT方法 | http://127.0.0.1/item/updateItem.action,POST方法 |
查(單一) | http://127.0.0.1/item/,GET方法(不帶參數) | http://127.0.0.1/item/queryItem.action?id=1,GET方法 |
查(全部) | http://127.0.0.1/item/1/,GET方法(帶參數) | http://127.0.0.1/item/queryItem.action/all,GET方法 |
示例
代碼
- test1
package GSF.Example.Restful;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class Restful {@RequestMapping("/restful/{var1}/{var2}")public String calculate(@PathVariable int var1, @PathVariable int var2, Model model){int result = var1 + var2;model.addAttribute("msg", "求和結果:" + result);return "hello";}
}
- test2
package GSF.Example.Restful;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;@Controller
public class Restful_method {//@RequestMapping(value = "/restful_method/{var1}/{var2}", method = {RequestMethod.POST})@RequestMapping(value = "/restful_method/{var1}/{var2}")@GetMappingpublic String calculate(@PathVariable int var1, @PathVariable int var2, Model model){int result = var1 + var2;model.addAttribute("msg", "求和結果:" + result);return "hello";}
}
應用:@PathVariable
-
將url變量綁定到方法參數上
-
若url變量傳入的類型和方法參數的類型不對應,會出現404無法訪問,而不是在程序中出現類型不匹配異常
應用:method屬性
- 指定該url的請求方法
應用:@GetMapping、…
-
通過注解的形式,指定url的請求方法類型
-
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping
數據處理及跳轉
項目Module名稱
Demo-04-SpringMVC-DataProcess_Redirection
- 代碼參考:上述連接
- 該部分,文章中不貼入完整代碼
結果跳轉
ModelAndView
package GSF.Example.ResultRedirection;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.mvc.Controller;public class ModelAndView implements Controller {@Overridepublic org.springframework.web.servlet.ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {org.springframework.web.servlet.ModelAndView mv = new org.springframework.web.servlet.ModelAndView();mv.addObject("msg", "hello, Result Redirection, ModelAndView");mv.setViewName("hello");return mv;}
}
-
springmvc-servlet中注冊bean
-
addObject:寫入數據
-
setViewName:設置要跳轉的視圖資源
- 配合視圖解析器
ServletAPI
package GSF.Example.ResultRedirection;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import java.io.IOException;@Controller
public class ServletAPI {@RequestMapping("servlet_redirection/test1")public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {// 輸出rsp.getWriter().println("hello, Result Redirection, ServletAPI: rsp.getWriter().println");}@RequestMapping("servlet_redirection/test2")// 重定向:禁止指向受保護的視圖資源public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {rsp.sendRedirect("/Result_Redirection/test2.jsp");}@RequestMapping("servlet_redirection/test3")public void test3(HttpServletRequest req, HttpServletResponse rsp) throws IOException, ServletException {// 請求轉發:可以指向受保護的視圖資源req.setAttribute("msg", "hello, Result Redirection, ServletAPI: req.setAttribute, req.getRequestDispatcher");req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req, rsp);}
}
-
注意:該代碼針對Tomcat10,servlet包名前綴是“jakarta”
-
test1:直接在響應結果中寫入數據,支持html標簽
-
test2:響應重定向,重新請求資源(禁止請求受保護資源)
-
test3:請求轉發,請求和響應信息可以繼續傳遞(可以請求受保護資源)
SpringMVC-無需視圖解析器
- 需要寫全路徑
package GSF.Example.ResultRedirection;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;// 請求前需要先注釋掉springmvc-servlet.xml的視圖解析器@Controller
public class SpringMVC_NoViewParser {@RequestMapping("/springMvc_redirection/test1")public String test1() {// 轉發return "/index_1.jsp";}@RequestMapping("/springMvc_redirection/test2")public String test2() {// 轉發//return "forward:/index.jsp";//return "forward:/index_1.jsp";return "forward:/WEB-INF/jsp/hello.jsp";}@RequestMapping("/springMvc_redirection/test3")public String test3() {// 重定向:不讓定向到受保護的視圖資源內//return "redirect:/index.jsp";return "redirect:/WEB-INF/jsp/hello.jsp";}
}
SpringMVC-有視圖解析器
- 根據視圖解析器的前綴和后綴,補全剩余路徑即可
- 針對響應重定向,不受視圖解析器的影響,寫入全路徑即可
package GSF.Example.ResultRedirection;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import java.io.IOException;@Controller
public class SpringMVC_ViewParser {@RequestMapping("/springMvc_redirection_VP/test1")public String test1() throws IOException {// 轉發:自動借助視圖解析器補充前綴和后綴// return "index_1"; // 不行// return "/index_2"; // 行return "/jsp/hello"; // 行}@RequestMapping("/springMvc_redirection_VP/test2")public String test2() throws IOException {// 重定向:不需要視圖解析器,寫全路徑return "redirect:/Result_Redirection/test2.jsp";}
}
數據處理-提交到后端的數據
package GSF.Example.DataProcess;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;@Controller
@RequestMapping("/data_process")
public class ProcessSubmitData {@RequestMapping("/same_name")public String test1(String name){System.out.println(name);return "/jsp/hello";}@RequestMapping("/different_name")public String test2(@RequestParam("username") String name){System.out.println(name);return "/jsp/hello";}@RequestMapping("/object")public String test3(User user){System.out.println(user);return "/jsp/hello";}
}
- test1:localhost:8080/data_process/same_name?name=123456
- test2:localhost:8080/data_process/different_name?username=123456
- test3:localhost:8080/data_process/object?name=gsf&id=1&age=15
數據處理-數據顯示到前端
package GSF.Example.DataShow;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;@Controller
public class ShowDataToView {// 第一種:ModelAndView,參考ResultRedirection/ModelAndView// ModelMap@RequestMapping("/show_data")public String test1(@RequestParam("username") String name, ModelMap model){//封裝要顯示到視圖中的數據//相當于req.setAttribute("name",name);model.addAttribute("msg",name);System.out.println(name);return "/jsp/hello";}// Model@RequestMapping("/show_data_2")public String test2(@RequestParam("username") String name, Model model){//封裝要顯示到視圖中的數據//相當于req.setAttribute("name",name);model.addAttribute("msg",name);System.out.println(name);return "/jsp/hello";}
}
- test1:ModelMap
- test2:Model
亂碼處理
方法1-springMVC-過濾器
- 使用springMVC提供的過濾器,在web.xml中配置
<filter><filter-name>encoding</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>encoding</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
- 極端情況下,對get支持不好
方法2-Tomcat修改配置文件
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />
方法3-自定義過濾器
- 過濾器
package com.kuang.filter;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;/**
* 解決get和post請求 全部亂碼的過濾器
*/
public class GenericEncodingFilter implements Filter {@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {//處理response的字符編碼HttpServletResponse myResponse=(HttpServletResponse) response;myResponse.setContentType("text/html;charset=UTF-8");// 轉型為與協議相關對象HttpServletRequest httpServletRequest = (HttpServletRequest) request;// 對request包裝增強HttpServletRequest myrequest = new MyRequest(httpServletRequest);chain.doFilter(myrequest, response);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}}
- 過濾器中調用的方法
//自定義request對象,HttpServletRequest的包裝類
class MyRequest extends HttpServletRequestWrapper {private HttpServletRequest request;//是否編碼的標記private boolean hasEncode;//定義一個可以傳入HttpServletRequest對象的構造函數,以便對其進行裝飾public MyRequest(HttpServletRequest request) {super(request);// super必須寫this.request = request;}// 對需要增強方法 進行覆蓋@Overridepublic Map getParameterMap() {// 先獲得請求方式String method = request.getMethod();if (method.equalsIgnoreCase("post")) {// post請求try {// 處理post亂碼request.setCharacterEncoding("utf-8");return request.getParameterMap();} catch (UnsupportedEncodingException e) {e.printStackTrace();}} else if (method.equalsIgnoreCase("get")) {// get請求Map<String, String[]> parameterMap = request.getParameterMap();if (!hasEncode) { // 確保get手動編碼邏輯只運行一次for (String parameterName : parameterMap.keySet()) {String[] values = parameterMap.get(parameterName);if (values != null) {for (int i = 0; i < values.length; i++) {try {// 處理get亂碼values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}}}}hasEncode = true;}return parameterMap;}return super.getParameterMap();}//取一個值@Overridepublic String getParameter(String name) {Map<String, String[]> parameterMap = getParameterMap();String[] values = parameterMap.get(name);if (values == null) {return null;}return values[0]; // 取回參數的第一個值}//取所有值@Overridepublic String[] getParameterValues(String name) {Map<String, String[]> parameterMap = getParameterMap();String[] values = parameterMap.get(name);return values;}
}
總結
- 為了避免亂碼問題,在可能設置編碼的地方,都設置為UTF-8
- springMVC提供的過濾器,基本就夠用了
Json
項目Module名稱
Demo-05-SpringMVC-Json
- 代碼參考:上述連接
- 該部分,文章中不貼入完整代碼
什么是Json?
概念
- JSON(JavaScript Object Notation, JS 對象標記)是一種輕量級的數據交換格式,目前使用特別廣泛。
- 采用完全獨立于編程語言的文本格式來存儲和表示數據。
- 簡潔和清晰的層次結構使得 JSON 成為理想的數據交換語言。
- 易于人閱讀和編寫,同時也易于機器解析和生成,并有效地提升網絡傳輸效率。
語法格式
- 對象表示為鍵值對,數據由逗號分隔
- 花括號保存對象
- 方括號保存數組
Json和JavaScript的區別
JSON 是 JavaScript 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質是一個字符串
var obj = {a: 'Hello', b: 'World'}; //這是一個對象,注意鍵名也是可以使用引號包裹的
var json = '{"a": "Hello", "b": "World"}'; //這是一個 JSON 字符串,本質是一個字符串
Json和JavaScript的相互轉換
var obj = JSON.parse('{"a": "Hello", "b": "World"}');
//結果是 {a: 'Hello', b: 'World'}var json = JSON.stringify({a: 'Hello', b: 'World'});
//結果是 '{"a": "Hello", "b": "World"}'
Controller返回Json數據:jackson
Module準備
1、導包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.8</version>
</dependency>
2、建立Module,完成springmvc-servlet.xml、web.xml配置(大差不差,不再詳細貼出代碼)
Controller核心代碼
package GSF.Example.Controller;import GSF.Example.Pojo.User;
import GSF.Example.Utils.JsonUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;//@Controller // 使用Controller,需要在方法上添加@ResponseBody注解,保證返回json形式數據
@RestController // 使用RestController,保證返回的都是json形式數據
public class UserController {@RequestMapping("/json1")//@RequestMapping(value = "/json1",produces = "application/json;charset=utf-8") // 設置返回數據字符集,避免亂碼//@ResponseBodypublic String json1() throws JsonProcessingException {//創建一個jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個對象User user = new User("秦疆1號", 3, "男");//將我們的對象解析成為json格式String str = mapper.writeValueAsString(user);System.out.println(str);//由于@ResponseBody注解,這里會將str轉成json格式返回;十分方便return str;}@RequestMapping("/json2")public String json2() throws JsonProcessingException {//創建一個jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個對象User user1 = new User("秦疆1號", 3, "男");User user2 = new User("秦疆2號", 3, "男");User user3 = new User("秦疆3號", 3, "男");User user4 = new User("秦疆4號", 3, "男");List<User> list = new ArrayList<User>();list.add(user1);list.add(user2);list.add(user3);list.add(user4);//將我們的對象解析成為json格式String str = mapper.writeValueAsString(list);return str;}// 默認返回一個時間戳,是一個lang整數值@RequestMapping("/json3")public String json3() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();//創建時間一個對象,java.util.DateDate date = new Date();//將我們的對象解析成為json格式String str = mapper.writeValueAsString(date);return str;}// 通過定義返回時間的格式返回數據@RequestMapping("/json4")public String json4() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();//不使用時間戳的方式mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//自定義日期格式對象SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//指定日期格式mapper.setDateFormat(sdf);Date date = new Date();String str = mapper.writeValueAsString(date);return str;}@RequestMapping("/json5")public String json5() throws JsonProcessingException {Date date = new Date();String json = JsonUtils.getJson(date); // 將代碼抽出來,自定義一個工具類return json;}
}
統一處理亂碼問題
- springmvc-servlet.xml配置
<!--Jackson統一解決亂碼問題-->
<mvc:annotation-driven><mvc:message-converters register-defaults="true"><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg value="UTF-8"/></bean><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"><property name="objectMapper"><bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"><property name="failOnEmptyBeans" value="false"/></bean></property></bean></mvc:message-converters>
</mvc:annotation-driven>
Controller返回Json數據:fastjson
Module準備
1、導包
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.60</version>
</dependency>
2、建立Module,完成springmvc-servlet.xml、web.xml配置(大差不差,不再詳細貼出代碼)
fastjson三大核心類
核心類 | 代表 | 解釋 |
---|---|---|
JSONObject | 代表 json 對象 | JSONObject實現了Map接口,猜想 JSONObject底層操作是由Map實現的 JSONObject對應json對象,通過各種形式的get()方法可以獲取json對象中的數據,也可利用諸如size(),isEmpty()等方法獲取"鍵:值"對的個數和判斷是否為空 其本質是通過實現Map接口并調用接口中的方法完成的 |
JSONArray | 代表 json 對象數組 | 內部是有List接口中的方法來完成操作的 |
JSON | 代表 JSONObject和JSONArray的轉化 | JSON類源碼分析與使用 主要是實現json對象,json對象數組,javabean對象,json字符串之間的相互轉化 |
數據類型相互轉換
- json對象,json對象數組,javabean對象,json字符串之間的相互轉化
package GSF.Example.Controller;import GSF.Example.Pojo.User;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;import java.util.ArrayList;
import java.util.List;public class FastJsonDemo {public static void main(String[] args) {//創建一個對象User user1 = new User("秦疆1號", 3, "男");User user2 = new User("秦疆2號", 3, "男");User user3 = new User("秦疆3號", 3, "男");User user4 = new User("秦疆4號", 3, "男");List<User> list = new ArrayList<User>();list.add(user1);list.add(user2);list.add(user3);list.add(user4);System.out.println("*******Java對象 轉 JSON字符串*******");String str1 = JSON.toJSONString(list);System.out.println("JSON.toJSONString(list)==>"+str1);String str2 = JSON.toJSONString(user1);System.out.println("JSON.toJSONString(user1)==>"+str2);System.out.println("\n****** JSON字符串 轉 Java對象*******");User jp_user1=JSON.parseObject(str2,User.class);System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);System.out.println("\n****** Java對象 轉 JSON對象 ******");JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));System.out.println("\n****** JSON對象 轉 Java對象 ******");User to_java_user = JSON.toJavaObject(jsonObject1, User.class);System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);}
}
Ajax
學一半,后邊再說吧,有點學不明白
攔截器:Interceptor
什么是攔截器?
概念
SpringMVC的處理器攔截器類似于Servlet開發中的過濾器Filter,用于對處理器進行預處理和后處理。開發者可以自己定義一些攔截器來實現特定的功能
過濾器和攔截器的區別
過濾器 | 攔截器 |
---|---|
servlet規范中的一部分,任何java web工程都可以使用 | 攔截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用 |
通過配置,可以對所有要訪問的資源進行攔截 | 是AOP思想的具體應用,只會攔截訪問的控制器方法,如果訪問的是jsp/html/css/image/js是不會進行攔截的 |
攔截器使用
- java代碼
package GSF.Example.Interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class MyInterceptor implements HandlerInterceptor {//在請求處理的方法之前執行//如果返回true執行下一個攔截器//如果返回false就不執行下一個攔截器public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {System.out.println("------------處理前------------");return true;}//在請求處理方法執行之后執行public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {System.out.println("------------處理后------------");}//在dispatcherServlet處理后執行,做清理工作.public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println("------------清理------------");}
}
- springmvc-servlet.xml配置
<!--關于攔截器的配置-->
<mvc:interceptors><mvc:interceptor><!--/** 包括路徑及其子路徑--><!--/admin/* 攔截的是/admin/add等等這種 , /admin/add/user不會被攔截--><!--/admin/** 攔截的是/admin/下的所有--><mvc:mapping path="/**"/><!--bean配置的就是攔截器--><bean class="GSF.Example.Interceptor.MyInterceptor"/></mvc:interceptor>
</mvc:interceptors>
文件上傳和下載
Module準備
1、建立相關Module
2、導包
<!--文件上傳有關的第三方庫-->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version>
</dependency>
3、springmvc-servlet.xml配置bean!!
<!--文件上傳配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
- 這個bean的名字必須叫這個,不能為其他的
核心代碼展示
前端頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2><h1>上傳文件</h1>
<h2>上傳單個文件,java原生代碼實現</h2>
<form action="/upload" enctype="multipart/form-data" method="post"><input type="file" name="file"/><input type="submit" value="upload">
</form><h2>上傳單個文件,調file.TransferTo保存文件代碼</h2>
<form action="/upload2" enctype="multipart/form-data" method="post"><input type="file" name="file"/><input type="submit" value="upload">
</form><h2>上傳多個文件(多個文件選擇框實現),調file.TransferTo保存文件代碼</h2>
<form action="/upload3" enctype="multipart/form-data" method="post"><input type="file" name="file"/><input type="file" name="file"/><input type="submit" value="upload">
</form><h2>上傳多個文件(單個文件選擇框實現),調file.TransferTo保存文件代碼</h2>
<form action="/upload3" enctype="multipart/form-data" method="post"><input type="file" name="file" multiple/><input type="submit" value="upload">
</form>
</body><h1>下載文件</h1>
<h2>java原生代碼實現</h2>
<a href="/download">點擊下載</a>
</html>
Controller
package GSF.Example.Controller;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
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;import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;@Controller
public class FileController {@RequestMapping("/upload")public String fileUpload_onefile_manualsave(@RequestParam("file") MultipartFile file , HttpServletRequest request) throws IOException {//獲取文件名 : file.getOriginalFilename();String uploadFileName = file.getOriginalFilename();//如果文件名為空,直接回到首頁!if ("".equals(uploadFileName)){return "redirect:/index.jsp";}System.out.println("上傳文件名 : "+uploadFileName);//上傳路徑保存設置String path = request.getServletContext().getRealPath("/upload");System.out.println(path);//如果路徑不存在,創建一個File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}System.out.println("上傳文件保存地址:"+realPath);InputStream is = file.getInputStream(); //文件輸入流OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件輸出流//讀取寫出int len=0;byte[] buffer = new byte[1024];while ((len=is.read(buffer))!=-1){os.write(buffer,0,len);os.flush();}os.close();is.close();return "redirect:/index.jsp";}/** 采用file.Transto 來保存上傳的文件*/@RequestMapping("/upload2")public String fileUpload2(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {//上傳路徑保存設置String path = request.getServletContext().getRealPath("/upload");File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}//上傳文件地址System.out.println("上傳文件保存地址:"+realPath);//通過CommonsMultipartFile的方法直接寫文件(注意這個時候)file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));return "redirect:/index.jsp";}@RequestMapping("/upload3") // 等價于 @RequestMapping(value = "/upload", method = RequestMethod.POST)public String fileUpload(HttpServletRequest req, @RequestParam("file") MultipartFile[] files) throws IOException {List<String> pathStrs = new ArrayList<String>();if(files.length > 0){//循環多次上傳多個文件for (MultipartFile file : files) {if(!file.isEmpty()){//上傳路徑保存設置String path = req.getServletContext().getRealPath("/upload");File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}//上傳文件地址System.out.println("上傳文件保存地址:"+realPath);//通過CommonsMultipartFile的方法直接寫文件(注意這個時候)file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));}}}return "redirect:/index.jsp";}// 下載文件的步驟:// 1、設置response響應頭// 2、讀取文件:InputStream// 3、寫出文件:OutputStream// 4、執行操作// 5、關閉流(先開的流后關)@RequestMapping(value="/download")public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{//要下載的圖片地址String path = request.getServletContext().getRealPath("/upload");String fileName = "基礎語法.jpg";//1、設置response 響應頭response.reset(); //設置頁面不緩存,清空bufferresponse.setCharacterEncoding("UTF-8"); //字符編碼response.setContentType("multipart/form-data"); //二進制傳輸數據//設置響應頭response.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));File file = new File(path,fileName);//2、 讀取文件--輸入流InputStream input=new FileInputStream(file);//3、 寫出文件--輸出流OutputStream out = response.getOutputStream();byte[] buff =new byte[1024];int index=0;//4、執行 寫出操作while((index= input.read(buff))!= -1){out.write(buff, 0, index);out.flush();}out.close();input.close();return null;}
}