# SpringMVCDemo202502 **Repository Path**: nieps/spring-mvcdemo202502 ## Basic Information - **Project Name**: SpringMVCDemo202502 - **Description**: spring mvc案例 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-02-05 - **Last Updated**: 2025-02-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: Spring-MVC ## README # SpringMVC笔记 ## web层框架: C控制层 演变过程: * servlet * structs1 核心类ActionServlet 依赖于servlet容器 (服务器) > 动态脚本语言: php asp jsp > > jsp/servlet 需要服务器的支持 * structs2 借助于structs1 的社区 核心 webwork 不再依赖于servlet * spring mvc ## 目标 * 掌握spring mvc工作流程 (面试必问) * 了解视图 (jsp thymeleaf freemarker ) * 掌握注解 (开发中用的 ) * 类型转换(了解) * 异常处理(掌握基于注解 的 全局异常处理) * 拦截器(掌握) * 数据校验(掌握 ) * 文件上传(熟悉 会就行) > 文件存储服务器:minio fastdfs oss * 跨域处理CORS (掌握) ## Hello示例 ### 核心类DispatcherServlet 你所有的请求,全部经过DispatcherServlet 转发 ,前端控制器 servlet定义: * web.xml * 通过注解@WebServlet 实现步骤: 1. 配置前端控制器DispatcherServlet web.xml配置servlet ,要指定springmvc配置文件 2. 在类路径下新建springmvc的配置文件(spring配置文件) 管理springmvc控制类 (由spring容器管理类,路径映射) 3. 控制类的实现 要求实现Controller接口 重写方法 返回ModelAndView ### 关于配置(了解) #### 前端控制器 * 在web.xml中定义时,要指定参数contextConfigLocation ,说明springmvc配置文件的位置 ,如果不指定 ,默认是/WEB-INF/dispatcherServlet的名称-servlet.xml * 路径映射 > 1. (了解)指定结尾(自定义) *.do 沿用structs1 风格 *.action 沿用structs2风格 *.niu > 2. (常用 ) / 拦截以/开头的请求 (包含静态资源) 不包含 jsp > > 注意:不能配置成: /* 这样会拦截所有请求(包含jsp,会根据访问的jsp查询handler 找不到报错) #### 默认配置文件 在核心类DispatcherServlet同目录下,有DispatcherServlet.properties文件,提供默认的配置,如默认的处理器映射器、处理器适配器、视图解析器 ## 注解配置 解决两个问题: * 核心类DispatcherServlet的映射 * spring mvc配置文件 ## 注解实现(重点) #### 基于表单实现 * @Controller 注解 > 标识控制类,方法返回逻辑视图 ##### 参数获取 * 在方法上定义与参数名相同的形参,既可接收到参数(适合参数少的情况) * 能过注解@RequestParam 显式的接收 > 什么情况下用该注解? > > 1. 如果提交的参数名与方法形参不一致,使用该注解的name或 value属性,指明具体的参数名 > 2. 使用该注解,默认对应的参数是必须的(用户提交请求必须传递参数,否则会报错) ,可以通过修改注解属性required = false 改为非必须的 > 3. 如果需要提供参数默认值时,使用该注解,通过属性defaultValue指定默认值 * 使用JavaBean接收,要求类的属性名与参数名 一致且提供get/set方法 (适合参数多的情况) * 路径参数 /user/1 用于将请求URL中的模板变量映射到方法的参数上,即取出uri模板中的变量作为参数。 > 实现: > > 1. 通过路径映射 指定模板URL 如 /user/{id} 、/user/{username}/{password} 参数通过 {} 加参数名做为占位符 > 2. 通过注解@PathVariable 获取模板URL中对应的参数 #### 基于JSON格式参数 * 使用注解@RequestBody 将json格式 的参数转换为javabean ,要求类中属性名与json中的key名保持一致 ,且提供get/set方法 * 使用@ReponseBody注解 将内容做为响应输出 ,不再跳转视图 @Controller与@RestController注解的区别? * @Controller 用于控制类,它里面的方法返回的是逻辑视图,它结合@ResponseBody注解可以返回文本字符串(json/xml) * @RestController它是@Controller 与@ResponseBody的复合注解,它里面的方法直接返回文本字符串(xml/json) > 在springmvc中要想实现json格式,满足两点: > > 1. 引入jackson依赖 jackson-databind > 2. 启用mvc注解支持@EnableWebMvc//启用spring mvc注解 #### 状态码 * 200 代表请求正常 * 4xx 代表客户端错误 > 1. 404 请求的地址不存在 > 2. 405 请求的方法不允许,如服务器设置的是post请求,客户端用get请求 不一致 > 3. 400 通常是参数出现问题 如格式 缺少参数。。。。 > 4. 415 - 不支持的媒体类型 通常是参数格式与Content-Type不一致 * 5xx 代表服务器错误 #### Restful 风格 ## Spring MVC类型转换(了解) 实现方式: * 实现Converter 接口 源数据类型是任意数据类型 * 实现Formatter 接口 ,源数据类型是固定的字符串 注册转换器,实现WebMvcConfigurer并重写如下方法: ~~~java @Override public void addFormatters(FormatterRegistry registry) { //注册类型转换器 //registry.addConverter(new StringToPointConvert()); registry.addFormatter(new StringToPointFormatter()); } ~~~ ## 异常处理 目标:学会全局异常处理 ### 了解基于视图的异常处理 分两种实现方式: * 局部异常处理 > 使用 @ ExceptionHandler 注解,在报异常的控制类中定义 ,只处理当前控制类中同类型的异常 * 全局异常处理 > 1. 使用单独的控制类实现异常处理,控制类使用@ControllerAdvice //异常增强 专注于全局异常处理 > 2. 使用 @ ExceptionHandler 注解,捕获特定的异常 > > ~~~java > @ControllerAdvice //异常增强 专注于全局异常处理 返回的是视图 > public class GlobalExceptionController { > > @ExceptionHandler({NullPointerException.class}) > public String error(NullPointerException e){ > System.out.println(e.toString()); > return "error.jsp"; > } > } > ~~~ > > > > ### 基于JSON格式的异常处理 分两种实现方式: * 局部异常处理 使用 @ ExceptionHandler 注解,方法返回的数据是文本数据(json/xml) * 全局异常处理 > 注解: @RestControllerAdvice+@ExceptionHandler 返回文本数据异常 > > ~~~java > @RestControllerAdvice//统一异常 文本数据 > public class GlobalExceptionController { > > @ExceptionHandler(NullPointerException.class) > public ResultBean error() { > return new ResultBean(0, "服务器异常", null); > } > > > @ExceptionHandler(Exception.class) > public ResultBean error2() { > return new ResultBean(0, "服务器出小差了", null); > } > } > > ~~~ > > @RestControllerAdvice=@ControllerAdvice+@ResponseBody ## 拦截器(掌握) 实现步骤: * 定义拦截器 实现HandlerInterceptor * 注册拦截器 基于mvc config 配置注册 ![image-20250207091923730](assets/image-20250207091923730.png) ## 认证机制 * 基础认证 每次请求传递用户名和密码 * 基于cookie认证 * 基于token认证 * oauth OAuth认证 token :令牌 是一个加密的字符串 包含用户的身份和权限信息 ## 同源策略 协议、域名、端口号三者一致为同源,不同源就是跨域。 http://localhost:8080/query http://localhost:8081/... ## CSRF 攻击 CSRF(Cross-Site Request Forgery)和XSRF实际上是同一种网络攻击方式的两种缩写,即跨站请求伪造攻击。以下是对这种攻击方式的详细解释: ### 一、定义 CSRF攻击是指攻击者冒充用户在用户不知情的情况下,以用户的名义向第三方网站发送恶意请求。由于这个请求是来自于受害者的浏览器,且通常已经通过了认证,所以第三方网站会误认为这是受害者的合法请求并予以执行。 ## 验证框架 正则核心: * \d 代表数字 * \D 代表非数字 * \w 字符 (字母 数字 下滑线等) * \W 非字符 * \s 代表空白 * \S 代表非空白 * [12345] 代表5个数字 中任何一个 * [0-9] 代表数字 * [a-z] 代表小写字母 * [A-Z] 代表大写字母 * \. 代表任意字符 * [\u4e00-\u9fa5] 汉字 边界符: * ^ 代表以什么开始 如 ^1 代表1开头 * $ 代表以什么结尾 * g 尽可能多的匹配 量词: * \* 代表任意数量 如 \d* 任意个数字 * \+ 代表一次或多次 \w+ 最少一个字符 * ? 代表出现0次或1次 \w? 最多一个字符 * {m} 代表出现m次 \d{3} 代表3个数字 * {m,} 代表最少出现m次 * {m,n} 最少出现m次 最多出现n次 ![验证](assets/%E9%AA%8C%E8%AF%81.png) ## 文件上传 要实现满足两个条件 : * 配置 多部件 > 两种实现方式 : > > 1. 在web.xml 在定义DispatcherServlet时 增加子元素 > > 2. 在初化类中,在servlet中添加 > > ~~~java > registration.setMultipartConfig(new MultipartConfigElement("/tmp")); > ~~~ * 配置解析 采用何种方式 实现上传 > 1. xml > > ~~~xml > > > ~~~ > > 2. 在配置类中 通过@Bean注解 向容器注入StandardServletMultipartResolver > > 注意: 要求容器中Bean的名称必须 是multipartResolver 一般情况下,上传文件会对文件名重写 > 设计表时: 上传的路径(重写后 /att/.../1.jpg) 文件名 照片.jpg 将所有的资源存储到统一的文件夹中,方便我们管理 /attachement / 202501/11122.jpg ## 静态资源 ~~~java @Configuration @ComponentScan(basePackages = {"com.by"}) @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer { @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { //这种方式 会拦截静态资源 但允许将没有映射的资源跳到转默认的default servlet处理 configurer.enable(); } } ~~~ ## SSM整合 ## 项目参考 [翼凯ERP](https://modao.cc/app/OUgx0pzNrpnejo4BRWww1N#screen=sldzkm7qirr5tob) [WMS仓储系统](http://175.178.48.140/project/wms0813/#id=f8isnb&p=wms%E4%BB%93%E5%82%A8%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F&g=1) [原型参考](https://www.axureshop.com/a/b/axure-prototypes) [泛普ERP](https://erpdemo.fanpusoft.com/Login.aspx?ReturnUrl=%2f) ## CORS跨域 两种解决方式: * 前端 通过代理 * 后端 解决 响应头参数: * **Access-Control-Allow-Origin** (必须) 允许来自哪些域名的请求访问 \* 代表来自所有的域名请求 允许访问 * **Access-Control-Allow-Credentials** (可选)是否允许浏览器携带cookie * **Access-Control-Expose-Headers** (可选) 允许请求获取到的响应头 * Access-Control-Allow-Methods(必须的) 允许哪些类型的方法可以访问 (get,post....) * **Access-Control-Max-Age** (可选) 预检缓存时间 单位 # 参考 ## 注解 ![Spring MVC注解](assets/Spring%20MVC%E6%B3%A8%E8%A7%A3.png)