柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • Java基础

  • JavaWeb

  • 拓展技术

  • 框架技术

  • 数据库

  • 数据结构

  • Spring

  • SpringMVC

  • SpringBoot

    • SpringBoot
    • SpringBoot3基础特性
    • SpringBoot3核心原理
    • 框架整合

      • SpringBoot SpringMVC 整合
        • SpringBoot 应用
        • 修改端口
        • 静态资源加载
        • 文件上传
        • 拦截器
        • 虚实映射重定向
        • 跨域
          • 简单请求
          • 非简单请求
          • SpringBoot解决方案
        • url图片
      • SpringBoot JDBC 整合
      • SpringBoot MyBatis 整合
      • SpringBoot tk-MyBatis 整合
      • SpringBoot Shiro 整合
      • SpringBoot Redis 整合
      • SpringBoot MyBatisPlus 整合
      • SpringBoot JSON 整合
      • SpringBoot Thymeleaf 整合
      • 整合WebSocket实现聊天功能
    • SpringBoot部署
  • SpringClound

  • Ruoyi-Vue-Plus

  • 后端
  • SpringBoot
  • 框架整合
Bozhu12
2023-06-10
目录

SpringBoot SpringMVC 整合

# SpringBoot 应用

SpringBoot 对 SpringMVC 的一些自动配置可以满足大部分需求,但也可以自定义配置类 并实现org.springframework.web.servlet.config.annotation.WebMvcConfigurer接口 进行手动部分配置

接口提供方法

返回 方法 说明
void ==addInterceptors(InterceptorRegistry registry)== 添加 拦截器,对请求进行拦截处理
void ==addResourceHandlers(ResourceHandlerRegistry registry)== 添加 或 修改静态资源
void ==addViewControllers(ViewControllerRegistry registry)== 无业务逻辑跳转(虚实映射重定向
void ==addCorsMappings(CorsRegistry registry)== 解决跨域问题

以下 SpringMVC配置问题 主要解决:

  • 修改端口
  • 静态资源加载
  • 拦截器配置
  • 虚实映射重定向
  • 跨域

# 修改端口

在SpringBoot的 全局属性(application.properties文件) 进行以下配置端口:

# 映射端口
server.port=80 

# 静态资源加载

Spring Boot 中 org.springframework.boot.autoconfigure.web.ResourceProperties类 ,已经定义了静态资源的默认路径 :(以下路径创建对应的目录即可直接访问

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
			"classpath:/META-INF/resources/", "classpath:/resources/",
			"classpath:/static/", "classpath:/public/" };
  • ==classpath:/META-INF/resources/==
  • ==classpath:/resources/==
  • ==classpath:/static/==
  • ==classpath:/public==

classpath:/ 指定的目录是指 缓存中加载的类路径classes

以上目录可以在项目中直接访问到指定根目录。如果自定义的资源路径则需要指定确定路径,例如:

项目默认的路径 : 测试访问 static/1.jpg ==localhost:8080/1.jpg==

自定义静态资源路径

  1. 重写方法映射 在SpringMVC的配置类中 重写 addResourceHandlers()方法 以下代码:

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 类似于 SpringMVC配置
        // <mvc:resources mapping="/test/**" location="/test/"/>
     	registry.addResourceHandler("/test/**").addResourceLocations("classpath:/test/");
    }
    

    如果指定实体本机文件则: ==registry.addResourceHandler("/pic/**").addResourceLocations("file:"+"D:/uploadFiles/");==

  2. 修改配置文件 修改 application.properties更改规则

    # 过滤规则
    spring.mvc.static-path-pattern=/static/**
    # 静态资源位置
    spring.web.resources.static-locations=classpath:/static/
    

    以上是默认配置 , 可手写覆盖 , 覆盖后原有的会失效

# 文件上传

表单默认应用 enctype="application/x-www-form-urlencoded" , 需要改成 enctype="multipart/form-data" 进行上传文件

修改默认大小限制

默认每个1M , 配置修改

# 单个文件最大
spring.servlet.multipart.max-file-size=10MB
# 单次请求最大
spring.servlet.multipart.max-request-size=10M

应用

@RestController
public class FileUploadController {
    @PostMapping("/upload")
    public String up(String nickname, MultipartFile photo , HttpServletRequest request) throws IOException {
        System.out.println("nickname = " + nickname);

        // 图片信息
        System.out.println("图片原始名称: "+photo.getOriginalFilename());
        System.out.println("图片类型: "+photo.getContentType());

        String path = request.getServletContext().getRealPath("/upload/");
        System.out.println("path = " + path);

        // 存储
        saveFile(photo,path);
        return "上传完毕";
    }

    // 存储
    private void saveFile(MultipartFile photo, String path) throws IOException {

        File dir = new File(path);
        // 目录空则创建
        if (!dir.exists()) {
            dir.mkdir();
        }
        File file = new File(path + photo.getOriginalFilename());
        photo.transferTo(file);
    }
}

# 拦截器

拦截器需要自行配置 。 SpringMVC拦截器类配置了解 (opens new window)

Spring Boot 定义了 HandlerInterceptor接口 , 该接口实现了自定义拦截器的功能 , 可以重写以下三个过程方法进行 :

  1. 请求前 ==preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)==

    参数:handler 被拦截的控制器对象(MyController) 返回:是否允许放行,false拦截

  2. 请求处理后 ==postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)==

    参数:handler 被拦截的控制器对象 ;modelAndView 控制器方法的返回值

  3. 请求最后 ==afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)== 参数:handler 被拦截的控制器对象 ;ex 控制器方法异常

大致步骤 :

  1. 创建 自定义拦截器 , 继承 HandlerInterceptor 并重写以上方法
  2. 配置 路径 (全选 , 部分 , 排除)
  3. 日志配置
  4. 测试

创建 自定义拦截器类

自定义拦截器MyInterceptor类 展开

模拟日志形式进行输出

public class MyInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);
    
    @Override
    public boolean preHandle(HttpServletRequest request , HttpServletResponse response , Object handler) {
        logger.debug("处理器执行前执行!");
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request , HttpServletResponse response , Object handler , ModelAndView modelAndView) throws Exception {
        logger.debug("处理器执行后执行!");
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request , HttpServletResponse response , Object handler , Exception ex) throws Exception {
        logger.debug("跳转后执行!");
    }
    
}

注意

如果需要在自定义拦截器中食用 自动注入对象 的话 , 需要写个有参构造方法进行传递 .

在配置类中 自动注入 , 在实例化时传参进去即可

配置类 路径配置

重写 addInterceptors方法 添加自定义拦截器 , 通过registry对象的addInterceptor()方法 来添加拦截器 , 拦截器的路径拦截有以下配置选项 : (分别写出应用的方法)

  • 所有请求路径拦截 : 无 , 默认所有请求拦截
  • 指定范围路径拦截 : addPathPatterns()
  • 排除指定路径拦截 : excludePathPatterns()
  • 指定拦截器的优先级 : order()
@Configuration
public class SpringMVCConfig implements WebMvcConfigurer {
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 通过registry来注册拦截器,通过addPathPatterns来添加拦截路径 (不加则拦截所有)
		registry.addInterceptor(new MyInterceptor())
            .addPathPatterns("/user/**");
	}
}

日志级别打印

在 全局属性(application.properties文件) 进行添加属性(此时在控制器是看不到日志的输出) 因 记录打印 级别 : debug ,日志打印 级别 :info

# 设置 com.*包 的日志级别为debug 
logging.level.com.*=debug

测试

运行项目 , 访问有效路径测试即可

# 虚实映射重定向

主要意图是把 访问的URI 转换至 自定义URI ,达到重定向效果 实现需要在 SpringMVC的配置类中 重写 addViewControllers()方法 以下代码:

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("login.html");
    registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}

首次访问重定向值登录页面,且设置最高优先级

# 跨域

CORS 是种 跨域资源共享的技术标准 , 为了更好的解决前端跨域请求 , CORS请求分为 简单请求 / 非简单请求 分别对跨域提供支持

跨域 : 当一个请求 url 的 协议/域名/端口 三者任意一个 与 当前页面url不同 称为 跨域

# 简单请求

请求方法 : GET / POST / HEAD 未自定义的请求头 : Accept / Accept-Language / Content--Language / Last-Event--lD / Content-Type Content-Type 的值只有以下三种 : text/plain , multipart/form-data , application/x-www-form-urlencode

前端发出请求时 : CORS的策略在请求头新增了个 Origin字段(url) , 用于告诉服务器来自哪里

后端收到请求后 :

可以根据 Origin字段 判断是否允许请求访问 , 如果允许 会在HTTP头信息添加 Access-Control-Allow-Origin字段(应用端口)

# 非简单请求

非简单请求时 浏览器会在真实请求发出前增加一次OPTION请求 称为预检请求

预检请求将真实请求的信息 , 包括请求方法/自定义头字段/源信息 添加到HTTP头信息字段中 , 询问服务器是否允许这样的操作

前端发出请求 :

OPTIONS /test HTTP/1.1
Origin: http://www.test.com
Access-Control-Request-Method: GET
# 请求的自定义头字段
Access-Control-Request-Headers: X-Custom-Header
Host: www.test.com

后端收到请求后 : 会对 Origin / Access-Control-Request-Method / Access-Control-Request-Headers 字段进行验证 , 后端请求允许通过后会返回

# 真实请求 请求允许 来源url/方法/头信息
Access-Control-Allow-Origin: http://www.test.com
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Headers: X-Custom-Header
# 允许 用户 发送/处理 cookie
Access-Control-Allow-Credentials: true
# 允许 请求有效期 毫秒
Access-Control-Max-Age: 1728000

# SpringBoot解决方案

解决跨域问题需要在 SpringMVC的配置类中 重写 addCorsMappings()方法 以下代码:

springboot 2.4.0版本前 :

@Override
public void addCorsMappings(CorsRegistry registry) {
   // 允许访问的路径
       registry.addMapping("/**")
               // 是否发送 cookie
               .allowCredentials(true)
               // 允许 跨域访问的源
               .allowedOrigins("*")
               // 允许 接收的请求类型
               .allowedMethods("POST","GET")
               // 允许 头部设置
               .allowedHeaders("*")
               // 允许 有效期
               .maxAge(1800);
}

springboot 2.4.0版本后 :
方法名更变为 : allowedOrigins => allowedOriginPatterns

@Override
public void addCorsMappings(CorsRegistry registry) {
    // 允许访问的路径
    registry.addMapping("/**")
            // 是否发送 cookie
            .allowCredentials(true)
            // 允许 跨域访问的源
            .allowedOriginPatterns("*")
            // 允许 接收的请求类型
            .allowedMethods("POST","GET")
            // 允许 头部设置
            .allowedHeaders("*")
            // 允许 有效期
            .maxAge(1800);
}

方案2 : 在启动器类加上注解 @CrossOrigin . 也可实现跨域功能 (PS注意版本问题)

# url图片

@Controller
@RequestMapping(value = "/image")
public class ImageController {
    @RequestMapping(value = "/get",produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public byte[] getImage() throws IOException {
        File file = new File("D:/test.jpg");
        FileInputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes, 0, inputStream.available());
        return bytes;
    }
}
#SpringMvc

← SpringBoot3核心原理 SpringBoot JDBC 整合→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式