Spring MVC

前摘

在这位大佬:Spring MVC【入门】就这一篇!
的基础上略作修改及讲解
代码已上传到CSDN

1.Spring MVC结构

在这里插入图片描述
传统的模型层被拆分为了业务层(Service)和数据访问层(DAO,Data Access Object)。
在 Service 下可以通过 Spring 的声明式事务操作数据访问层,而在业务层上还允许我们访问 NoSQL ,这样就能够满足异军突起的 NoSQL 的使用了,它可以大大提高互联网系统的性能。

2.使用web.xml配置Spring MVC

  1. 新建项目HelloSpringMVC,我是在IDEA中
  2. 配置路径
  3. 在WEB-INF目录下创建 web.xml
    注意:\<servlet-name>dispatcher\</servlet-name>
    dispatcher这个名字在下一步会用到
<!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 version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Archetype Created Web Application</display-name>

    <!-- 将applicationContext.xml添加进来 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <!-- 拦截所有的请求 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

把<url-pattern>元素的值改为 / ,表示要拦截所有的请求,并交由Spring MVC的后台控制器来处理,

  1. 在WEB-INF目录下编辑 dispatcher-servlet.xml
    dispatcher-servlet.xml 这个文件名的开头 dispatcher 与上面 web.xml 中的 <servlet-name> 元素配置的 dispatcher 对应,这是 Spring MVC 的映射配置文件(xxx-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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="simpleUrlHandlerMapping"
          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <!-- /hello 路径的请求交给 id 为 helloController 的控制器处理-->
                <prop key="/hello">helloController</prop>
            </props>
        </property>
    </bean>
    <bean id="helloController" class="controller.HelloController"></bean>
</beans>
  1. 编写 HelloController
    在 Package【controller】下创建 【HelloController】类,并实现 org.springframework.web.servlet.mvc.Controller 接口:
package controller;

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

public class HelloController implements Controller{
    @Override
    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
    	/*
		Spring MVC 通过 ModelAndView 对象把模型和视图结合在一起
		这里表示视图的是index.jsp
		模型数据的是 message,内容是 “Hello Spring MVC”
		*/
        ModelAndView mav = new ModelAndView("index.jsp");
        mav.addObject("message", "Hello Spring MVC");
        return mav;
    }
}
  1. 准备 index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
<h1>${message}</h1>

内容很简单,用El表达式显示 message 的内容。

  1. 部署 Tomcat 及相关环境 及运行

    运行结果就是这样,注意域名:
    在这里插入图片描述

3.原理解析

  1. DispatcherServlet
    在这里插入图片描述
    我们在web.xml中设置了DispatcherServlet这个servlet的\<url-pattern>/,在该匹配模式下,客户端只能通过唯一的路径来访问这个Servlet,DispatcherServlet 会拦截所有的请求,并且将这些请求发送给 Spring MVC 控制器。
  2. 第二站:处理器映射(HandlerMapping)
  • 典型的应用程序中可能会有多个控制器,这些请求到底应该发给哪一个控制器呢?

所以 DispatcherServlet 会查询一个或多个处理器映射来确定请求的下一站在哪里,处理器映射会根据请求所携带的 URL 信息来进行决策
例如上面的例子中,我们通过配置 dispatcher-servlet.xml文件中的simpleUrlHandlerMapping来将 /hello 地址交给 helloController 处理。helloController是一个bean,对应HelloController类:

<bean id="simpleUrlHandlerMapping"
      class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <!-- /hello 路径的请求交给 id 为 helloController 的控制器处理-->
            <prop key="/hello">helloController</prop>
        </props>
    </property>
</bean>
<bean id="helloController" class="controller.HelloController"></bean>
  1. 第三站:控制器
    一旦选择了合适的控制器, DispatcherServlet 会将请求发送给选中的控制器,到了控制器,请求会卸下其负载(用户提交的请求)等待控制器处理完这些信息:
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
    // 处理逻辑
    ....
}
  1. 第四站:返回 DispatcherServlet

当控制器在完成逻辑处理后,通常会产生一些信息,这些信息就是需要返回给用户并在浏览器上显示的信息,它们被称为模型(Model)
仅仅返回原始的信息时不够的——这些信息需要以用户友好的方式进行格式化,一般会是 HTML,所以,信息需要发送给一个视图(view),通常会是 JSP。

控制器所做的最后一件事就是将模型数据打包,并且表示出用于渲染输出的视图名(逻辑视图名)。它接下来会将请求连同模型和视图名发送回 DispatcherServlet。

public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
    // 处理逻辑
    ....
    // 返回给 DispatcherServlet
    return mav;
}
  1. 第五站:视图解析器

这样一来,控制器就不会和特定的视图相耦合,传递给 DispatcherServlet 的视图名并不直接表示某个特定的 JSP。(实际上,它甚至不能确定视图就是 JSP)相反,它传递的仅仅是一个逻辑名称,这个名称将会用来查找产生结果的真正视图。

DispatcherServlet 将会使用视图解析器(view resolver)来将逻辑视图名匹配为一个特定的视图实现,它可能是也可能不是 JSP

上面的例子是直接绑定到了 index.jsp 视图

  1. 第六站:视图

既然 DispatcherServlet 已经知道由哪个视图渲染结果了,那请求的任务基本上也就完成了。

它的最后一站是视图的实现,在这里它交付模型数据,请求的任务也就完成了。视图使用模型数据渲染出结果,这个输出结果会通过响应对象传递给客户端。

4.使用注解配置 Spring MVC

通过上面的例子我们已经对 Spring MVC 有了一定的了解,并且通过 XML 配置的方式创建了第一个 Spring MVC 程序,我们来看看基于注解应该怎么完成上述程序的配置:

  1. 第一步:为 HelloController 添加注解
package controller;

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

@Controller
public class HelloController{
    @RequestMapping("/hello")
    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mav = new ModelAndView("index.jsp");
        mav.addObject("message", "Hello Spring MVC");
        return mav;
    }
}

注解详情

  • @Controller 注解:
    很明显,这个注解是用来声明控制器的,但实际上这个注解对 Spring MVC 本身的影响并不大。(Spring 实战说它仅仅是辅助实现组件扫描,可以用@Component注解代替,但我自己尝试了一下并不行,因为上述例子没有配置 JSP 视图解析器我还自己配了一个仍没有成功…)
  • @RequestMapping 注解:
    很显然,这就表示路径/hello会映射到该方法上
  1. 第二步:取消之前的 XML 注释

在 dispatcher-servlet.xml 文件中,注释掉之前的配置,然后增加一句组件扫描,注意修改了<beans的属性,不然<context会报错:

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!--    <bean id="simpleUrlHandlerMapping"-->
<!--          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">-->
<!--        <property name="mappings">-->
<!--            <props>-->
<!--                &lt;!&ndash; /hello 路径的请求交给 id 为 helloController 的控制器处理&ndash;&gt;-->
<!--                <prop key="/hello">helloController</prop>-->
<!--            </props>-->
<!--        </property>-->
<!--    </bean>-->
<!--    <bean id="helloController" class="controller.HelloController"></bean>-->
    <!-- 扫描controller下的组件 -->
    <context:component-scan base-package="controller"/>
</beans>
  1. 第三步:重启服务器
    在这里插入图片描述
  • @RequestMapping 注解细节
    如果 @RequestMapping 作用在类上,那么就相当于是给该类所有配置的映射地址前加上了一个地址,例如:
@Controller
@RequestMapping("/wtf")
public class HelloController {
    @RequestMapping("/hello")
    public ModelAndView handleRequest(....) throws Exception {
        ....
    }
}

则访问地址: http://localhost:8090/HelloSpringMVC/wtf/hello

3.配置视图解析器

视图解析器负责定位视图,它接受一个由 DispaterServlet 传递过来的逻辑视图名来匹配一个特定的视图
在前面的例子中,我们把视图直接绑定为index.jsp文件。现在我们要修改它

如果代码写成这样,就表示跳转到页面 index.jsp
new ModelAndView("index.jsp");

所谓的视图定位,指的是代码还是写成这样,但是会跳转到 /WEB-INF/page/index.jsp
new ModelAndView("index");

  • 需求: 有一些页面我们不希望用户用户直接访问到,例如有重要数据的页面,例如有模型数据支撑的页面。
  • 造成的问题:
    我们可以在【web】根目录下放置一个【test.jsp】模拟一个重要数据的页面,我们什么都不用做,重新启动服务器,网页中输入localhost/test.jsp就能够直接访问到了,这会造成数据泄露…
    另外我们可以直接输入localhost/index.jsp试试,根据我们上面的程序,这会是一个空白的页面,因为并没有获取到${message}参数就直接访问了,这会影响用户体验

解决方案

我们将我们的 JSP 文件配置在【WEB-INF】文件夹中的【page】文件夹下,【WEB-INF】是 Java Web 中默认的安全目录,是不允许用户直接访问的(也就是你说你通过 localhost/WEB-INF/ 这样的方式是永远访问不到的)

但是我们需要将这告诉给视图解析器,我们在 dispatcher-servlet.xml 文件中做如下配置:

<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/page/" />
    <property name="suffix" value=".jsp" />
</bean>

这里配置了一个 Spring MVC 内置的一个视图解析器,该解析器是遵循着一种约定:会在视图名上添加前缀和后缀,进而确定一个 Web 应用中视图资源的物理路径的。让我们实际来看看效果:

  1. 第一步:修改 HelloController

我们将代码修改一下:
在这里插入图片描述

  1. 第二步:配置视图解析器:

按照上述的配置, dispatcher-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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!--    <bean id="simpleUrlHandlerMapping"-->
<!--          class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">-->
<!--        <property name="mappings">-->
<!--            <props>-->
<!--                &lt;!&ndash; /hello 路径的请求交给 id 为 helloController 的控制器处理&ndash;&gt;-->
<!--                <prop key="/hello">helloController</prop>-->
<!--            </props>-->
<!--        </property>-->
<!--    </bean>-->
<!--    <bean id="helloController" class="controller.HelloController"></bean>-->
    <!-- 扫描controller下的组件 -->
    <context:component-scan base-package="controller"/>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>
  1. 第三步:剪贴 index.jsp 文件

在【WEB-INF】文件夹下新建一个【page】文件夹,并将【index.jsp】文件剪贴到里面:

  1. 第四步:更新资源重启服务器
    在这里插入图片描述

原理:

在这里插入图片描述

  • 注意:此时的配置仅是 dispatcher-servlet.xml 下的
    在这里插入图片描述
  1. 通过web.xml转发给org.springframework.web.servlet.DispatcherServlet,
  2. 通过处理器映射,交给id=HelloController的bean处理,
  3. 找到controller包下的HelloController.java,
  4. 控制器(HelloController.java)传递模型及视图,new ModelAndView(“index”);跳转到index,
  5. 但要加上dispatcher-serlvet.xml中的viewResolver配置的前缀prefix后缀suffix,
  6. 最后就成了/WEB-INF/page/index.jsp 。

4.控制器接受请求数据

使用控制器接收参数往往是 Spring MVC 开发业务逻辑的第一步,为探索 Spring MVC 的传参方式,为此我们先来创建一个简单的表单用于提交数据:

1.在page文件夹里建立test.jsp

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
<html>
<head>
    <title>测试表单</title>
</head>
<body>
<form action="param1" method="post">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    <br/>
    <input type="submit" value="提  交 到param1 自己从Req里面获取">
</form>


<form action="param2" method="post">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    <br/>
    <input type="submit" value="提  交 到param2 直接使用同名参数">
</form>

<form action="param3" method="post">
    用户名:<input type="text" name="YourUsername"><br/>
    密码:<input type="text" name="password"><br/>
    <br/>
    <input type="submit" value="提  交 到param3 使用@RequestParam来指定UI发过来的名字">
</form>

<form action="param4" method="post">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    <br/>
    <input type="submit" value="提  交 到param4 使用模型传参">
</form>

</body>
</html>

注意注意:
action里不带/打开的路径带项目名,如:http://localhost:8090/HelloSpringMVC/param,
如果带/打开的路径不带项目名,如:http://localhost:8090/param,
这里不展开讲

2.在page里建立test2.jsp用来显示数据

用于控制器回显数据,后面讲

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Spring 消息</title>
  </head>
  <body>
  <h1>${message}</h1>
  </body>
</html>

3.在controller中建立TestController.java作为控制器接受参数

@Controller
public class TestController
{
	//设置路径,不设置模型、视图
    @RequestMapping("/test")
    public ModelAndView testPage(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        return new ModelAndView("test");
    }
    //定义print方法,转到test2.jsp中用于输出接收到的数据
    private ModelAndView print(String username, String password) {
        System.out.println("username is " + username);
        System.out.println("password is " + password);
        String message =  String.format("user=%s,password=%s", username, password);
        ModelAndView modelAndView = new ModelAndView("test2");
        modelAndView.addObject("message", message);
        return modelAndView;
    }
}

使用 Servlet 原生 API 实现:

我们很容易知道,表单会提交到 /param 这个目录,我们先来使用 Servlet 原生的 API 来看看能不能获取到数据,在TestController.java添加:

	/**
     * 传递参数: 自己从Req里面获取
     * @param httpServletRequest
     * @param httpServletResponse
     * @return
     * @throws Exception
     */
    @RequestMapping("/param1")
    public ModelAndView postParam(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        String username = httpServletRequest.getParameter("username");
        String password = httpServletRequest.getParameter("password");
        return print(username, password);
    }

使用同名匹配规则

在TestController.java添加:

/**
     * 传递参数2: 直接使用同名参数
     * @param username 这个与JSP文件的参数同名
     * @param password 这个与JSP文件的参数同名
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/param2", method = RequestMethod.POST)
    public ModelAndView postParam2(String username, String password) throws Exception {
        return print(username, password);
    }
  • 问题: 这样又会和前台产生很强的耦合,这是我们不希望的
  • 解决: 使用 @RequestParam(“前台参数名”) 来注入:

使用 @RequestParam(“前台参数名”) 来注入

在TestController.java添加:

/**
     * 传递参数3: 使用@RequestParam来指定UI发过来的名字
     * @param username
     * @param password
     * @return
     * @throws Exception
     * @RequestParam里放置jsp文件的参数名
     */
    @RequestMapping(value = "/param3", method = RequestMethod.POST)
    public ModelAndView postParam3(@RequestParam("YourUsername") String username,
                                   @RequestParam("password") String password) throws Exception {
        return print(username, password);
    }
  • @RequestParam 注解细节:
    该注解有三个变量:valuerequireddefaultvalue
    value :指定 name 属性的名称是什么,value 属性都可以默认不写
    required :是否必须要有该参数,可以设置为【true】或者【false】
    defaultvalue :设置默认值

我个人觉得:这和前一种区别大吗?我不要你觉得,我要我觉得

使用模型传参

要求: 前台参数名字必须和模型中的字段名一样
在dao文件夹创建一个 User 模型:

package dao;

public class User {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

在TestController.java添加:

/**
     * 传递参数4: 使用模型传参
     * @param user
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/param4", method = RequestMethod.POST)
    public ModelAndView postParam4(User user) throws Exception {
        return print(user.getUsername(), user.getPassword());
    }

5.中文乱码问题

当我们依照上面的方法,传递的数据是中文就会出现乱码问题
我们可以通过配置 Spring MVC 字符编码过滤器来完成,在 web.xml 中添加:

<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 中的一样,该方法只对 POST 方法有效(因为是直接处理的 request)

5.控制器回显数据

数据回显:模型数据导向视图(模型数据 —> Controller —> 视图) 说明:SpringMVC在调用方法前会创建一个隐含的模型对象,作为模型数据的存储容器(隐含模型)

通过上面,我们知道了怎么接受请求数据,并能解决 POST 乱码的问题,那么我们怎么回显数据呢?这就是我们前面创建的【test2.jsp】:

1.使用 Spring MVC 所提供的 ModelAndView 对象

就是我们在前面的print方法中使用的

ModelAndView modelAndView = new ModelAndView("test2");
modelAndView.addObject("message", message);
return modelAndView;

当我们调用postParam 1234中的一个方法时,它返回ModelAndView,然后就会通过视图解析器到达视图。

2.使用 Model 对象

@ModelAttribute
public void model(Model model) {
	model.addAttribute("message", "注解成功");
}
@RequestMapping("/value")
public String handleRequest() {
    return "test2";
}

先调用model方法,再调用handleRequest。
这个怎么代替我们的print方法呢??
这样:

/**
     * 传递参数5:使用Model接收
     * @param user
     * @param model
     * @return String
     */
    @RequestMapping(value = "/param5", method = RequestMethod.POST)
    public String addStudent(@ModelAttribute("User")User user,
                             ModelMap model) {
        String message =  String.format("username=%s,password=%s", user.getUsername(), user.getPassword());
        model.addAttribute("message", message);
        return "test2";
    }

@ModelAttribute注解里面怎么写都行?我现在不大懂

6.客户端跳转

前面不管是地址/hello跳转到 index.jsp 还是/test跳转到 test.jsp,这些都是服务端的跳转,也就是 request.getRequestDispatcher(“地址”).forward(request, response);这是转发,详见HttpServletResponse与HttpServletRequest
中转发与重定向的区别

@Controller
public class HelloController{
    @RequestMapping("/hello")
    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mav = new ModelAndView("index");
        mav.addObject("message", "Hello Spring MVC");
        return mav;
    }

    /**
     * 客户端跳转
     * @return ModelAndView
     */
    @RequestMapping("/jump")
    public ModelAndView jump() {
        ModelAndView m = new ModelAndView("redirect:/hello");
        return m;
    }
}

我们使用redirect:/hello就表示我们要跳转到/hello这个路径,我们重启服务器,在地址栏中输入:http://localhost:8090/HelloSpringMVC/jump,会自动跳转到/hello路径下
也可以这样用:

@RequestMapping("/jump")
public String jump() {
    return "redirect: ./hello";
}

7.文件上传

  • 注意: 需要先导入 commons-io-1.3.2.jar 和 commons-fileupload-1.2.1.jar 两个包

1.第一步:配置上传解析器

在 dispatcher-servlet.xml 中新增一句:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

开启对上传功能的支持

2.第二步:编写 JSP

文件名为 upload.jsp,仍创建在【page】下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试文件上传</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="picture">
    <input type="submit" value="上 传">
</form>
</body>
</html>

3.第三步:编写控制器

在 Package【controller】下新建【UploadController】类:

package controller;

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 org.springframework.web.servlet.ModelAndView;

@Controller
public class UploadController {

    @RequestMapping("/upload")
    public void upload(@RequestParam("picture") MultipartFile picture) throws Exception {
        System.out.println(picture.getOriginalFilename());
    }

    @RequestMapping("/test3")
    public ModelAndView upload() {
        return new ModelAndView("upload");
    }

}

4.第四步:测试

在浏览器地址栏中输入:http://localhost:8090/HelloSpringMVC/test3 ,选择文件点击上传,测试成功:
在这里插入图片描述
不能在地址栏输入http://localhost:8090/HelloSpringMVC/upload

我还编写了test4上传完图片后会显示出来,代码不贴了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值