Spring MVC

一、Spring MVC的简介

  • Spring MVC是Spring提供的MVC框架
  • Spring MVC是Spring Framework的一部分,负责表示层

二、Spring MVC的架构图

三、Spring MVC的入门案例

1. 入门案例一

1.1 在pom.xml中导入相关依赖

<!--导入spring-webmvc会自动导入spring的相关依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.7.RELEASE</version>
</dependency>
<!--入门案例一使用了,所以要导入-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>3.0-alpha-1</version>
    <scope>provided</scope>
</dependency>

1.2 在web.xml中配置控制器并加载Spring的配置文件

<?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>
            dispatcherServlet
        </servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <!--加载Spring的配置文件-->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:application.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <!--dispatcherServlet的url为"/",千万注意-->
        <!--不能配置为/*,否则Spring MVC给出的结果视图是JSP的话,因为是转发,会出现循环,出现又进入springmvc的情况-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

1.3 在application.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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--开启Spring的注解扫描-->
    <context:component-scan base-package="com.chenlianyuan"/>
    <!--映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--处理适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    
    <bean name="/hello" class="com.cskaoyan.controller.HelloController"/>

</beans>

1.4 创建controller类用于演示

package com.cskaoyan.controller;

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

public class HelloController implements Controller {

    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest,javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView modelAndView = new ModelAndView();
        String value = "SpringMvc";
        modelAndView.setViewName("hello.jsp");
        modelAndView.addObject("value",value);
        return modelAndView;
    }

}

1.5 创建JSP页面用于演示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        Hello ${value}
    </body>
</html>

1.6 结果

2. 入门案例二

2.1 在pom.xml中导入相关依赖

同入门案例一

2.2 在web.xml中配置控制器并加载Spring的配置文件

同入门案例一

2.3 开启Spring MVC的注解扫描(及注册驱动)

<?xml version="1.0" encoding="UTF-8"?>
<!--需要一个mvc的标签-->
<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:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--Spring的注解开关-->
    <context:component-scan base-package="com.cskaoyan"/>
    <!--Spring MVC的注解开关(注册驱动)-->
    <!--加了这句话以后会自动配置最新版的注解的处理器映射器和处理器适配器-->
    <mvc:annotation-driven/>
    
</beans>

2.4 创建controller类用于演示

package com.cskaoyan.controller;

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

@Controller
public class HelloController {

    @RequestMapping("hello")
    public ModelAndView hello1(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("hello.jsp");
        modelAndView.addObject("value","Hello Spring MVC");
        return modelAndView;
    }

}

2.5 创建JSP页面用于演示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        Hello ${value}
    </body>
</html>

2.6 结果

三、Spring MVC的用法

1. URL路径映射

1.1 一个URL映射到一个方法上

//代码节选
@Controller
public class MyController{
    //URL和方法建立联系
    @RequestMapping(value = "hello")
    public ModelAndView hello(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/hello.jsp");
        modelAndView.addObject("value","Spring MVC");
        return modelAndView;
    }
    //URL和方法建立联系
    @RequestMapping(value = "goodbye")
    public ModelAndView hello1(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/goodbye.jsp");
        modelAndView.addObject("value","Spring MVC");
        return modelAndView;
    }

}

1.2 多个URL映射到一个方法上(一一列举)

//代码节选
@Controller
public class MyController{
    //多个URL和方法建立联系
    @RequestMapping(value = {"login1","login2","login3"})
    public ModelAndView login(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/login.jsp");
        modelAndView.addObject("value","Please sign in");
        return modelAndView;
    }

}

1.3 多个URL映射到一个方法上(使用通配符)

//代码节选
@Controller
public class MyController{

    //多个URL和方法建立联系
    @RequestMapping(value = {"login*"})
    public ModelAndView hello(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/login.jsp");
        modelAndView.addObject("value","Please sign in");
        return modelAndView;
    }

}

2. 请求方法限定(错误码405)

2.1 方式一

//代码节选
@Controller
@RequestMapping("user")
public class UserController{
    //限定了请求方法
    @RequestMapping(value = "register",method = RequestMethod.POST)
    public ModelAndView register(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/user.jsp");
        modelAndView.addObject("method","register");
        return modelAndView;
    }

}

2.2 方式二

//代码节选
@Controller
@RequestMapping("user")
public class UserController{

    //注解上已限定了请求方法
    @PostMapping("login")
    //@GetMapping("login")
    public ModelAndView login(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/login.jsp");
        modelAndView.addObject("method","register");
        return modelAndView;
    }

}
//代码节选
//@PostMapping注解内部
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@RequestMapping(
    method = {RequestMethod.POST}
)
public @interface PostMapping {
    ...//省略
}

3. 参数的限定(错误码400)

3.1 限定必须有某个参数

//代码节选
@Controller
@RequestMapping("user")
public class UserController{

    //要求必须要有"username"和"password"两个参数
    @RequestMapping(value = "login",method = RequestMethod.POST,params ={"username","password"})
    public ModelAndView login(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/login.jsp");
        modelAndView.addObject("method","register");
        return modelAndView;
    }

}

3.2 限定参数的值

//代码节选
@Controller
@RequestMapping("user")
public class UserController{

    //要求"username"参数的值不能为"XiDaDa"
    @RequestMapping(value = "login",method = RequestMethod.POST,params ={"username!=XiDaDa","password"})
    public ModelAndView login(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/login.jsp");
        modelAndView.addObject("method","register");
        return modelAndView;
    }

}

4. Content-type的限定(错误码415)

//代码节选
@Controller
@RequestMapping("user")
public class UserController{

    //限定了Content-type类型
    @RequestMapping(value = "login",method = RequestMethod.POST,params ={"username!=XiDaDa","password"},consumes = "text/html")
    public ModelAndView login(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/login.jsp");
        modelAndView.addObject("method","register");
        return modelAndView;
    }

}

5. Accept限定(错误码406)

//代码节选
@Controller
@RequestMapping("user")
public class UserController{

    //限定了Accept类型
    @RequestMapping(value = "login",method = RequestMethod.POST,params ={"username!=XiDaDa","password"},produces = "text/html")
    public ModelAndView login(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/login.jsp");
        modelAndView.addObject("method","register");
        return modelAndView;
    }

}

五、Spring MVC的Controller方法的返回值

1. 返回ModelAndView

//节选部分代码
@Controller
@RequestMapping(value = "hello")
public class MyController {
    
    @RequestMapping(value = "modelAndView")
    public ModelAndView showUser() throws Exception{
        User user = new User();
        user.setAge(1);
        user.setName("ChenLianYuan");
        user.setPhoneNumber("123456789");
        //新建一个ModelAndView类
        ModelAndView modelAndView = new ModelAndView();
        //Model处理:通过modelandView的addObject方法
        modelAndView.addObject("user",user);
        //View的处理:通过modelandView的setViewName方法
        modelAndView.setViewName("user");
        return modelAndView;
    }
    
}
<!--user.jsp-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Hello Spring MVC</title>
    </head>
    <body>
        Hello ${user}
    </body>
</html>

2. 返回void

//节选部分代码
@Controller
public class MyController {

    @RequestMapping(value = "void")
    public void showUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception{
        User user = new User();
        user.setAge(1);
        user.setName("ChenLianYuan");
        user.setPhoneNumber("123456789");
        //通过Request和Response去实现Model和view的处理
        httpServletRequest.setAttribute("user",user);
        httpServletRequest.getRequestDispatcher("/WEB-INF/user.jsp").forward(httpServletRequest,httpServletResponse);
        return;
    }
    
}
<!--user.jsp-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Hello Spring MVC</title>
    </head>
    <body>
        Hello ${user}
    </body>
</html>

3. 返回字符串

3.1 物理视图名

//节选部分代码
@Controller
public class MyController {

    @RequestMapping(value = "unhappy")
    //使用的是org.springframework.ui.Model
    public String unHappy(Model model){
        model.addAttribute("method","unHappy");
        //物理视图
        return "/WEB-INF/view/Hellp.jsp";
    }

}

3.2 逻辑视图名

@Controller
public class MyController {

    @RequestMapping(value = "unhappy")
    //使用的是org.springframework.ui.Model
    public String unHappy(Model model){
        model.addAttribute("method","unHappy");
        return "Hello";
    }

}
<!--配置视图解析器-->
<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/view/"/>
    <property name="suffix" value=".jsp"/>
</bean>

3.3 重定向

//重定向的是URL,而不是页面
@Controller
public class MyController {
          
    //重定向到了这个方法
    @RequestMapping(value = "hello2")
    public String hello2(){
        return "/WEB-INF/view/hello1.jsp";
    }
    
    @RequestMapping(value = "hello3")
    public String hello3(){
        return "forward:hello2";
        //重定向到了hello2(),而不是hello2.jsp
        //最终结果是访问到了hello1.jsp
    }
    
}

3.4 转发

4. 返回JSON(演示)

4.1 导入依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9</version>
</dependency>

4.2 演示返回JSON数据

4.2.1 使用@ResponseBody

@Controller
public class HelloController {
    
    @RequestMapping("hello")
    //JSON的注解。使返回值是JSON格式
    @ResponseBody
    public User hello(){
        User user = new User();
        user.setUsername("ChenLianYuan");
        user.setPassword("123456");
        user.setId(1);
        Hobby hobby = new Hobby();
        hobby.setName("rap");
        user.setHobby(hobby);
        return user;
    }
    
}

4.2.2 使用@RestController

//此注解是@Controller和@ResponseBody的结合
//使用此注解相当于在当前类下的所有@RequestMapping的方法上都加了@ResponseBody注解
@RestController
public class HelloController {
    
    @RequestMapping("hello")
    public User hello(){
        User user = new User();
        user.setUsername("ChenLianYuan");
        user.setPassword("123456");
        user.setId(1);
        Hobby hobby = new Hobby();
        hobby.setName("rap");
        user.setHobby(hobby);
        return user;
    }
    
}

4.3 额外演示下接收JSON数据(使用Postman)

@RestController
public class GoodbyeController {
    
    @RequestMapping("goodbye")
    public User Goodbye(@RequestBody User user){
        return user;
    }
    
}

六、Spring MVC的请求参数的封装

1. 通过Request封装(以后不再使用这个)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <form action="/submitRequest" method="post">
            <imput type="text" name="username"/><br/>
            <imput type="text" name="password"/><br/>
            <imput type="submit"/>
        </form>
    </body>
</html>
@Controller
public class GoodbyeController {
    
    @RequestMapping("submitRequest")
    public ModelAndView getParameterByRequest(HttpServletRequest request){
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/WEB-INF/view/show.jsp");
        User user = new User(username,password);
        modelAndView.addObject("user",user);
        return modelAndView;
    }
    
}

2. 自动封装(需要注意乱码问题和日期转换问题)

2.1 基本类型

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>基本类型参数的封装</title>
    </head>
    <body>
        <form action="/submitBaseParameter" method="post">
            <imput type="text" name="username"/><br/>
            <imput type="text" name="password"/><br/>
            <imput type="text" name="age"/><br/>
            <imput type="text" name="married"/><br/>
            <imput type="submit"/>
        </form>
    </body>
</html>
//我们将age和married转换成int和boolean类型的值
//通过Spring MVC默认提供的类型转换器
@Controller
public class MyController {
    //要求请求方法的形参的参数名要和input标签的name对应
    @RequestMapping("submitBaseParameter")
    public String getBaseParameter(String username,String password,int age,boolean married,Model model){
        User user = new User(username,password,age,married);
        model.addAttribute("user",user);
        return "show";
    }
    
}

2.2 单级JavaBean

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Java Bean类型参数的封装</title>
    </head>
    <body>
        <form action="/submitJavaBeanParameter" method="post">
            <imput type="text" name="username"/><br/>
            <imput type="text" name="password"/><br/>
            <imput type="text" name="age"/><br/>
            <imput type="text" name="married"/><br/>
            <imput type="submit"/>
        </form>
    </body>
</html>
@Controller
public class MyController {
    //Java Bean写在请求方法的形参中
    //要求Java Bean的成员变量名和input标签中的name一致
    @RequestMapping("submitJavaBeanParameter")
    public String getBaseParameter(User user,Model model){
        User user = new User(username,password,age,married);
        model.addAttribute("user",user);
        return "show";
    }
    
}

2.3 多级JavaBean

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>多级Java Bean类型参数的封装</title>
    </head>
    <body>
        <form action="/submitMultiJavaBeanParameter" method="post">
            <imput type="text" name="user.username"/><br/>
            <imput type="text" name="user.password"/><br/>
            <imput type="text" name="user.age"/><br/>
            <imput type="text" name="user.married"/><br/>
            <imput type="text" name="description"/><br/>
            <imput type="text" name="count"/><br/>
            <imput type="submit"/>
        </form>
    </body>
</html>
public class SuperBean {
    
    private User user;
    
    private String descirption;
    
    private int count;
    
    ...//省略
    
}
//多级Java Bean的成员变量名,要和input标签的头一级目录对应

2.4 日期(需要转换器)

<mvc:annotation-driven conversion-service="conversionService"/>

<bean id="myconverter" class="com.chenlianyuan.converter.StringToDateConverter"/>

<bean id="conversionService" 
      class="org.Springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <ref bean="myconverter"/>
        </set>
    </property>
</bean>
package com.chenlianyuan.converter;

public class StringToDateConverter implements Converter<String,Date> {
    
    @Override
    public Date convert(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");
        try {
            Date parse = simpleDateFormat.parse(s);
            return parse;
        } catch(ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    
}

2.5 数组(基本类型)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>数组类型(基本类型)参数的封装</title>
    </head>
    <body>
        <form action="/submitArray" method="post">
            <imput type="text" name="array"/><br/>
            <imput type="text" name="array"/><br/>
            <imput type="text" name="array"/><br/>
            <imput type="text" name="array"/><br/>
            <imput type="text" name="array"/><br/>
            <imput type="submit"/>
        </form>
    </body>
</html>
//使用同一个name,并且input标签中的name与形参的参数名对应
@Controller
public class MyController {
    
    @RequestMapping("submitArray")
    public String getArray(String[] array){
        System.out.println(Arrays.toString(array));
        return "show";
    }
    
}

2.6 数组(JavaBean)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>数组类型(JavaBean)参数的封装</title>
    </head>
    <body>
        <form action="/submitArrayInJavaBean" method="post">
            <imput type="text" name="name"/><br/>
            <imput type="text" name="array"/><br/>
            <imput type="text" name="array"/><br/>
            <imput type="text" name="array"/><br/>
            <imput type="text" name="array"/><br/>
            <imput type="submit"/>
        </form>
    </body>
</html>
public class ArrayBean {
    
    String[] array;
    
    String name;
        
    ...//省略
        
}
@Controller
public class MyController {
    
    @RequestMapping("submitArrayInJavaBean")
    public String getArray(ArrayBean arrayBean){
        String[] array = arrayBean.getArray();
        System.out.println(Arrays.toString(array));
        return "show";
    }
    
}

2.7 集合(用List演示)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>多级Java Bean类型参数的封装</title>
    </head>
    <body>
        <form action="/submitListBean" method="post">
            <imput type="text" name="user.username"/><br/>
            <imput type="text" name="user.password"/><br/>
            <imput type="text" name="user.age"/><br/>
            <imput type="text" name="user.married"/><br/>
            <imput type="text" name="abc"/><br/>
            <!--User要和成员变量名对应-->
            <imput type="text" name="users[0].name"/><br/>
            <imput type="text" name="users[0].password"/><br/>          
            <imput type="text" name="users[0].age"/><br/>
            <imput type="text" name="users[0].married"/><br/>
            <imput type="text" name="users[1].name"/><br/>
            <imput type="text" name="users[1].password"/><br/>          
            <imput type="text" name="users[1].age"/><br/>
            <imput type="text" name="users[1].married"/><br/>
            <imput type="submit"/>
        </form>
    </body>
</html>
public class ListBean {
    
    User user;
    
    int abc;
    
    ArrayList<User> users;
    
    ...//省略
        
}
@Controller
public class MyController {

    @RequestMapping("submitListBean")
    public String getListBean(ListBean listBean,Model model){
        ...
        return "show";
    }
    
}

七、Spring MVC的文件上传(演示)

1. 导入依赖(pom.xml)

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

2. 配置表单(FileUpload.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>FileUpload</title>
    </head>
    <body>
        <h1>文件上传</h1>
        <%--form表单提交默认是application/x-www-form-urlencoded--%>
        <%--而上传文件把文件用二进制的方式传输,默认的格式已经满足不了需求,就需要使用multipart/form-data格式来发送接收--%>
        <form action="fileupload" enctype="multipart/form-data" method="post">
            <input type="file" name="myfile"/><br/>
            <input type="submit">
        </form>
    </body>
</html>

3. 配置上传成功页面(success.jsp)

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

4. 配置文件上传的处理器(application.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!--需要一个mvc的标签-->
<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:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--Spring的注解开关-->
    <!--<context:component-scan base-package="com.chenlianyuan"/>-->
    <!--Spring MVC的注解开关-->
    <mvc:annotation-driven/>

    <!--id一定要等于multipartResolver-->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--可以限制上传的文件的大小-->
        <!--设置上传的文件的最大尺寸为5MB-->
        <property name="maxUploadSize">
            <value>5242880</value>
        </property>
    </bean>

</beans>

5. 创建controller类用于演示

package com.chenlianyuan.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

public class MyController {

    @RequestMapping(value = "fileupload")
    //参数名要和input标签中的name一致
    public String fileupload(MultipartFile myfile) throws IOException{
        //创建一个文件夹用来接收文件
        File directory = new File("D://FileUpload");
        if (!directory.exists()){
            directory.mkdir();
        }
        String name = myfile.getName();
        File file = new File(directory,name);
        //接收文件的核心代码
        myfile.transferTo(file);
        return "/success.jsp";
    }

}

6. 注册controller类(application.xml)

<!--在3.所在的application.xml中注册-->

八、Spring MVC的静态资源处理

1. 方式一:通过默认的servlet进行放行

<!--在web.xml中加上-->
<!--要配置多个,每种文件配置一个-->
<!--要写在DispatcherServlet的前面, 让defaultServlet先拦截请求,这样请求就不会进入Spring了-->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>

2. 方式二:web服务器默认的资源处理器

<!--在application.xml中加上-->
<!--web服务器默认的资源处理器-->
在springMVC-servlet.xml(spring的配置文件)中配置<mvc:default-servlet-handler />后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
一般Web应用服务器默认的Servlet名称是"default",因此DefaultServletHttpRequestHandler可以找到它。如果你所有的Web应用服务器的默认Servlet名称不是"default",则需要通过default-servlet-name属性显示指定:
<mvc:default-servlet-handler default-servlet-name="所使用的Web服务器默认使用的Servlet名称" />

<mvc:default-servlet-handler/>

3. 方式三:Spring MVC的资源处理器

<mvc:default-servlet-handler />将静态资源的处理经由Spring MVC框架交回Web应用服务器处理。而<mvc:resources />更进一步,由Spring MVC框架自己处理静态资源,并添加一些有用的附加值功能。

首先,<mvc:resources />允许静态资源放在任何地方,如WEB-INF目录下、类路径下等,你甚至可以将JavaScript等静态文件打到JAR包中。通过location属性指定静态资源的位置,由于location属性是Resources类型,因此可以使用诸如"classpath:"等的资源前缀指定资源位置。传统Web容器的静态资源只能放在Web容器的根路径下,<mvc:resources />完全打破了这个限制。

其次,<mvc:resources />依据当前著名的Page Speed、YSlow等浏览器优化原则对静态资源提供优化。你可以通过cacheSeconds属性指定静态资源在浏览器端的缓存时间,一般可将该时间设置为一年,以充分利用浏览器端的缓存。在输出静态资源时,会根据配置设置好响应报文头的Expires 和 Cache-Control值。

在接收到静态资源的获取请求时,会检查请求头的Last-Modified值,如果静态资源没有发生变化,则直接返回303相应状态码,提示客户端使用浏览器缓存的数据,而非将静态资源的内容输出到客户端,以充分节省带宽,提高程序性能。

在springMVC-servlet中添加如下配置:

<mvc:resources

location="/,classpath:/META-INF/publicResources/" mapping="/resources/**"/>

以上配置将Web根路径"/"及类路径下 /META-INF/publicResources/ 的目录映射为/resources路径。假设Web根路径下拥有images、js这两个资源目录,在images下面有bg.gif图片,在js下面有test.js文件,则可以通过 /resources/images/bg.gif 和 /resources/js/test.js 访问这二个静态资源。

假设WebRoot还拥有images/bg1.gif 及 js/test1.js,则也可以在网页中通过 /resources/images/bg1.gif 及 /resources/js/test1.js 进行引用。

<!--在application.xml中加上-->
<!--mapping:访问路径或映射路径-->
<!--location:真实路径,要以/结尾-->
<mvc:resources mapping="/abc/**" location="/WEB-INF/jpg/"/>

九、解决中文乱码

<!--在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>

十、Rest风格

1. URL的一部分作为形参

<!--如CSDN上的某一篇文章-->
https://blog.csdn.net/weixin_39786569/article/details/91797233
<!--网址最后的"91797233"是文章的ID-->
//如某段Rest风格的代码
@Controller
public class MyController {
    
    //使用@PathVariable注解完成Restful风格
    @RequestMapping("queryUser/id/{myid}/{name}")
    public String queryUserById(@PathVariable("myid") int id,@PathVariable("name") String name,Model model){
        userService.queryUserById(id);
        model.addAttribute("id",id);
        return "/show.jsp";
    }
    
}

2. @RequestParam(请求参数的限定)

@Controller
public class MyController {
    
    @RequestMapping("queryUsernameAndPassword")
    public String queryUsernameAndPassword(@RequestParam("username") String username,String password,Model model){
        userService.queryUserById(id);
        model.addAttribute("id",id);
        return "/show.jsp";
    }
    
}

3. @RequestHeader

@Controller
public class MyController {
    
    @RequestMapping("queryUsernameAndPassword")
    public String queryUsernameAndPassword(@RequestParam("username") String username,String password,@RequestHeader("Accept-Language")String acceptLanguage,Model model){
        userService.queryUserById(id);
        model.addAttribute("id",id);
        return "/show.jsp";
    }
    
}

十一、Spring MVC的异常处理(案例)

1. 思路

  • 系统中异常包括两类:

    • 编译时异常(通过捕获异常从而获取异常信息)
    • 运行时异常(通过规范代码开发、测试通过手段减少运行时异常的发生)
  • 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由Spring MVC的前端控制器交由异常处理器进行异常处理。

2.

十二、Spring MVC的拦截器

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章