SpringMVC

整合三层架构

SpringMVC和Struts2框架的区别

相同

都是基于MVC模型写的

底层都离不开ServletAPI

区别

SpringMVC的入口是Servlet,Structs2是Filter

SpringMVC基于方法设计,但Structs是基于类设计,每次执行都会创建一个类,所以SpringMVC的执行速度要稍快一些.

SpringMVC快速入门

RequestMapping注解

RequestMapping的作用

配置映射关系.当该注解出现在类上,则表示一个高级路径,在该类中的方法中出现RequestMapping注解,表示下一级路径,访问时必须遵守,否则404

RequestMapping的属性

  • Value
  • method:配置限制访问方式,以一个数组配置
    • RequestMethod.POST
    • RequestMethod.GET
  • params:限制请求参数条件,配置后,使用方法必须有指定的参数,如果配置等于,则参数必须相等.
    • params={“key=value”},请求参数必须有key且值等于value
    • params={“key!100”},请求参数必须有key,且不等于100
  • headers:发出请求中必须包含指定请求头

请求参数的绑定

在方法的参数列表中设置参数,然后调用参数

如果参数中有内涵参数,比如Account中有参数User,在表单提交时, 要把name属性改为User.name,这表示提交的时Account中的User的name

配置解决中文乱码的过滤器

没有配置该过滤器,在参数为中文时发送POST请求会乱码,此时,我们配置过滤器.

在web.xml中配置解决中文乱码的过滤器

1
2
3
4
5
6
7
8
9
10
11
12
<filter>
<filter-name></filter-name>
<filter-class>org.springframeword.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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

SpringMVC常用注解

RequestParam

该注解使用与参数上,为参数名多样化.

参数列表为name

RequestBody

不适用于get,在post请求方式下,拿到整个请求体,在参数上描述

PathVariable

用于绑定url中的占位符,适用于Restful风格编程,访问路径统一,在各个方法上绑定参数,

RequestHeader

用于获取请求消息头

ModelAttribute

出现在方法上,表示当前方法会在控制器方法执行之前执行.

出现在参数上,表示获取指定的数据给参数赋值.

SpringMVC返回值类型和相应数据类型

  1. String类型返回值

    指定逻辑视图名,返回值为一个String类型字符串,通过视图解析器,路径为/WEB-INF/pages/返回字符串.jsp

  2. void类型返回值

    若void类型返回值时,默认跳转到@RequestMapping的路径.jsp页面.程序报404.

    我们可以使用请求转发或重定向方式来进行跳转

    1
    2
    3
    4
    // 请求转发
    // request.getRequestDispatcher("/WEB-INF/pages/add.jsp").forward(request,response);
    // 重定向
    // response.sendRedirect(request.getContextPath()+"/add2.jsp");
  1. ModelAndView类型返回值

    1
    ModelAndView mv=new ModelAndView();
  1. 使用ModelAndView对象进行跳转(参数为页面名)

    1
    mv.setViewName("list");
  2. 使用ModelAndView对象进行数据传输

    1
    2
    3
    User user=new User();
    //使用键值对方式
    mv.addObject("users", users);

SpringMVC框架提供转发/重定向

  1. 请求转发
1
2
3
4
5
@RequestMapping("/delete")
public String delete() throws Exception {
System.out.println("delete方法执行了...");
// return "forward:/WEB-INF/pages/success.jsp"; //转发页面
return "forward:/user/findAll";//转发方法
  1. 重定向
1
2
3
4
5
@RequestMapping("/count")
public String count() throws Exception {
System.out.println("count方法执行了...");
return "redirect:/add.jsp";
// return "redirect:/user/findAll";

ResponseBody相应json数据

  • 配置DispatcherServlet会拦截所有资源,这会导致静态资源也被拦截无法使用.所以,我们要配置静态资源不被拦截,在SpringMVC.xml配置文件中进行以下配置

location表示webapp目录下的包的所有文件

mapping表示以/static开头的所有请求路径

1
2
3
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/>
  • 使用@ResponseBody来获取请求体数据,使用@RequestBody将json字符串转换成javaBena对象.
1
2
3
4
5
6
7
8
9
10
public @ResponseBody User testJson(@RequestBody User user)
{

System.out.println("ajax 执行了");
System.out.println(user);

user.setName("xixixiix");

return user;
}

使用@RequestBody,获取json字符串然后转为User类型,执行方法结束后,再使用@ResponseBody来将User对象转为json字符串传回.

json与JavaBean对象转换需要导入以下jar包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>

Spring实现文件上传

  1. 导入文件上传所需jar包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
    </dependency>
    <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
    </dependency>
  2. 编写上传文件表单

    1
    2
    3
    4
    <form action="user/mvcUpload"  method="post" enctype="multipart/form-data">
    选择文件: <input type="file" name="upload">
    <input type="submit" value="上传">
    </form>
  3. 编写文件上传Controller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    @RequestMapping("/mvcUpload")
    public String mvcUpload(HttpServletRequest request,MultipartFile upload)
    {
    System.out.println("MVC upload run");
    //获取文件上传路径
    String path = request.getSession().getServletContext().getRealPath("/uploads/");
    System.out.println(path);
    File file=new File(path);
    //判断文件夹是否存在,不存在则新建该文件夹
    if(!file.exists())
    {
    file.mkdir();//新建文件夹
    }

    //获取上传文件名
    String fileName = upload.getOriginalFilename();
    UUID uuid = UUID.randomUUID();
    //使每一次上传文件名唯一
    fileName=uuid+"_"+fileName;
    //上传文件
    try {
    upload.transferTo(new File(file,fileName));
    } catch (IOException e) {
    e.printStackTrace();
    }

    return "success";
    }
  4. 配置文件解析器

    在SpringMVC.xml中配置文件解析器,注意在解析器中,id值固定,必须为multipartResolver

    1
    2
    3
    4
    5
    6
    7
    <bean id="multipartResolver" <!-- id 的值是固定的-->
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置上传文件的最大尺寸为 5MB -->
    <property name="maxUploadSize">
    <value>5242880</value>
    </property>
    </bean>

SpringMVC实现跨服务器文件上传

  1. 导入跨服务文件上传所需jar包.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-core</artifactId>
    <version>1.18.1</version>
    </dependency>
    <dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
    <version>1.18.1</version>
    </dependency>
  2. 编写跨服务器文件上传form表单

    1
    2
    3
    4
    <form action="user/uploadOther"  method="post" enctype="multipart/form-data">
    选择文件: <input type="file" name="upload">
    <input type="submit" value="跨服务器上传">
    </form>
  3. 编写跨服务器文件上传controller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    @RequestMapping("/uploadOther")
    public String upload(MultipartFile upload)
    {
    System.out.println("others");

    //指定文件上传路径
    String path="http://localhost:9090/images_war/uploads/";
    //获取文件名
    String filename = upload.getOriginalFilename();
    UUID uuid = UUID.randomUUID();
    filename=uuid+filename;
    //创建客户端对象
    Client client = Client.create();
    //连接服务器
    WebResource webResource = client.resource(path + filename);
    try {
    //上传文件
    webResource.put(upload.getBytes());
    } catch (IOException e) {
    e.printStackTrace();
    }
    System.out.println(path);
    return "success";
    }

SpringMVC异常处理

image-20200214184206090

若出现异常,程序一层一层抛出,直到表现层,转入到一个错误提示页面.

  1. 编写自定义异常

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class sysException extends Exception{
    private String message;

    public String getMessage() {
    return message;
    }


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

    public sysException(String message) {
    this.message = message;
    }

    }
  2. 编写异常处理器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public class exceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,Object o,Exception e) {

    sysException ex=null;

    if(e instanceof sysException)
    {
    ex=(sysException) e;
    }
    else
    {
    ex=new sysException("错误!请联系管理员");
    }

    ModelAndView mv=new ModelAndView();
    //将错误信息抛出
    mv.addObject("message",ex.getMessage());
    //转到错误页面
    mv.setViewName("error");

    return mv;
    }
  3. 在SpringMVC.xml配置文件中配置自定义的异常处理器

    1
    <bean id="sysExceptionResolver" class="Code.exceptionResolver.exceptionResolver"></bean>

SpringMVC中的拦截器

  1. 拦截器用于预处理/后处理/jsp页面后处理
  2. 拦截器会按照定义的顺序来执行.
  3. 拦截器与过滤器的区别
    1. 任何框架都可以使用过滤器,但只能SpringMVC框架可以使用拦截器
    2. 过滤器能拦截所有资源.
    3. 拦截器只会对控制器中的方法进行拦截.

重写拦截器

实现HandlerInterceptor接口,复写其中方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class interceptor1 implements HandlerInterceptor {
//预先处理
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {
System.out.println("前前前前前1");
return true;
}
//后处理
@Override
public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {
System.out.println("后后后后后1");
}
//jsp后处理
@Override
public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {
System.out.println("jsp后后后后1");
}

在预先处理中,返回值类型为boolean类型,若返回true则放行,返回false则不放行.

在配置文件中配置拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*"/>
<!--<mvc:exclude-mapping path=""/>-->
<bean class="Code.interceptor.interceptor1"></bean>
</mvc:interceptor>
</mvc:interceptors>

<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*"/>
<bean class="Code.interceptor.interceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>

多个配置器配置时,需要多个标签.