# SpringFramework框架 ## 一、面向切面编程(AOP) #### 1、什么是AOP Aspect-Oriented Programming(面向切面编程)是Spring框架的核心特性之一,用于**分离横切关注点**(如日志、事务、安全等与业务逻辑无关的功能)。其核心思想是将这些关注点从业务代码中剥离,集中到**切面(Aspect)** 中管理,从而提升代码的模块化和可维护性。AOP是通过代理的方式实现。 #### 2、导入依赖 ```xml org.aspectj aspectjweaver 1.9.24 ``` #### 3、配置Spring ##### 添加命名空间 ```xml xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd" ``` 如下图  ##### 开启自动化代理 ```xml ``` ##### 完整配置 ```xml ``` ## 二、使用AOP #### 1、定义切面 创建`cn.doooog.springdome.aspect.LogAspect.java`切面类 ```java package cn.doooog.springdome.aspect; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Component @Aspect public class LogAspect { } ``` #### 2、定义切点 使用`@PointCut("execution()")`来定义 execution表达式 `execution(修饰符 [包.][类.][方法.](参数))` `.`为占位符,例如参数可以使用`..` `*`为任意长度字符 定义一个空方法函数,来作为定义切点的载体 ```java package cn.doooog.springdome.aspect; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component @Aspect public class LogAspect { @Pointcut("execution(* cn.doooog.springdome.service.*.*(..))") public void cutPoint(){} } ``` **注意**:`execution(* cn.doooog.springdome.service.*.*(..))`为切入service包下所有的类中所有的方法,任何参数都可以。 #### 3、前置通知 使用`@Before("cutPoint()")`修饰,会自动注入`JoinPoint`类型的切入点参数 ```java @Before("cutPoint()") public void beforeLog(JoinPoint joinPoint){ System.out.println("[前置通知: " + joinPoint.getSignature().toString() + "]"); } ``` **注意**:切入点参数通过`getSignature()`方法可以获取切入点方法的基本信息,包括类名`getDeclaringTypeName()`、方法名`getName()`、参数列表`getModifiers()` #### 4、后置通知 使用`@After("cutPoint()")`修饰,会自动注入`JoinPoint`类型的切入点参数,无论是否发生异常都会切入 ```java @After("cutPoint()") public void afterLog(JoinPoint joinPoint) { System.out.println("[后置通知: " + joinPoint.getSignature().toString() + "]"); } ``` #### 5、返回通知 使用`@AfterReturning(pointcut = "cutPoint()", returning = "自定义参数")`修饰,会自动注入`JoinPoint`类型的切入点参数,注意若需要接收返回值就需要添加一个`Object`类型的自定义参数,参数名与上方注解要保持一致,否则会注入失败。 ```java @AfterReturning(pointcut = "cutPoint()", returning = "result") public void returningLog(JoinPoint joinPoint, Object result) { System.out.println("[返回通知: " + joinPoint.getSignature().toString() + "] 返回值:" + result); } ``` **注意**:返回通知的优先级高于后置通知 #### 6、异常通知 使用`@AfterThrowing(pointcut = "cutPoint()", throwing = "自定义参数")`修饰,会自动注入`JoinPoint`类型的切入点参数,注意若需要接收返回值就需要添加一个`Exception`类型的自定义参数,参数名与上方注解要保持一致,否则会注入失败。 ```java @AfterThrowing(pointcut = "cutPoint()", throwing = "exception") public void throwingLog(JoinPoint joinPoint, Exception exception) { System.out.println("[异常通知: " + joinPoint.getSignature().toString() + "] 异常:" + exception); } ``` #### 7、环绕通知 环绕通知相当于将上述通知类型全部组合起来。 使用`@Around("cutPoint()")`修饰,会自动注入`ProceedingJoinPoint`类型的切入点参数(暂定参数名为`pjp`),必须将其加到方法参数列表中,否则无法使用环绕通知,使用`pjp.proceed()`来执行切入点的原方法,环绕通知可以返回方法执行后的返回对象。 ```java @Around("cutPoint()") public Object aroundLog(ProceedingJoinPoint pjp) { Object result = null; try { System.out.println("[环绕前置通知: " + pjp.getSignature().toString() + "]"); result = pjp.proceed(); System.out.println("[环绕返回通知: " + pjp.getSignature().toString() + "] 返回值:" + result); } catch (Throwable e) { System.out.println("[环绕异常通知: " + pjp.getSignature().toString() + "] 异常:" + e); } finally { System.out.println("[环绕后置通知: " + pjp.getSignature().toString() + "]"); } return result; } ``` **注意**:环绕通知的执行优先级高于其他通知类型。 # SpringMVC ## 一、框架流程 #### 1、静态概念 `Controller`:控制层 `View`:视图层 `Model`:模型层 `DispatcherServlet`:中央控制器/前端控制器,所有的请求和处理都需要中央控制器进行分发 `HandlerAdapter`:处理器适配器式Controller具体表现 `HandlerInterceptor`:拦截器,为Controller层做拦截 `HandlerMapping`:处理器映射器,用来为请求做路径映射 `ModelAndView`:Model的具体表现 `ViewResolver`:视图解析器,帮助DispatcherServlet找到View视图 #### 2、动态处理流程分析  1. **客户端发送HTTP请求**: - 浏览器或客户端应用发起HTTP请求(GET/POST等) - 请求URL指向Spring MVC应用部署的服务器 2. **DispatcherServlet接收请求**: - Spring MVC的前端控制器,所有请求的入口点 - 继承自HttpServlet,配置在web.xml中映射所有请求 3. **HandlerMapping查找处理器**: - 根据请求URL路径查找对应的控制器方法 - 返回HandlerExecutionChain(包含Controller方法+拦截器) 4. **获取HandlerAdapter**: - 根据控制器类型选择合适的适配器 - 支持多种控制器类型(@Controller,HttpRequestHandler等) 5. **执行拦截器前置处理**: - 执行拦截器链的preHandle方法 - 用于身份验证、日志记录等前置处理 6. **preHandle方法处理**: - 若返回false则中断请求处理 - 通常用于权限验证、请求过滤 7. **调用控制器方法**: - 实际执行业务逻辑的入口点 - 解析请求参数、路径变量、请求头等 8. **业务逻辑处理**: - 调用服务层(Service)处理核心业务 - 事务管理通常在此层实现 9. **数据处理层访问**: - 访问数据库或其他持久化存储 - 通过Repository或DAO组件实现 10. **返回数据结果**: - 将查询/处理结果返回给服务层 11. **服务层返回业务数据**: - 处理后的业务数据返回控制器 12. **构建ModelAndView**: - 封装模型数据和视图信息 - 可能返回视图名称或直接返回数据(REST) 13. **返回处理结果**: - 将结果返回到HandlerAdapter 14. **执行拦截器后置处理**: - 调用拦截器的postHandle方法 - 可在视图渲染前修改模型数据 15. **postHandle方法处理**: - 访问ModelAndView进行最后修改 - 添加公共模型数据或记录信息 16. **返回最终结果**: - HandlerAdapter将结果返回DispatcherServlet 17. **ViewResolver解析视图**: - 根据逻辑视图名解析为实际视图 - 解析为JSP、Thymeleaf或JSON视图等 18. **返回视图对象**: - 例如InternalResourceView、ThymeleafView等 - 包含具体的视图渲染实现 19. **View渲染视图**: - 使用模板引擎生成响应内容 - 支持多种视图技术(JSP, Thymeleaf, FreeMarker等) 20. **合并模型数据**: - 将控制器添加的模型数据合并到视图 - 填充模板中的变量占位符 21. **生成响应内容**: - 渲染完成的HTML/JSON响应内容 - 设置正确的Content-Type头 22. **执行最终处理**: - 调用拦截器的afterCompletion方法 - 无论成功失败都会执行 23. **afterCompletion方法**: - 请求完成后的清理工作 - 释放资源、记录请求完成时间等 24. **返回HTTP响应**: - 包含渲染后的内容和响应头 - 通过HTTP返回给客户端浏览器 ## 二、安装并配置Tomcat 详见:[SpringMVC框架介绍及环境配置](https://soki.me/archives/289.html)中的第二条 ## 三、配置SpringMVC #### 1、创建项目 选择Maven项目,选择WebAPP模板  #### 2、导入依赖 ```xml UTF-8 1.8 1.8 7.0.0-M9 org.springframework spring-context ${spring.version} org.springframework spring-webmvc ${spring.version} ``` 3、修改`web.xml` ```xml char encoding filter encodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 encodingFilter /* springMvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath*:SpringMVC.xml 1 springMvc / ``` #### 3、创建配置文件 创建`rescources/SpringMVC.xml` ```xml ``` #### 4、创建Controller实体类 创建`controller/ctrl01.java`,使用`@RequestMapping("/[url]")`进行网页URL映射,通过`@ResponseBody`来标记该内容为响应体直接返回数据 ```java package cn.doooog.springmvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class ctrl01 { // 为当前的方法公开一个接口,供外界访问 @RequestMapping("/hello") // 以响应体方式直接返回数据 @ResponseBody public String hello() { System.out.println("ctrl01.hello()"); return "hello springmvc"; } } ``` #### 5、运行服务器 等待浏览器自动打开后输入`/hello` 成功如图  ## 四、SpringMVC注解 #### 1、`@ResponseBody` 将返回的数据以`response.getWriter()`的形式输出给客户端 ##### 使用位置 * 类名上方:表示该处理器类中所有的方法都直接返回数据 * 方法名上:表示该方法直接返回数据 #### 2、`@RequestMapping` 与该注解作用相同的是`@GetMapping`、`@PostMapping` 用于建立请求URL与处理请求方法之间的对应关系,请求路径不能出现重复 ##### 基本语法 ```java @RequestMapping([属性]="属性值",[属性="属性值"]) ``` **注意**:当只有`value`时可以省略属性名直接写 ##### 属性 * `value`:设置URL映射路径 * `method`:设置请求方式,默认为`RequestMethod.GET` * `params`:设置请求参数 ##### 使用位置 * 类名上方:为当前类设置同一的URL目录 * 方法名上:为该方法设置URL映射路径 ##### 映射多级路径 ```java @RequestMapping(value = {"/url1","/url2"},...) ``` ##### 添加参数 参数类型分为: * 简单数据类型 * 常用数据类型 * 数组 * 对象 * Servlet原生的类 * HttpServletRequest * HttpServletResponse * HttpSession对象 **简单数据类型** ```java @RequestMapping(value = "/hello") @ResponseBody public String helloGet(@RequestParam(name = "age", required = false) int age,@RequestParam(name = "money", defaultValue = "0") double money,@RequestParam("name") String name) { System.out.println("ctrl01.hello()"); return "get - age:" + age + ",money:" + money + ",name:" + name; } ``` ##### 数组类型 ```java @RequestMapping(value = "/hello") @ResponseBody public String helloGet(@RequestParam(name = "age",required = false) int[] age) { System.out.println("ctrl01.hello()"); return "get - age:" + Arrays.toString(age); } ``` ##### 对象类型 创建`cn.doooog.springmvc/User.java`对象类 ```java package cn.doooog.springmvc.po; public class User { private String name; private int age; private String sex; public User() { } public User(String name, int age, String sex) { this.name = name; this.age = age; this.sex = sex; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", sex='" + sex + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } ``` **注意**:对象属性名要与参数名保持一致 ```java @RequestMapping(value = "/hello") @ResponseBody public String helloGet(User user) { System.out.println("ctrl01.hello()"); return "get - age:" + user; } ``` #### 3、`@RequestParam` 为进行访问时设置所需提交的参数 ##### 基本语法 ```java @RequestParam([属性]="属性值",[属性="属性值"]) ``` ##### 属性 * `name`:参数的别名 * `required`:是否必要,只有数据可赋值为`null`才会生效 * `defaultValue`:没有参数时的默认值 Loading... # SpringFramework框架 ## 一、面向切面编程(AOP) #### 1、什么是AOP Aspect-Oriented Programming(面向切面编程)是Spring框架的核心特性之一,用于**分离横切关注点**(如日志、事务、安全等与业务逻辑无关的功能)。其核心思想是将这些关注点从业务代码中剥离,集中到**切面(Aspect)** 中管理,从而提升代码的模块化和可维护性。AOP是通过代理的方式实现。 #### 2、导入依赖 ```xml <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.24</version> </dependency> ``` #### 3、配置Spring ##### 添加命名空间 ```xml xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd" ``` 如下图  ##### 开启自动化代理 ```xml <!--开启自动化代理--> <aop:aspectj-autoproxy/> ``` ##### 完整配置 ```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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--加入自动化扫描--> <context:component-scan base-package="cn.doooog.[项目名]"/> <!--自动化装配--> <context:annotation-config/> <!--开启自动化代理--> <aop:aspectj-autoproxy/> </beans> ``` ## 二、使用AOP #### 1、定义切面 创建`cn.doooog.springdome.aspect.LogAspect.java`切面类 ```java package cn.doooog.springdome.aspect; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Component @Aspect public class LogAspect { } ``` #### 2、定义切点 使用`@PointCut("execution()")`来定义 execution表达式 `execution(修饰符 [包.][类.][方法.](参数))` `.`为占位符,例如参数可以使用`..` `*`为任意长度字符 定义一个空方法函数,来作为定义切点的载体 ```java package cn.doooog.springdome.aspect; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component @Aspect public class LogAspect { @Pointcut("execution(* cn.doooog.springdome.service.*.*(..))") public void cutPoint(){} } ``` **注意**:`execution(* cn.doooog.springdome.service.*.*(..))`为切入service包下所有的类中所有的方法,任何参数都可以。 #### 3、前置通知 使用`@Before("cutPoint()")`修饰,会自动注入`JoinPoint`类型的切入点参数 ```java @Before("cutPoint()") public void beforeLog(JoinPoint joinPoint){ System.out.println("[前置通知: " + joinPoint.getSignature().toString() + "]"); } ``` **注意**:切入点参数通过`getSignature()`方法可以获取切入点方法的基本信息,包括类名`getDeclaringTypeName()`、方法名`getName()`、参数列表`getModifiers()` #### 4、后置通知 使用`@After("cutPoint()")`修饰,会自动注入`JoinPoint`类型的切入点参数,无论是否发生异常都会切入 ```java @After("cutPoint()") public void afterLog(JoinPoint joinPoint) { System.out.println("[后置通知: " + joinPoint.getSignature().toString() + "]"); } ``` #### 5、返回通知 使用`@AfterReturning(pointcut = "cutPoint()", returning = "自定义参数")`修饰,会自动注入`JoinPoint`类型的切入点参数,注意若需要接收返回值就需要添加一个`Object`类型的自定义参数,参数名与上方注解要保持一致,否则会注入失败。 ```java @AfterReturning(pointcut = "cutPoint()", returning = "result") public void returningLog(JoinPoint joinPoint, Object result) { System.out.println("[返回通知: " + joinPoint.getSignature().toString() + "] 返回值:" + result); } ``` **注意**:返回通知的优先级高于后置通知 #### 6、异常通知 使用`@AfterThrowing(pointcut = "cutPoint()", throwing = "自定义参数")`修饰,会自动注入`JoinPoint`类型的切入点参数,注意若需要接收返回值就需要添加一个`Exception`类型的自定义参数,参数名与上方注解要保持一致,否则会注入失败。 ```java @AfterThrowing(pointcut = "cutPoint()", throwing = "exception") public void throwingLog(JoinPoint joinPoint, Exception exception) { System.out.println("[异常通知: " + joinPoint.getSignature().toString() + "] 异常:" + exception); } ``` #### 7、环绕通知 环绕通知相当于将上述通知类型全部组合起来。 使用`@Around("cutPoint()")`修饰,会自动注入`ProceedingJoinPoint`类型的切入点参数(暂定参数名为`pjp`),必须将其加到方法参数列表中,否则无法使用环绕通知,使用`pjp.proceed()`来执行切入点的原方法,环绕通知可以返回方法执行后的返回对象。 ```java @Around("cutPoint()") public Object aroundLog(ProceedingJoinPoint pjp) { Object result = null; try { System.out.println("[环绕前置通知: " + pjp.getSignature().toString() + "]"); result = pjp.proceed(); System.out.println("[环绕返回通知: " + pjp.getSignature().toString() + "] 返回值:" + result); } catch (Throwable e) { System.out.println("[环绕异常通知: " + pjp.getSignature().toString() + "] 异常:" + e); } finally { System.out.println("[环绕后置通知: " + pjp.getSignature().toString() + "]"); } return result; } ``` **注意**:环绕通知的执行优先级高于其他通知类型。 # SpringMVC ## 一、框架流程 #### 1、静态概念 `Controller`:控制层 `View`:视图层 `Model`:模型层 `DispatcherServlet`:中央控制器/前端控制器,所有的请求和处理都需要中央控制器进行分发 <img src="https://pic.soki.me/file/piclist/image-20251030141916833.png" alt="image-20251030141916833" style="zoom: 33%;" style=""> `HandlerAdapter`:处理器适配器式Controller具体表现 <img src="https://pic.soki.me/file/piclist/image-20251030142306407.png" alt="image-20251030142306407" style="zoom:25%;" style=""> `HandlerInterceptor`:拦截器,为Controller层做拦截 `HandlerMapping`:处理器映射器,用来为请求做路径映射 <img src="https://pic.soki.me/file/piclist/image-20251030142038982.png" alt="image-20251030142038982" style="zoom:25%;" style=""> `ModelAndView`:Model的具体表现 `ViewResolver`:视图解析器,帮助DispatcherServlet找到View视图 #### 2、动态处理流程分析  1. **客户端发送HTTP请求**: - 浏览器或客户端应用发起HTTP请求(GET/POST等) - 请求URL指向Spring MVC应用部署的服务器 2. **DispatcherServlet接收请求**: - Spring MVC的前端控制器,所有请求的入口点 - 继承自HttpServlet,配置在web.xml中映射所有请求 3. **HandlerMapping查找处理器**: - 根据请求URL路径查找对应的控制器方法 - 返回HandlerExecutionChain(包含Controller方法+拦截器) 4. **获取HandlerAdapter**: - 根据控制器类型选择合适的适配器 - 支持多种控制器类型(@Controller,HttpRequestHandler等) 5. **执行拦截器前置处理**: - 执行拦截器链的preHandle方法 - 用于身份验证、日志记录等前置处理 6. **preHandle方法处理**: - 若返回false则中断请求处理 - 通常用于权限验证、请求过滤 7. **调用控制器方法**: - 实际执行业务逻辑的入口点 - 解析请求参数、路径变量、请求头等 8. **业务逻辑处理**: - 调用服务层(Service)处理核心业务 - 事务管理通常在此层实现 9. **数据处理层访问**: - 访问数据库或其他持久化存储 - 通过Repository或DAO组件实现 10. **返回数据结果**: - 将查询/处理结果返回给服务层 11. **服务层返回业务数据**: - 处理后的业务数据返回控制器 12. **构建ModelAndView**: - 封装模型数据和视图信息 - 可能返回视图名称或直接返回数据(REST) 13. **返回处理结果**: - 将结果返回到HandlerAdapter 14. **执行拦截器后置处理**: - 调用拦截器的postHandle方法 - 可在视图渲染前修改模型数据 15. **postHandle方法处理**: - 访问ModelAndView进行最后修改 - 添加公共模型数据或记录信息 16. **返回最终结果**: - HandlerAdapter将结果返回DispatcherServlet 17. **ViewResolver解析视图**: - 根据逻辑视图名解析为实际视图 - 解析为JSP、Thymeleaf或JSON视图等 18. **返回视图对象**: - 例如InternalResourceView、ThymeleafView等 - 包含具体的视图渲染实现 19. **View渲染视图**: - 使用模板引擎生成响应内容 - 支持多种视图技术(JSP, Thymeleaf, FreeMarker等) 20. **合并模型数据**: - 将控制器添加的模型数据合并到视图 - 填充模板中的变量占位符 21. **生成响应内容**: - 渲染完成的HTML/JSON响应内容 - 设置正确的Content-Type头 22. **执行最终处理**: - 调用拦截器的afterCompletion方法 - 无论成功失败都会执行 23. **afterCompletion方法**: - 请求完成后的清理工作 - 释放资源、记录请求完成时间等 24. **返回HTTP响应**: - 包含渲染后的内容和响应头 - 通过HTTP返回给客户端浏览器 ## 二、安装并配置Tomcat 详见:[SpringMVC框架介绍及环境配置](https://soki.me/archives/289.html)中的第二条 ## 三、配置SpringMVC #### 1、创建项目 选择Maven项目,选择WebAPP模板  #### 2、导入依赖 ```xml <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <spring.version>7.0.0-M9</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> </dependencies> ``` 3、修改`web.xml` ```xml <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <!-- 编码过滤 utf-8 --> <filter> <description>char encoding filter</description> <filter-name>encodingFilter</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>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- servlet请求分发器 --> <servlet> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--配置文件设置--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:SpringMVC.xml</param-value> </init-param> <!-- 表示启动容器时初始化该Servlet --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMvc</servlet-name> <!-- 这是拦截请求, /代表拦截所有请求,拦截所有*.do请求 --> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> ``` #### 3、创建配置文件 创建`rescources/SpringMVC.xml` ```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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="cn.doooog.springmvc"/> <mvc:annotation-driven/> </beans> ``` #### 4、创建Controller实体类 创建`controller/ctrl01.java`,使用`@RequestMapping("/[url]")`进行网页URL映射,通过`@ResponseBody`来标记该内容为响应体直接返回数据 ```java package cn.doooog.springmvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class ctrl01 { // 为当前的方法公开一个接口,供外界访问 @RequestMapping("/hello") // 以响应体方式直接返回数据 @ResponseBody public String hello() { System.out.println("ctrl01.hello()"); return "hello springmvc"; } } ``` #### 5、运行服务器 等待浏览器自动打开后输入`/hello` 成功如图  ## 四、SpringMVC注解 #### 1、`@ResponseBody` 将返回的数据以`response.getWriter()`的形式输出给客户端 ##### 使用位置 * 类名上方:表示该处理器类中所有的方法都直接返回数据 * 方法名上:表示该方法直接返回数据 #### 2、`@RequestMapping` 与该注解作用相同的是`@GetMapping`、`@PostMapping` 用于建立请求URL与处理请求方法之间的对应关系,请求路径不能出现重复 ##### 基本语法 ```java @RequestMapping([属性]="属性值",[属性="属性值"]) ``` **注意**:当只有`value`时可以省略属性名直接写 ##### 属性 * `value`:设置URL映射路径 * `method`:设置请求方式,默认为`RequestMethod.GET` * `params`:设置请求参数 ##### 使用位置 * 类名上方:为当前类设置同一的URL目录 * 方法名上:为该方法设置URL映射路径 ##### 映射多级路径 ```java @RequestMapping(value = {"/url1","/url2"},...) ``` ##### 添加参数 参数类型分为: * 简单数据类型 * 常用数据类型 * 数组 * 对象 * Servlet原生的类 * HttpServletRequest * HttpServletResponse * HttpSession对象 **简单数据类型** ```java @RequestMapping(value = "/hello") @ResponseBody public String helloGet(@RequestParam(name = "age", required = false) int age,@RequestParam(name = "money", defaultValue = "0") double money,@RequestParam("name") String name) { System.out.println("ctrl01.hello()"); return "get - age:" + age + ",money:" + money + ",name:" + name; } ``` ##### 数组类型 ```java @RequestMapping(value = "/hello") @ResponseBody public String helloGet(@RequestParam(name = "age",required = false) int[] age) { System.out.println("ctrl01.hello()"); return "get - age:" + Arrays.toString(age); } ``` ##### 对象类型 创建`cn.doooog.springmvc/User.java`对象类 ```java package cn.doooog.springmvc.po; public class User { private String name; private int age; private String sex; public User() { } public User(String name, int age, String sex) { this.name = name; this.age = age; this.sex = sex; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", sex='" + sex + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } ``` **注意**:对象属性名要与参数名保持一致 ```java @RequestMapping(value = "/hello") @ResponseBody public String helloGet(User user) { System.out.println("ctrl01.hello()"); return "get - age:" + user; } ``` #### 3、`@RequestParam` 为进行访问时设置所需提交的参数 ##### 基本语法 ```java @RequestParam([属性]="属性值",[属性="属性值"]) ``` ##### 属性 * `name`:参数的别名 * `required`:是否必要,只有数据可赋值为`null`才会生效 * `defaultValue`:没有参数时的默认值 最后修改:2025 年 10 月 30 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 👆请简单粗暴地爱我。