不安分的黑娃
踏踏实实,坚持学习,慢慢就懂了~

SpringMVC快速使用——基于XML配置和Servlet3.0

1、官方文档

https://docs.spring.io/spring-framework/docs/5.2.8.RELEASE/spring-framework-reference/web.html#spring-web

2、目标

基于SpringMVC框架,使用XML配置编写一个Web应用,根据客户端发送的请求参数,动态展示欢迎页内容。

3、编写pom文件引入jar包

这里使用5.3.8版本Spring框架。基于Servlet API,必须引入servlet-api依赖。

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.black</groupId>
  <artifactId>spring-springmvc-xml</artifactId>
  <packaging> war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>spring-springmvc-xml Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <!-- 定义Spring版本 -->
  <properties>
      <spring.verson>5.3.8</spring.verson>
  </properties>
  <dependencies>
    <!-- 引入 Spring Framework jar包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <!-- 引入 Spring MVC jar包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.verson}</version>
    </dependency>

    <!-- 引入 servlet-api (不希望打到war包中,有可能tomcat容器就已经带有这个包了)-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    <!-- 日志 jar -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jcl</artifactId>
        <version>${spring.verson}</version>
    </dependency>
    
    <!-- 日志:slf4j + logback  -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.31</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.2.3</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
        <scope>compile</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>spring-springmvc-xml</finalName>
  </build>
</project>

4、编写 web.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">

  <!-- 指定 Root WebApplicationContext xml配置文件 -->
  <!-- 如果不配置 contextConfigLocation这个属性,那么,自动会去加载  WEB-INF/applicationContext.xml  如果没有则报异常-->
  <!-- 如果不需要 WebApplicationContext 继承关系则, contextConfigLocation 的 value 设置为 空 -->
  <!--  (一般上不用WebApplicationContext继承关系) -->
  <!-- context-param  更详实说明看 【11.1 web.xml context-param说明】-->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value>
  </context-param>

  <!-- 1、定义上下文监听 -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!-- 2、定义 dispatcherServlet-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<!-- 如果不配置 contextConfigLocation 则默认加载 WEB-INF/${servlet-name}-servlet.xml-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-context.xml</param-value>
    </init-param>
    <!-- web应用一启动就初始化这个servlet -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <!-- 3、定义 dispatcherServlet-->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <!-- 注意:dispatcherServlet必须是“/”, 不能是“/*”;   -->
    <!-- 如果是“/*”,那么当返回modelAndView是个jsp时,它会继续走这个servlet去找“/WEB-INF/.../*.jsp”对应的controller -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <display-name>spring-web-application</display-name>
  <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

5、编写 spring-context.xml

位置:/src/main/resource/spring-context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	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.xsd">

  <!-- 定义 handlerMapping(根据url 查找 Controller) -->
  <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
  
  <!-- 定义视图解析器(根据视图名解析为对应的jsp)  -->
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/"></property>
    <property name="suffix" value=".jsp"></property>    
  </bean>
  <!-- 定义controller  -->
  <bean id="/welcome" class="com.black.app.controller.WelcomeController" />
</beans>

6、编写日志配置

位置:/src/main/resource/logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" >
    <!--0. 日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" 
         value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] [%-10.15t] %20.30logger{30}.%M[line:%L]: %m%n}"/> 
    <!-- 时间戳 -->
    <timestamp key="file_name_date" datePattern="yyyyMMdd"/>
    <!--1. 记录日志到文件-->
    <appender name="LogFile" class="ch.qos.logback.core.FileAppender">
        <!-- 日志文件名 -->
        <file>${file_name_date}/log-info-${file_name_date}.log</file>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
  <!--1. 输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <root>
        <appender-ref ref="LogFile" />
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

7、编写 Controller

package com.black.app.controller;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class WelcomeController implements Controller {
	private static Logger logger = LoggerFactory.getLogger(WelcomeController.class);
	
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("WelcomeController#handleRequest 开始处理...");
		//获取请求参数-姓名
		//request.getParameter 既支持GET 也支持POST
		String name = request.getParameter("name");
		//如果在windows乱码则进行转码
		name = new String(name.getBytes("ISO8859-1"),"UTF-8");
		logger.info("WelcomeController#handleRequest 请求参数:." + name);
		ModelAndView view = new ModelAndView();
		view.addObject("name", name);
		//返回 welcome.jsp
		view.setViewName("welcome");
		logger.info("WelcomeController#handleRequest 处理结束。");
		return view;
	}

}

8、编写 welcome.jsp

位置:/src/main/webapp/WEB-INF/welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<body>
<h2>欢迎【<%= request.getAttribute("name")%>】同学,来到我的 spring-springmvc-xml web应用</h2>
</body>
</html>

9、打包

maven compile package

war包路径:spring-springmvc-xml\target\spring-springmvc-xml.war

10、部署

将spring-springmvc-xml.war部署 apache-tomcat 下。
(1)将 spring-springmvc-xml.war 拷贝到 apache-tomcat-7.0.91\webapps\

(2)编写 apache-tomcat-7.0.91\conf\server.xml

<!-- 设置8180端口 -->
<Connector port="8180" protocol="HTTP/1.1"  connectionTimeout="20000" edirectPort="9000" />
...
<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
<!-- 增加 context标签 -->
<Context docBase="spring-springmvc-xml" path="/" reloadable="true"/>
</Host>
...

(3)启动 apache-tomcat
apache-tomcat-7.0.91\bin\startup.bat

如果闪退,记得将安装目录添加到配置环境变量CATALINA_HOME=E:\work\software\apache-tomcat-7.0.91 :

image

(4)启动后控制台打印:
image
(5)启动后,war包被解压,应用放在webapps/spring-springmvc-xml 下:

image

11、测试

(1)访问首页:http://localhost:8180/spring-springmvc-xml/

image

(2)访问欢迎页:http://localhost:8180/spring-springmvc-xml/welcome?name=小明

image

http://localhost:8180/spring-springmvc-xml/welcome?name=小红

image
(3)post 请求访问欢迎页:http://localhost:8180/spring-springmvc-xml/welcome

image

12、一些说明

12.1 web.xml context-param说明

context-param 里的 contextConfigLocation 和 init-param 的contextConfigLocation有什么区别?
(1)context-param 里的配置参数是所有的 servlet 实例共享的。
(2)context-param 里的contextConfigLocation 是 Root WebApplicationContext,是可以被很多 DispatcherServlet 实例继承的; init-param 的contextConfigLocation 是 WebApplicationContext ,只能当前 DispatcherServlet 实例拥有的配置,与其他 servlet(不仅仅是DispatcherServlet实例) 不共享。
(3)如果不需要 WebApplicationContext 的继承关系,则 context-param 里的contextConfigLocation 配置是:

  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value>
  </context-param>

如果需要 WebApplicationContext 的继承,则 context-param 里的contextConfigLocation 配置是:

  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

如果需要继承 Root WebApplicationContext 的,则 init-param 里的contextConfigLocation 配置是:

   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-context.xml</param-value>
    </init-param>

Spring 官方文档中的继承关系:

image

对应 web.xml 示例:

<web-app>
  <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/root-context.xml</param-value>
  </context-param>
  <servlet>
  <servlet-name>app1</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/app1-context.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  <servlet-name>app1</servlet-name>
  <url-pattern>/app1/*</url-pattern>
  </servlet-mapping>
</web-app>

(4) 如果context-param 不配置 contextConfigLocation 参数, 那么默认会加载 /WEB-INF/applicationContext.xml 文件;
如果文件不存在,则会报错:

2021-07-19 00:42:41.802 [INFO ] [ost-startStop-1] o.s.web.context.ContextLoader.initWebApplicationContext[line:271]: Root WebApplicationContext: initialization started
2021-07-19 00:42:42.081 [DEBUG] [ost-startStop-1] w.c.s.XmlWebApplicationContext.prepareRefresh[line:629]: Refreshing Root WebApplicationContext
2021-07-19 00:42:42.225 [ERROR] [ost-startStop-1] o.s.web.context.ContextLoader.initWebApplicationContext[line:313]: Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:671)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5157)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5680)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1018)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:994)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
	at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127)
	at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2021)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
	at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:159)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:333)
	... 25 common frames omitted

(5) 如果 dispatcherServlet init-param 不配置 contextConfigLocation 参数,会自动去加载 “/WEB-INF/${servletname}-servlet.xml” 即/WEB-INF/dispatcherServlet-servlet.xml ;如果文件不存在 那么会报错:

2021-07-19 00:39:47.019 [DEBUG] [ost-startStop-1] w.c.s.XmlWebApplicationContext.prepareRefresh[line:629]: Refreshing WebApplicationContext for namespace 'dispatcherServlet-servlet'
2021-07-19 00:39:47.031 [ERROR] [ost-startStop-1] o.s.w.s.DispatcherServlet.initServletBean[line:534]: Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:671)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
	at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702)
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668)
	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716)
	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591)
	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
	at javax.servlet.GenericServlet.init(GenericServlet.java:158)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1230)
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1174)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1066)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5409)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5707)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1018)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:994)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
	at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127)
	at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2021)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcherServlet-servlet.xml]
	at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:159)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:333)
	... 32 common frames omitted

12.2 一些特殊的Bean类型

Spring MVC 的9大组件

Bean type 解释
HandlerMapping 映射一个请求到一个Handler(有一堆拦截器);
主要有两个实现:RequestMappingHandlerMapping(支持@RequestMapping注解)和 SimpleUrlHandlerMapping(URL 映射到 一个 Handler)
HandlerAdapter 帮助DispatcherServlet调用handler
HandlerExceptionResolver 解决异常的策略
ViewResolver 根据逻辑视图名解析出真实的视图
LocaleResolver,LocaleContextResolver 解析器 Locale,为了提供国际化视图
ThemeResolver 解析应用能够使用的主题
MultipartResolver 解析multi-part请求
FlashMapManager 重定向时可以将一个请求的属性传给另一个请求


13、上传文件

有两种上传文件方式:

  • 使用Apache Commons FileUpload
  • 使用 Servlet 3.0 multipart parsing

13.1 Apache Commons FileUpload

主页:https://commons.apache.org/proper/commons-fileupload/
(1) 引入commons-fileupload jar包

 <!-- 引入 commons-fileupload-->
	<dependency>
	    <groupId>commons-fileupload</groupId>
	    <artifactId>commons-fileupload</artifactId>
	    <version>1.4</version>
	</dependency>

(2)配置 multipartResolver

 <!-- 上传下载 -->
  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  </bean>

(3)配置上传Controller
跳转上传jsp页面controller:

<bean id="/uploadpage" class="com.black.app.controller.UploadPageController" />
public class UploadPageController implements Controller {
	
	private static Logger logger = LoggerFactory.getLogger(UploadPageController.class);

	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("跳转上传文件页面...");
		ModelAndView view = new ModelAndView();
		//返回 upload.jsp
		view.setViewName("upload");
		return view;
	}
}

跳转上传动作controller:

<bean id="/upload"   class="com.black.app.controller.UploadFileController" >
      <property name="saveDir" value="d:/upload" />
  </bean>

保存上传文件到"d:/upload/"下,上传完成后返回“上传成功”

public class UploadFileController implements Controller {
	
	private static Logger logger = LoggerFactory.getLogger(UploadFileController.class);

	//保存路径
	private String saveDir;
	
	public String getSaveDir() {
		return saveDir;
	}

	public void setSaveDir(String saveDir) {
		this.saveDir = saveDir;
	}


	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("上传文件...");
		ModelAndView view = new ModelAndView();
		view.setViewName("upload-result");
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		
		if(isMultipart) {
			//创建上传路径
//			URL u = UploadFileController.class.getClassLoader().getResource("");
//			String filePathString = u.getPath()+"/upload";
			logger.info("上传路径:" + saveDir );
			File file = new File(saveDir);
			if(!file.exists()) {
				file.mkdirs();
			}
			
			MultipartHttpServletRequest mp = (MultipartHttpServletRequest)request;
			Iterator<String> iterator =  mp.getFileNames();
			while (iterator.hasNext()) {
				String fileName = iterator.next();
				MultipartFile f = mp.getFile(fileName);
				String realName =  f.getOriginalFilename();
				f.transferTo(new File(saveDir + File.separator + realName));
			}
			view.addObject("result", "成功!");
		}
		return view;
	}
}

(4)编写上传页面和上传结果页面
upload.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<% String contextPath = application.getContextPath();
%>
<html>
<body>
<h2>上传文件</h2>
<form method="POST" enctype="multipart/form-data" action="<%=contextPath %>/upload">
    选择文件: <input type="file" name="upfile"><br/>
  备注: <input type="text" name="note"><br/>
  <br/>
  <input type="submit" value="Press"> 上传
</form>
</body>
</html>

upload-result.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<body>
<h2>上传文件<%= request.getAttribute("result")%></h2>
</body>
</html>

(5)验证
浏览器访问 http://localhost:8180/spring-springmvc-xml/uploadpage

image


选择上传redis-6.2.0.tar.gz文件:
image


点击【Press】上传,结果:
image


查看d:/upload/文件:
image


至此,使用 commons-fileupload 上传文件成功!

13.2 Servlet 3.0 multipart parsing

(1) web.xml 增加<multipart-config>配置

<servlet>
...
    <!-- 上传 配置-->
    <multipart-config>
      <location> d:/upload
      </location>
      <!--max-file-size:单个文件最大大小(-1:无限制)-->
      <max-file-size>-1</max-file-size>
      <!-- max-request-size:所有文件最大大小(-1:无限制)-->
      <max-request-size>-1</max-request-size>
      <!-- 超过 file-size-threshold 时会被写到磁盘-->
      <file-size-threshold>0</file-size-threshold>
    </multipart-config>
    ...
</servlet>

(2) 配置 StandardServletMultipartResolver

  <!-- 上传下载 (servlet3.0  必须在web.xml  增加multipart-config配置) --> 
  <bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
  </bean>

(3)使用 13.1 的Controller 和jsp页面
(4)验证

浏览器访问 http://localhost:8180/spring-springmvc-xml/uploadpage

image


image


查看d:/upload/文件:

image


posted on 2021-07-19 02:06  不安分的黑娃  阅读(169)  评论(0编辑  收藏  举报