4-SpringMVC

文章目錄

  • 項目源碼地址
  • 回顧-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

項目源碼地址

GitHubhttps://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依賴所在的目錄不一樣

image-20231130172457456

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

image-20231130175322983

image-20231130175420492

image-20231130175521737

image-20231130175558908

image-20231130175709773

  • 暫不清楚為啥要選這個,也不知道選不帶有war exploded的會有啥問題

image-20231130175900950

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執行原理

image-20231210103958973

實現部分:表示框架已經幫忙完成;虛線部分:表示需要我們手動編寫的地方

步驟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

整體結構圖及后續寫入代碼

image-20231130203829024

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

整體結構圖及后續寫入代碼

image-20231130225354825

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;}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/211319.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/211319.shtml
英文地址,請注明出處:http://en.pswp.cn/news/211319.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

github使用方法【附安裝包】

如果你是一枚Coder&#xff0c;但是你不知道Github&#xff0c;那么我覺的你就不是一個菜鳥級別的Coder&#xff0c;因為你壓根不是真正Coder&#xff0c;你只是一個Code搬運工。說明你根本不善于突破自己&#xff01;為什么這么說原因很簡單&#xff0c;很多優秀的代碼以及各種…

高級系統架構設計師之路

前言&#xff1a;系 統 架 構 設 計 師 (System Architecture Designer)是項目開發活動中的眾多角色之 一 &#xff0c;它可 以是 一個人或 一個小組&#xff0c;也可以是一個團隊。架構師 (Architect) 包含建筑師、設計師、創造 者、締造者等含義&#xff0c;可以說&#xff0…

邊緣計算系統設計與實踐:引領科技創新的新浪潮

文章目錄 一、邊緣計算的概念二、邊緣計算的設計原則三、邊緣計算的關鍵技術四、邊緣計算的實踐應用《邊緣計算系統設計與實踐》特色內容簡介作者簡介目錄前言/序言本書讀者對象獲取方式 隨著物聯網、大數據和人工智能等技術的快速發展&#xff0c;傳統的中心化計算模式已經無法…

基于ssm人力資源管理系統論文

摘 要 隨著企業員工人數的不斷增多&#xff0c;企業在人力資源管理方面負擔越來越重&#xff0c;因此&#xff0c;為提高企業人力資源管理效率&#xff0c;特開發了本人力資源管理系統。 本文重點闡述了人力資源管理系統的開發過程&#xff0c;以實際運用為開發背景&#xff0…

【大數據】Hudi 核心知識點詳解(一)

Hudi 核心知識點詳解&#xff08;一&#xff09; 1.數據湖與數據倉庫的區別 &#xff1f;1.1 數據倉庫1.2 數據湖1.3 兩者的區別 2.Hudi 基礎功能2.1 Hudi 簡介2.2 Hudi 功能2.3 Hudi 的特性2.4 Hudi 的架構2.5 湖倉一體架構 3.Hudi 數據管理3.1 Hudi 表數據結構3.1.1 .hoodie …

【C語言】位運算實現二進制數據處理及BCD碼轉換

文章目錄 1&#xff0e;編程實驗&#xff1a;按short和unsigned short類型分別對-12345進行左移2位和右移2位操作&#xff0c;并輸出結果。2&#xff0e;編程實驗&#xff1a;利用位運算實現BCD碼與十進制數之間的轉換&#xff0c;假設數據類型為unsigned char。3&#xff0e;編…

FPGA | Verilog基礎語法

這里寫自定義目錄標題 Case語句系統任務$dumpfile | 為所要創建的VCD文件指定文件名。$dumpvar | 指定需要記錄到VCD文件中的信號$fscanf$fread菜鳥教程連接 Case語句 case(case_expr)condition1 : true_statement1 ;condition2 : true_stat…

多線程(進階二:CAS)

目錄 一、CAS的簡單介紹 CAS邏輯&#xff08;用偽代碼來描述&#xff09; 二、CAS在多線程中簡單的使用 三、原子類自增的代碼分析 都看到這了&#xff0c;點個贊再走吧&#xff0c;謝謝謝謝謝 一、CAS的簡單介紹 CAS的全稱&#xff1a;“Compare And Swap”&#xff0c;字…

C語言——字符函數和字符串函數(一)

&#x1f4dd;前言&#xff1a; 這篇文章對我最近學習的有關字符串的函數做一個總結和整理&#xff0c;主要講解字符函數和字符串函數&#xff08;strlen&#xff0c;strcpy和strncpy&#xff0c;strcat和strncat&#xff09;的使用方法&#xff0c;使用場景和一些注意事項&…

python常見庫的匯總

python常見庫 一、爬蟲二、界面開發三、圖片處理四、視頻處理、視頻剪輯五、音頻處理六、數據處理七、數據庫八、網頁開發九、神經學習、AI開發十、打包十一、Excel處理十二、微信十三、控制鼠標鍵盤十四、手柄十五、控制外設十六、郵箱十七、短信 一、爬蟲 Requests&#xff…

Java入門項目--螞蟻愛購

簡介 這是一個靠譜的Java入門項目實戰&#xff0c;名字叫螞蟻愛購。 從零開發項目&#xff0c;視頻加文檔&#xff0c;十天就能學會開發JavaWeb項目&#xff0c;教程路線是&#xff1a;搭建環境> 安裝軟件> 創建項目> 添加依賴和配置> 通過表生成代碼> 編寫Ja…

解鎖MySQL的威力:針對常見問題的快速解決指南

數據庫和表的創建 創建數據庫&#xff1a; CREATE DATABASE IF NOT EXISTS MyDatabase; USE MyDatabase;案例&#xff1a; 想象您要開始一個博客項目。首先&#xff0c;您需要一個地方來存儲所有的文章和用戶信息。上述命令幫助您創建了這樣一個存儲空間&#xff0c;名為MyDa…

Tomcat使用https方式連接

Tomcat使用https方式連接 攏共分兩步&#xff0c;第一步&#xff1a;生成密鑰。第二步&#xff1a;修改配置。 第一步&#xff1a;生成密鑰。 keytool -genkey -v -alias tomcat -keyalg RSA -validity 365 -keystore /usr/tomcat-8.5/conf/tomcat.keystore第二步&#xff1…

RocketMQ-源碼架構二

梳理一些比較完整&#xff0c;比較復雜的業務線 消息持久化設計 RocketMQ的持久化文件結構 消息持久化也就是將內存中的消息寫入到本地磁盤的過程。而磁盤IO操作通常是一個很耗性能&#xff0c;很慢的操作&#xff0c;所以&#xff0c;對消息持久化機制的設計&#xff0c;是…

華為機試真題 C++ 實現【字符串重新排列】

題目 給定一個字符串s&#xff0c;s包括以空格分隔的若干個單詞&#xff0c;請對s進行如下處理后輸出&#xff1a; 1、單詞內部調整&#xff1a;對每個單詞字母重新按字典序排序 2、單詞間順序調整&#xff1a; 1&#xff09;統計每個單詞出現的次數&#xff0c;并按次數降序…

蒙特霍爾問題(選擇三扇門后的車與羊)及其貝葉斯定理數學解釋

1. 蒙特霍爾問題 有一個美國電視游戲節目叫做“Let’s Make a Deal”&#xff0c;游戲中參賽者將面對3扇關閉的門&#xff0c;其中一扇門背后有一輛汽車&#xff0c;另外兩扇門后是山羊&#xff0c;參賽者如果能猜中哪一扇門后是汽車&#xff0c;就可以得到它。 通常&#xf…

筆記68:Pytorch中repeat函數的用法

repeat 相當于一個broadcasting的機制 repeat(*sizes) 沿著指定的維度重復tensor。不同與expand()&#xff0c;本函數復制的是tensor中的數據。 import torch import torch.nn.functional as F import numpy as np a torch.Tensor(128,1,512) B a.repeat(1,5,1) print(B.s…

OpenGL 著色器程序的保存和加載(二進制)

背景 為了提高OpenGL 著色器程序的編譯和鏈接速度&#xff0c;我們可以將程序保存為二進制進行加載&#xff0c;可以大幅度提升加載效率。 方法 以下是加載和保存二進制程序的方法。 // 加載著色器程序的二進制文件到已創建的著色器程序中 bool loadPragram(const std::str…

javaee實驗:文件上傳及攔截器的使用

目錄 文件上傳ModelAttribute注解實驗目的實驗內容實驗過程項目結構編寫代碼結果展示 文件上傳 Spring MVC 提供 MultipartFile 接口作為參數來處理文件上傳。 MultipartFile 提供以下方法來獲取上傳的文件信息&#xff1a; ? getOriginalFilename 獲取上傳的文件名字&#x…

華為OD機試真題-測試用例執行計劃-2023年OD統一考試(C卷)

題目描述: 某個產品當前迭代周期內有N個特性( F1,F2,.......FN)需要進行覆蓋測試,每個特性都被評估了對應的優先級,特性使用其ID作為下標進行標識。 設計了M個測試用例(T1,T2......,TM ),每個用例對應了一個覆蓋特性的集合,測試用例使用其ID作為下標進行標識,測試用例…