SpringMVC大威天龍

夢三發表於2020-08-13

一 SpringMVC簡介

SpringMVC是Spring提供的一個強大而靈活的Web框架 藉助於註解 SpringMVC提供了幾乎是POJO的開發模式 使得控制器的開發和測試更加簡單

 

二 SpringMVC優點

1. 角色劃分清晰

2. 分工明確 而且擴充套件相當靈活

3. 和Spring其它框架無縫整合 是其它Web框架所不具備的

4. 功能強大的資料驗證 格式化 繫結機制

5. 約定大於配置的契約式程式設計支援 基於註解的零配置支援等等

 

三 SpringMVC框架核心

DispatcherServlet 前端控制器

使用者請求到達前端控制器 它就相當於MVC模式中的C DispatcherServlet是整個流程控制的中心 由它呼叫其它元件處理使用者的請求 DispatcherServlet的存在降低了元件之間的耦合性

HandlerMapping 處理器對映器

SpringMVC三大元件之一 HandlerMapping負責根據使用者請求URL找到Handler即處理器 SpringMVC提供了不同的對映器實現不同的對映方式 比如配置檔案方式 實現介面方式 註解方式等等

Handler 處理器

Handler是繼DispatcherServlet前端控制器的後端控制器 在DispatcherServlet的控制下Handler對具體的使用者請求進行處理 由於Handler涉及到具體的使用者業務請求 所以一般情況需要程式設計師根據業務需求開發Handler

HandlAdapter 處理器介面卡

SpringMVC三大元件之一 通過HandlerAdapter對處理器進行執行 這是介面卡模式的應用 通過擴充套件介面卡可以對更多型別的處理器進行執行

ViewResolver 檢視解析器

SpringMVC三大元件之一 ViewResolver負責將處理結果生成View檢視 ViewResolver首先根據邏輯檢視名解析成物理檢視名即具體的頁面地址 再生成View檢視物件 最後對View進行渲染將處理結果通過頁面展示給使用者

View 檢視

SpringMVC提供了很多View檢視型別的支援 比如FreemarkerView PDFView等等 最常用的檢視就是JSP 一般情況下需要通過頁面標籤或頁面模版技術將模型資料通過頁面展示給使用者 需要程式設計師根據業務需求開發具體的頁面

 

四 SpringMVC初體驗

1. 新建一個Maven專案

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hy.springmvc</groupId>
    <artifactId>springmvc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <!-- 定義依賴版本號 -->
    <properties>
        <javax.servlet-api.version>4.0.1</javax.servlet-api.version>
        <jsp-api.version>2.0</jsp-api.version>
        <jstl.version>1.2</jstl.version>
        <spring.version>5.0.5.RELEASE</spring.version>
        <jackson-databind.version>2.9.5</jackson-databind.version>
        <commons-fileupload.version>1.3.3</commons-fileupload.version>
    </properties>

    <!-- 管理jar版本號 -->
    <dependencyManagement>
        <dependencies>
            <!-- servlet -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${javax.servlet-api.version}</version>
                <scope>provided</scope>
            </dependency>
            <!-- jsp -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jsp-api</artifactId>
                <version>${jsp-api.version}</version>
                <scope>provided</scope>
            </dependency>
            <!-- jstl -->
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>${jstl.version}</version>
            </dependency>
            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jms</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <!-- jackson(spring mvc need) -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson-databind.version}</version>
            </dependency>
            <!-- fileupload(spring mvc need) -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${commons-fileupload.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- jsp -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- jstl -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- jackson(spring mvc need) -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <!-- fileupload(spring mvc need) -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- 編譯 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!-- tomcat7 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8080</port>
                    <path>/</path>
                    <uriEncoding>UTF-8</uriEncoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. 新建webapp資料夾及子資料夾和web.xml

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_3_1.xsd"
         version="3.1">

    <!-- 處理POST提交亂碼 -->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <!-- 攔截所有 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 前端控制器 -->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/spring-mvc.xml</param-value>
        </init-param>
        <!-- 配置SpringMVC啟動時機
                1. 第一次被訪問時啟動 值為負數
                2. 隨著容器啟動而啟動 值為0或正數 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <!-- 攔截所有(不包含jsp 包含js png css...) -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

3. 建立jsp webapp/WEB-INF/jsp/index.jsp webapp/WEB-INF/jsp/success.jsp webapp/WEB-INF/jsp/exception.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.1.min.js"></script>
    <script type="text/javascript">
        var param = '{"name":"禕哥哥", "age":18}';
        function json() {
            $.ajax({
                url: "${pageContext.request.contextPath}/test/postBody",
                data: param,
                contentType: "application/json;charset=UTF-8",
                type: "post",
                dataType: "json",
                success: function (data) {
                    alert(data.name + ", " + data.age);
                }
            });
        }
    </script>
</head>
<body>

<h3>初體驗</h3>

${message}<br/><br/>

<a href="${pageContext.request.contextPath}/test/forward">轉發</a><br/><br/>

<a href="${pageContext.request.contextPath}/test/redirect">重定向</a><br/><br/>

<a href="${pageContext.request.contextPath}/test/error">異常處理</a><br/><br/>

<a href="${pageContext.request.contextPath}/test/get?name=hy&age=18">GET請求 /test/get?name=hy&age=18</a><br/><br/>

<a href="${pageContext.request.contextPath}/test/getPath/黃禕">GET請求 /test/getPath/黃禕</a><br/><br/>

<p>普通表單 普通型別引數繫結 List型別引數繫結</p>
<form action="${pageContext.request.contextPath}/test/postList" method="post">
    姓名 <input type="text" name="name"/><br/>
    年齡 <input type="text" name="age"/><br/>
    愛好 <input type="checkbox" name="hobby" value="1"/>紅中
    <input type="checkbox" name="hobby" value="2"/>發財
    <input type="checkbox" name="hobby" value="3"/>白板<br/>
    <input type="submit" value="提交"/>
</form>

<p>普通表單 普通型別引數繫結 陣列型別引數繫結</p>
<form action="${pageContext.request.contextPath}/test/postArray" method="post">
    姓名 <input type="text" name="name"/><br/>
    年齡 <input type="text" name="age"/><br/>
    愛好 <input type="checkbox" name="hobby" value="1"/>紅中
    <input type="checkbox" name="hobby" value="2"/>發財
    <input type="checkbox" name="hobby" value="3"/>白板<br/>
    <input type="submit" value="提交"/>
</form>

<p>普通表單 Model型別引數繫結</p>
<form action="${pageContext.request.contextPath}/test/postModel" method="post">
    姓名 <input type="text" name="name"/><br/>
    年齡 <input type="text" name="age"/><br/>
    愛好 <input type="checkbox" name="hobby" value="1"/>紅中
    <input type="checkbox" name="hobby" value="2"/>發財
    <input type="checkbox" name="hobby" value="3"/>白板<br/>
    <input type="submit" value="提交"/>
</form>

<p>檔案表單 單檔案</p>
<form action="${pageContext.request.contextPath}/test/postSingleFile" enctype="multipart/form-data" method="post">
    姓名 <input type="text" name="name"/><br/>
    檔案 <input type="file" name="file"/><br/>
    <input type="submit" value="提交"/>
</form>

<p>檔案表單 多檔案</p>
<form action="${pageContext.request.contextPath}/test/postMoreFile" enctype="multipart/form-data" method="post">
    姓名 <input type="text" name="name"/><br/>
    檔案 <input type="file" name="file"/>
    <input type="file" name="file"/><br/>
    <input type="submit" value="提交"/>
</form>

<input type="button" value="請求體是json格式字串" onclick="json()"/>

</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h3>成功了</h3>

${user.toString()}

</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h3>出錯了</h3>

${error.toString()}

</body>
</html>

4. 配置常量 resources/resource.properties

### 常量 ###
NAME=HUANGYI

5. 建立配置檔案 resources/spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">

    <!-- 引入配置檔案 -->
    <context:property-placeholder location="classpath:*.properties" />

    <!-- 掃描的位置 -->
    <context:component-scan base-package="com.hy.springmvc.controller" />

    <!-- 註解驅動 -->
    <mvc:annotation-driven />

    <!-- 檔案上傳實現類 id名稱必須固定 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 預設編碼 -->
        <property name="defaultEncoding" value="UTF-8" />
        <!-- 檔案上傳大小(單位B) 5M = 5 * 1024 * 1024 -->
        <property name="maxUploadSize" value="5242880" />
    </bean>

    <!-- 檢視解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 邏輯檢視字首 -->
        <property name="prefix" value="/WEB-INF/jsp" />
        <!-- 邏輯檢視字尾 -->
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 載入靜態資源 -->
    <mvc:default-servlet-handler />

    <!-- 攔截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 攔截所有 -->
            <mvc:mapping path="/**" />
            <bean class="com.hy.springmvc.interceptor.Interceptor" />
        </mvc:interceptor>
        <!-- 多個攔截器 攔截器會順序執行 -->
        <!--<mvc:interceptor>-->
        <!--<mvc:mapping path="/**" />-->
        <!--<bean />-->
        <!--</mvc:interceptor>-->
    </mvc:interceptors>

    <!-- 異常處理器 -->
    <bean class="com.hy.springmvc.exception.HttpErrorResolver" />
</beans>

6. 建立實體類 com.hy.springmvc.model.User com.hy.springmvc.model.HttpError

public class User {

    private String name;
    private Integer age;
    private Integer[] hobby;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer[] getHobby() {
        return hobby;
    }

    public void setHobby(Integer[] hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", hobby=" + Arrays.toString(hobby) +
                '}';
    }
}
public class HttpError extends Exception {

    private int code;
    private String message;

    public HttpError() {}

    public HttpError(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "HttpError{" +
                "code=" + code +
                ", message='" + message + '\'' +
                '}';
    }
}

7. 建立攔截器 com.hy.springmvc.interceptor.Interceptor

public class Interceptor implements HandlerInterceptor {

    // Controller執行前呼叫此方法
    // 返回true繼續執行 返回false中止執行
    // 這裡可加入登入校驗 許可權攔截等
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(" ========== preHandle ========== ");
        // 放行
        return true;
    }

    // Controller執行後 且未返回檢視前 呼叫此方法
    // 這裡可在返回使用者前對模型資料進行加工處理 比如這裡加入公用資訊以便頁面顯示
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {}

    // Controller執行後 且檢視返回後 呼叫此方法
    // 這裡可得到執行Controller時的異常資訊
    // 這裡可記錄操作日誌
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {}
}

8. 建立異常處理器 com.hy.springmvc.exception.HttpErrorResolver

public class HttpErrorResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        // Object o 發生異常的具體位置
        System.out.println("resolveException = " + o.toString());
        // 寫日誌記錄 發郵件提醒

        if (System.currentTimeMillis() % 2 == 0) {
            /** 有檢視 **/
            HttpError error = e instanceof HttpError ? (HttpError) e : new HttpError(-1, "未知異常");
            ModelAndView view = new ModelAndView();
            view.addObject("error", error);
            view.setViewName("/exception");
            return view;

        } else {
            /** 無檢視 **/
            HttpError error = e instanceof HttpError ? (HttpError) e : new HttpError(-1, "未知異常");
            try {
                response.setContentType("text/html;charset=UTF-8"); //解決返回中的中文亂碼
                PrintWriter writer = response.getWriter();
                writer.write(error.toString());
                writer.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            return null;
        }
    }
}

9. 建立控制器 com.hy.springmvc.controller.TestController

@Controller
@RequestMapping("/test")
public class TestController {

    @Value("${NAME}")
    private String NAME;

    /**
     * @param model Model
     * @param accept @RequestHeader 獲取指定請求頭的值
     * @return 資源路徑
     */
    @RequestMapping("/index")
    public String index(Model model, @RequestHeader("Accept") String accept) {
        model.addAttribute("message", NAME + " " + accept);
        return "/index";
    }

    /**
     * 轉發
     * @return Mapping路徑
     */
    @RequestMapping("/forward")
    public String forward() {
        return "forward:index";
    }

    /**
     * 重定向
     * @return Mapping路徑
     */
    @RequestMapping("/redirect")
    public String redirect() {
        return "redirect:index";
    }

    /**
     * 異常處理
     * @return 資源路徑
     */
    @RequestMapping("/error")
    public String error() {
        int i = 1 / 0; //模擬異常
        return "/index";
    }

    /**
     * @RequestMapping 作用在類上=第一級訪問目錄 作用在方法上=第二級訪問目錄
     * path=指定請求路徑 path=指定請求方法 params=指定限制請求引數的條件 headers=指定限制請求頭的條件
     * @param model Model
     * @param name 普通型別引數繫結
     * @param age @RequestParam 把請求中指定名稱的引數傳遞給控制器中形參賦值
     *            name=請求引數中的名稱 required=請求引數中是否必須提供此引數 defaultValue=預設值
     * @return 資源路徑
     */
    @RequestMapping(path = "/get", method = RequestMethod.GET)
    public String get(Model model, String name, @RequestParam(name = "age", required = true, defaultValue = "0") Integer age) {
        User user = new User();
        user.setName(name);
        user.setAge(age);
        model.addAttribute("user", user);
        return "/success";
    }

    /**
     * @param model Model
     * @param name @PathVariable 繫結url中的佔位符
     * @return 資源路徑
     */
    @GetMapping("/getPath/{name}")
    public String getPath(Model model, @PathVariable String name) {
        User user = new User();
        user.setName(name);
        model.addAttribute("user", user);
        return "/success";
    }

    /**
     * @ResponseBody 將方法的返回值 以特定格式寫入到響應體
     * @param name 普通型別引數繫結
     * @param age 普通型別引數繫結
     * @param hobby List型別引數繫結 必須新增@RequestParam
     * @return json格式字串
     */
    @PostMapping("/postList")
    @ResponseBody
    public User postList(String name, Integer age, @RequestParam List<Integer> hobby) {
        Integer[] array = hobby.toArray(new Integer[0]);
        User user = new User();
        user.setName(name);
        user.setAge(age);
        user.setHobby(array);
        return user;
    }

    /**
     * @param name 普通型別引數繫結
     * @param age 普通型別引數繫結
     * @param hobby 陣列型別引數繫結
     * @return json格式字串
     */
    @PostMapping("/postArray")
    @ResponseBody
    public User postArray(String name, Integer age, Integer[] hobby) {
        User user = new User();
        user.setName(name);
        user.setAge(age);
        user.setHobby(hobby);
        return user;
    }

    /**
     * @param user Model型別引數繫結
     * @return json格式字串
     */
    @PostMapping("/postModel")
    @ResponseBody
    public User postModel(User user) {
        return user;
    }

    /**
     * @param request HttpServletRequest
     * @param name 普通型別引數繫結
     * @param file 單檔案
     * @return json格式字串
     * @throws Exception 異常
     */
    @PostMapping("/postSingleFile")
    @ResponseBody
    public User postSingleFile(HttpServletRequest request, String name, MultipartFile file) throws Exception {
        String path = saveFile(request, file);
        User user = new User();
        user.setName(name + ", " + path);
        return user;
    }

    /**
     * @param request HttpServletRequest
     * @param name 普通型別引數繫結
     * @param file 多檔案
     * @return json格式字串
     * @throws Exception 異常
     */
    @PostMapping("/postMoreFile")
    @ResponseBody
    public User postMoreFile(HttpServletRequest request, String name, MultipartFile[] file) throws Exception {
        StringBuilder builder = new StringBuilder();
        if (null != file && 0 != file.length) {
            for (MultipartFile multipartFile : file) {
                String path = saveFile(request, multipartFile);
                builder.append(" ").append(path);
            }
        }
        User user = new User();
        user.setName(name + "," + builder.toString());
        return user;
    }

    /**
     * @param user @RequestBody 用於獲取請求體的內容
     * @return json格式字串
     */
    @PostMapping("/postBody")
    @ResponseBody
    public User postBody(@RequestBody User user) {
        return user;
    }

    private String saveFile(HttpServletRequest request, MultipartFile file) throws Exception {
        if (null != file && !file.isEmpty()) {
            String fileName = UUID.randomUUID().toString().replace("-", ""); //檔名
            String originalFilename = file.getOriginalFilename();
            String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
            String path = request.getServletContext().getRealPath("/upload") + "/" + fileName + substring;
            file.transferTo(new File(path));
            return path;
        }
        return "";
    }
}

啟動專案 訪問 http://localhost:8080/test/index

 

相關文章