SpringMVC_IDEA高级

本文介绍 SpringMVC 中拦截器的使用方法及其配置,并详细讲解了如何处理 AJAX 请求及文件上传与下载操作。文章还介绍了三种 JSON 返回方式:jackson、gson 和 fastjson 的配置与应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、拦截器

1.简介

使用拦截器Interceptor对请求进行拦截,类似于过滤器Filter

2.用法

步骤:

  1. 定义一个类,实现HandlerInterceptor
package interceptor;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/30 15:54
 * @Version 1.0
 */

public class HelloInterceptor implements HandlerInterceptor {
    //调用目标处理方法之前执行,可以作权限,日志等处理
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod)handler;//参数handler本质上就是HandlerMethod实例
            Object bean = handlerMethod.getBean();
            Method method = handlerMethod.getMethod();
            System.out.println("HelloInterceptor.preHandle,bean:" + bean.getClass() + ",method:" + method.getName()
                    + ",args:" + Arrays.toString(method.getParameterTypes()));
        }
        return true;//true表示继续调用后续的拦截器或目标处理方法,false表示不再调用
    }
    //调用目标处理方法之后处理,渲染视图之前,可以对数据模型或视图进行修改
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("HelloInterceptor,postHandle");
    }
    //渲染视图之后,,可以用来释放资源
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("HelloInterceptor.afterCompletion");
    }
}

package interceptor;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/30 16:41
 * @Version 1.0
 */

public class TimeInterceptor implements HandlerInterceptor {

    private long startTime,endTime;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        startTime = System.currentTimeMillis();
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        endTime = System.currentTimeMillis();
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            System.out.println("执行目标方法" + handlerMethod.getMethod().getName() + "花费时间:" + (endTime-startTime) + "ms");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

  1. 配置拦截器
<!--配置拦截器-->
    <mvc:interceptors>
        <!--默认拦截所有请求-->
        <bean class="interceptor.HelloInterceptor"/>
        <!--拦截指定请求-->
        <mvc:interceptor>
            <mvc:mapping path="/user/regist"/>
            <mvc:mapping path="login"/>
            <mvc:mapping path="/path/*"/>
            <mvc:exclude-mapping path="/path/test7"/>
            <bean class="interceptor.TimeInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

在这里插入图片描述

HelloInterceptor,postHandle
HelloInterceptor.afterCompletion
HelloInterceptor,postHandle
HelloInterceptor,postHandle
HelloInterceptor.afterCompletion
HelloInterceptor.afterCompletion

登录之后
HelloInterceptor.preHandle,bean:class controller.ParamController,method:test9,args:[class java.lang.String]
RequestBody = username=%E7%8B%AC%E5%AD%A4%E6%B1%82%E8%B4%A5&password=123
HelloInterceptor,postHandle
HelloInterceptor.afterCompletion

二、处理AJAX

  1. @ResponseBody
    为方法添加该注解后,将返回值写到响应体中
package controller;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/30 17:46
 * @Version 1.0
 */
@Controller
@RequestMapping("/ajax")
public class AjaxController {
    @RequestMapping("/test1")
    public void test1(HttpServletResponse response) throws IOException {
        response.getWriter().write("success");
    }

    @RequestMapping("/test2")
    @ResponseBody //将返回值写到响应体中,并不是跳转视图
    public String test2(){
        return "success2";
    }

    @RequestMapping("/getUser")
    @ResponseBody
    public User getUser(){
        User user = new User(1001, "唐闪", "123", 18);
        return user;
    }
}

  1. 返回JSON
    三种方式:
    jackson,SpringMVC默认支持
    gson,SpringMVC默认支持,google开发
    fastjson,SpringMVC默认不支持,alibaba开发
    2.1 使用jackson
    步骤:
  2. 添加jar包
<!--jackson-->
      <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
      <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-databind.version}</version>
      </dependency>
  1. 配置消息转换器(省略)
<mvc:annotation-driven conversion-service="conversionService">
        <!--配置消息转换器,jackson和gson可以省略,fastjson不可以-->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

2.2 使用gson
步骤:

  1. 添加jar包
 	<!--gson-->
      <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
     <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>${gson.version}</version>
      </dependency>
  1. 配置消息转换器(省略)
<mvc:annotation-driven conversion-service="conversionService">
        <!--配置消息转换器,jackson和gson可以省略,fastjson不可以-->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.GsonHttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

2.3 使用fastjson
步骤:

  1. 添加jar包
<!-- fastjson -->
      <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>${fastjson.version}</version>
      </dependency>
  1. 配置消息转换器
	<mvc:annotation-driven conversion-service="conversionService">
        <!--配置消息转换器,jackson和gson可以省略,fastjson不可以-->
        <mvc:message-converters>
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes" value="application/json"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

三、文件上传和下载

文件上传

1.1 简介
SpringMVC对文件上传提供了支持,基于commons­-fileupload
1.2 用法
步骤:

  1. 添加jar包
<!-- commons-fileupload -->
      <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
      <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>${commons-fileupload.version}</version>
      </dependency>
  1. 编写jsp页面
<%--
  Created by IntelliJ IDEA.
  User: Matthew
  Date: 2019/3/30
  Time: 17:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
    <script>
        $(function () {
            $('#btn').on('click',function () {
                $.post('${pageContext.request.contextPath}/ajax/getUsers', function (data) {
                    console.log(data);
                });
            });
        });
    </script>
</head>
<body>
<button id="btn">发送AJAX请求</button>
</body>
</html>

  1. 配置文件解析器
<!--配置文件解析器 id必须为multipartResolver-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSizePerFile" value="5000000"/>
    </bean>
  1. 通过CommonsMultipartFile来接收文件
package controller;

import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/30 20:18
 * @Version 1.0
 */
@Controller
@RequestMapping("/file")
public class FileController {
    //文件上传只能以post方式
    @PostMapping("/upload")//文件上传CommonsMultipartFile前必须加RequestParam注解
    public String upload(String username, @RequestParam CommonsMultipartFile file, HttpSession session) {
        System.out.println("用户名:" + username);
        System.out.println("表单名称:" + file.getName());
        System.out.println("文件名:" + file.getOriginalFilename());
        System.out.println("文件大小:" + file.getSize());
        //获取上传目录的物理路径
        String path = session.getServletContext().getRealPath("\\WEB-INF\\upload\\");
        System.out.println(path);

        try {
            file.transferTo(new File(path, StringUtils.renameFileName(file.getOriginalFilename())));

        } catch (IOException e) {
            e.printStackTrace();
        }

        return "success";
    }
    @PostMapping("/uploads")//文件上传CommonsMultipartFile前必须加RequestParam注解
    public String uploads(String username, @RequestParam CommonsMultipartFile[] files, HttpSession session) {

        //获取上传目录的物理路径
        String path = session.getServletContext().getRealPath("\\WEB-INF\\upload\\");
        for (CommonsMultipartFile file : files) {
            try {
                file.transferTo(new File(path, StringUtils.renameFileName(file.getOriginalFilename())));

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "success";
    }
}

文件下载

两种方式:
使用OutputStream
使用ResponseEntity

使用OutputStream

传递文件名的两种方式:
使用请求参数传递文件名
使用rest风格传递文件名
默认情况下如果url结尾有后缀,会被自动截取掉,解决方式:
1. 将文件名放到url中间
2. 配置不自动截取后缀(使用较少)

//    @RequestMapping("/download")
//    public void download(String filename, HttpSession session, HttpServletResponse response) {
        @RequestMapping("/{filename}/download")
        public void download(@PathVariable String filename, HttpSession session, HttpServletResponse response) throws IOException {
            String path = session.getServletContext().getRealPath("/WEB-INF/upload/");
            File file = new File(path, filename);

            try {
                response.setHeader("content-disposition", "attachment;filename=" + filename);
                StreamUtils.copy(new FileInputStream(file), response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

//    @RequestMapping("/download")
//    public void download(String filename, HttpSession session, HttpServletResponse response) {
        @RequestMapping("/{filename}/download")
        public void download(@PathVariable String filename, HttpSession session, HttpServletResponse response) throws IOException {
            String path = session.getServletContext().getRealPath("/WEB-INF/upload/");
            File file = new File(path, filename);

            try {
                response.setHeader("content-disposition", "attachment;filename=" + filename);
                StreamUtils.copy(new FileInputStream(file), response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

2.2 使用ResponseEntity

 @RequestMapping("/download2")
        public ResponseEntity<byte[]> download2(String filename, HttpSession session) throws IOException {
            String path = session.getServletContext().getRealPath("/WEB-INF/upload/");
            File file = new File(path, filename);

            byte[] bytes = FileUtils.readFileToByteArray(file);
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("content-disposition","attachment;filename=" + filename);

            return new ResponseEntity<byte[]>(bytes, httpHeaders, HttpStatus.OK);//包含:文件数据,响应头,状态码
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值