rp网站做多大/seo教程论坛
SpringMVC概述
- 定义
- SpringMVC是一种基于Java实现MVC设计模型的轻量级Web框架
- MVC设计模型:即将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。这种分离使开发人员可以更容易地管理和维护代码。
- 它属于SpringFrameWork的后续产品,已经融合在Spring Web Flow中
- 它拥有一套完善的注解机制,通过注解可以让一个简单的Java类成为处理请求的控制器,而无需实现任何接口。同时它还支持
RESTful
编程风格的请求
- SpringMVC是一种基于Java实现MVC设计模型的轻量级Web框架
- SpringMVC的三大组件:处理器映射器(HandlerMapping)、处理器适配器(HandlerAdapter)、视图解析器(ViewResolver)
- SpringMVC就是要求我们编写一个个Controller控制器来处理请求,然后将结果转换成JSON数据响应给客户端
SpringMVC快速入门
环境准备相同步骤
-
Step1: 导入Spring坐标
-
导入Spring基础坐标:spring-context
-
导入Spring提供的监听器
ContextLoaderListener
的相关坐标:spring-web -
导入Spring集成Web环境相关坐标:servlet、jsp
-
导入Spring注解相关坐标:Annotation
-
导入与AOP相关的坐标:aop、aspectj
-
AOP坐标会在导入spring-context坐标后系统自动导入,如图所示
-
-
导入事务相关坐标:spring-tx
-
导入数据库相关坐标:mysql、数据源坐标(druid、cp30)
-
导入Spring集成JUnit相关坐标:junit、spring-test
-
导入Spring集成MyBatis相关坐标:mybatis、spring-jdbc、mybatis-spring
-
SpringMVC的相关坐标:spring-webmvc (注意:必须为必须为5.2.x.RELEASE版本)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SpringMvcDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>MvcClaDemo</artifactId><packaging>war</packaging><name>MvcClaDemo Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--===================Spring基础坐标=======================--><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><!--===================Spring自带监听器ContextLoaderListener所需坐标=======================--><!--spring-web--><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.2.25.RELEASE</version></dependency><!--===================Spring集成Web环境相关坐标=======================--><!-- servlet--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><!--jsp--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope></dependency><!--===================Spring注解相关坐标=======================--><!--Annotation坐标--><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><!--=====================Spring集成AOP相关坐标=========================--><!--aspectj坐标--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.22.1</version></dependency><!--spring-tx坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>6.1.15</version></dependency><!--=====================数据库相关坐标=========================--><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--===================Spring集成junit相关坐标=======================--><!--junit坐标--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--spring-test坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>6.1.6</version><scope>test</scope></dependency><!--=====================MyBatis相关坐标=========================--><!--MyBatis坐标--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.16</version></dependency><!--mybatis-spring--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>3.0.3</version></dependency><!--spring-jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>6.1.10</version></dependency><!--===================SpringMVC基础坐标=======================--><!--spring-webmvc--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.25.RELEASE</version></dependency></dependencies><build><finalName>MvcClaDemo</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build> </project>
-
-
Step2: 右键源代码配置文件目录(即资源文件
resources
)→New
→File
,创建properties配置文件,博主文件名为jdbc.properties
,该配置文件代码如下-
注意: properties配置文件中配置的各个属性前必须添加个
id.
(即id.属性
,比如:属性url
就设置为id.url
,博主设置的为jdbc.url
),以供Spring配置文件可以使用属性占位符${}
语法引用这些属性#driverClassName代表数据库驱动,后跟驱动全类名(在MySQL驱动jar包下的META-INF下的services文件夹下的java.sql.Driver文件内) jdbc.driverClassName=com.mysql.cj.jdbc.Driver # 数据库连接URL jdbc.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai # 数据库用户名 jdbc.username=root # 数据库密码 jdbc.password=123456 # 初始化连接数量---即容器中初始的数据库连接数量 jdbc.initialSize=5 # 最大活跃连接数量---容器中初始为5个,但若5个用完了,此时可以在申请5个数据库连接数量 #也就是说容器中最多存放10个数据库连接 jdbc.maxActive=10 # 获取连接时的最大等待时间,单位:毫秒。---与数据库进行连接时若超过3s仍未连接成功,则会报错 jdbc.maxWait=3000 #最小空闲连接数量---minIdle=5 # 配置检测连接是否有效的SQL,可以是一个查询语句,如果不指定则默认为"SELECT 1"---validationQuery=SELECT 1 # 是否开启自动提交事务---defaultAutoCommit=true
-
-
Step3: 在web项目核心目录(即
webapp
)下创建视图页面success.jsp,代码如下<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html><head><title>Title</title></head><body><h1>...Success Running...</h1></body> </html>
SpringMVC XML代码实现
需求:客户端发起请求,服务端接受请求,执行逻辑并进行视图跳转
-
步骤
- 导入SpringMVC的相关坐标
- 配置SpringMVC的核心前端控制器
DispathcerServlet
- 它拦截所有传入的请求,并将它们分发到适当的控制器
Controller
进行处理。 - 它可通过配置
web.xml
文件或Spring Boot的自动配置以注册DispatcherServlet
。
- 它拦截所有传入的请求,并将它们分发到适当的控制器
- 编写
web/Controller
表现层 的Controller控制器- 创建Controller类和视图页面
- 使用注解
@Controller
将Controller控制器配置到Spring容器中,并利用注解@RequestMapping("/xxx")
来给控制器中的业务方法设置地址请求映射 - 配置SpringMVC的核心文件
spring-mvc.xml
- 在该文件中配置
web/Controller
表现层 注解的组件扫描
- 在该文件中配置
- 在web.xml文件中配置SpringMVC的全局初始化参数
- 注意:该全局初始化参数是在配置SpringMVC的核心前端控制器的
<Servlet>
标签体内配置的,因为SpringMVC的全局初始化参数主要是该核心前端控制器DispatcherServlet
使用的
- 注意:该全局初始化参数是在配置SpringMVC的核心前端控制器的
- 执行访问测试(即客户端发起请求测试)
-
注意:
- SpringMVC快速入门之前要先把Spring相关代码及配置工作完成,具体步骤可详见Spring完整知识点汇总中的Spring集成Web环境→Spring配置文件的形式
- 此时不在需要
web/Controller
表现层 包下的继承Servlet接口的类,因为SpringMVC的本质就是对Servlet的简化处理
-
Step1: 创建业务层service包、持久层dao包、表现层controller包,代码分别如下
-
在dao包下创建
UserDao
接口,代码如下package at.guigu.dao;public interface UserDao {public void save(); }
-
在service包下创建
UserService
类,代码如下package at.guigu.service;import at.guigu.dao.UserDao;public class UserService {private UserDao userDao;public void setUserDao(UserDao bookDao) {this.userDao = bookDao;}public void save() {System.out.println("BookService save...");userDao.save();} }
-
在controller包下创建UserController类,代码如下
package at.guigu.controller;public class Usercontroller {public String save() {System.out.println("Usercontroller save...");//跳转到指定的视图页面return "success.jsp";} }
-
-
Step2: 使用
@RequestMapping
注解配置Controller控制器对应类中业务方法的映射地址,Usercontroller
代码更改如下package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;//将Usercontroller放到Spring容器中 @Controller public class Usercontroller {//设置请求地址映射@RequestMapping("/quick")public String save() {System.out.println("Usercontroller save...");return "success.jsp";} }
-
Step3: 右键源代码配置文件目录(即资源文件
resources
)→New
→XML Configuration File
→Spring Config
,文件名为spring-mvc.xml
,然后配置Spring以及SpringMVC的核心文件applicationContext.xml
、spring-mvc.xml
,代码如下-
Step3-1: Spring的核心配置文件代码如下
- 使用
context
命名空间加载jdbc.properties
文件(前提:需引入context
命名空间和约束路径)context
命名空间:xmlns:context="http://www.springframework.org/schema/context"
context
约束路径:http://www.springframework.org/schema/context
、http://www.springframework.org/schema/context/spring-context.xsd
- 配置数据源对应的bean
- 配置MyBatis的SqlSessionFactory
- 配置数据源
- 配置MyBatis核心配置文件(注意:若有的配置必须通过MyBatis核心配置文件配置时,则需要该步)
- 配置别名
- 引入dao包下所有接口对应的SQL映射文件
- 此时Spring会进行持久层扫描,自动生成该层中对应接口的bean
<?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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--使用`context`命名空间加载 `properties` 文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--Druid对应的bean--><bean id="dataSourceDruid" class="com.alibaba.druid.pool.DruidDataSource"><!--使用属性占位符`${}`语法引用properties文件中的属性--><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--配置MyBatis的SqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--配置数据源--><property name="dataSource" ref="dataSourceDruid"/><!--加载MyBatis的核心配置文件<property name="configLocation" value="classpath:mybatis-config.xml"/>--><!--配置别名--><property name="typeAliasesPackage" value="at.guigu.pojo"/></bean><!--引入dao包下所有接口对应的SQL映射文件即MyBatis 持久层扫描,会自动生成该层中对应接口的bean--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="at.guigu.dao"/></bean><!--配置bookService bean--><bean id="bookService" class="at.guigu.service.UserService"><!--绑定依赖关系--><property name="userDao" ref="userDao"></property></bean></beans>
- 使用
-
Step3-2: SpringMVC的核心配置文件代码如下
-
配置注解的组件扫描 需要在SpringMVC的配置文件中引入context和mvc的命名空间、约束路径;然后使用context命名空间配置组件扫描即可。
- 命名空间:
xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
- 约束路径
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
- 配置组件扫描代码:
<context:component-scan base-package="at.guigu.controller"></context:component-scan>
base-package
:给定一个包,然后会自动扫描该包下的所有内容,以便可以识别使用注解配置的类、字段和方法
- 注意:
- 其它三层架构包的注解的组件扫描在Spring的配置文件中配置
- 引入mvc的命名空间和约束路径是为了配置mvc的注解驱动,其作用可详见 SpringMVC回写数据——返回对象或集合 部分的内容
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--mvc的注解驱动--><mvc:annotation-driven/><!--配置Controller层的注解的组件扫描--><context:component-scan base-package="at.guigu.controller"></context:component-scan><!--等同于<context:component-scan base-package="at.guigu">type指定要扫描的内容为注解,expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有@Controller注解的类<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan> --> </beans>
-
-
-
Step4: 在web项目核心目录(即
webapp
)下的web.xml中进行全局配置。web.xml完整代码如下- 配置Spring相关的配置
- Spring的全局初始化参数、配置Spring所提供的
ContextLoaderListener
监听器、web配置
- Spring的全局初始化参数、配置Spring所提供的
- 配置SpringMVC的核心前端控制器
DispathcerServlet
- 配置SpringMVC的全局初始化参数,该全局初始化参数用于定义SpringMVC的配置文件供监听器使用
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--配置Spring的全局初始化参数--><context-param><!--定义参数的名称,必须是唯一的--><param-name>contextConfigLocation</param-name><!--定义参数的值--><param-value>classpath:applicationContext.xml</param-value></context-param><!--监听器--><!--配置Spring所提供的`ContextLoaderListener` 监听器--><listener><!--监听器类的全限定名--><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--声明Servlet--><!--配置SpringMVC的前端控制器的Servlet--><servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--配置SpringMVC的全局初始化参数--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><!--将URL模式映射到特定的Servlet上(即DispatcherServlet)--><servlet-mapping><!--指定的Servlet的类名--><servlet-name>DispatcherServlet</servlet-name><!--给指定的Servlet设置url,相当于@WebServlet("/")--><!--代表将所有请求都交给前端控制器处理--><url-pattern>/</url-pattern></servlet-mapping></web-app>
- 配置Spring相关的配置
-
客户端发起请求测试:Tomcat运行该Web项目后输入地址映射的url后会自动跳转到
success.jsp
页面 -
完整包结构如下
SpringMVC注解代码实现
-
Step1: 创建业务层service包、持久层dao包、表现层controller包,代码分别如下
-
在dao包下创建
UserDao
接口,代码如下:package at.guigu.dao; import org.apache.ibatis.annotations.Mapper;@Mapper public interface UserDao {public void save(); }
@Mapper
注解作用: 用于标记单个Mapper接口,让MyBatis生成它的实现类并注入到Spring容器中。也就是说此时不需要创建持久层的实现类,有IOC容器自动创建,其唯一标识id为对应接口名首字母大写(即userDao
)该注解也可以使用
@MapperScan(at.guigu.dao)
来代替,不过该注解需写在Spring的核心配置文件中,表示: 用于扫描指定包中的所有接口,将它们自动注册为Spring的Bean并作为Mapper以上两个注解在做项目时可根据实际情况选择
由于它们需要让MyBatis生成它的实现类并注入到Spring容器中,所以必须要有MyBatis的核心配置类,否则不会生效
-
在service包下创建
UserService
类,代码如下:package at.guigu.service;import at.guigu.dao.UserDao; import org.springframework.stereotype.Service;@Service("userService") public class UserService {private UserDao userDao;public void setUserDao(UserDao bookDao) {this.userDao = bookDao;}public void save() {System.out.println("BookService save...");userDao.save();} }
-
在controller包下创建
UserController
类,代码如下:package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;// 将Usercontroller放到Spring容器中 @Controller public class Usercontroller {// 设置请求地址映射@RequestMapping("/quick")public String save() {System.out.println("Usercontroller save...");// 跳转到指定的视图页面return "success.jsp";} }
-
-
Step2: 创建一个与三层架构包同级的
config
包,并在该包下创建拆分配置文件对应的数据源拆分类DataSourceConfiguration
,代码如下(以Druid为例)- Step2-1: 创建数据源bean
package at.guigu.config;import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.PropertySource; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;// 分配置文件对应的类不用配置@Configuration以及@ComponentScan注解 // 加载properties配置文件<context:property-placeholder location="classpath:jdbc.properties"/> @PropertySource("classpath:jdbc.properties") public class DataSourceConfiguration {@Value("${jdbc.driverClassName}")private String driverClassName;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*** Druid对应的bean* Spring会将当前方法的返回值以指定的id存储到Spring的IOC容器中* @return* @throws Exception*/@Bean("dataSourceDruid")public DataSource getDruidDataSource() throws Exception{// 创建数据源对象DruidDataSource dataSource = new DruidDataSource();// 设置数据源基本连接数据dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;} }
-
Step3: 在config包下创建MyBatis的核心配置类
MyBatisConfiguration
,代码如下package at.guigu.config;import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean;import javax.sql.DataSource;public class MyBatisConfiguration {@Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();// 相当于设置别名<package name="at.guigu.pojo"/>sqlSessionFactoryBean.setTypeAliasesPackage("at.guigu.pojo");// 相当于配置数据库连接信息sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean;}// 映射扫描配置类,相当于引入dao包下所有接口对应的SQL映射文件<package name="at.guigu.dao"/>@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();mapperScannerConfigurer.setBasePackage("at.guigu.dao");return mapperScannerConfigurer;} }
-
Step4: 在config包下创建Spring主配置文件对应的主类
SpringConfiguration
,引入分配置文件对应的拆分类DataSourceConfiguration
以及MyBatisConfiguration
,代码如下:package at.guigu.config;import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import;// 该注解代表该类是Spring的核心配置类 @Configuration // 配置注解的组件扫描<context:component-scan base-package="at.guigu"></context:component-scan> @ComponentScan("at.guigu") @MapperScan("at.guigu.dao") // 引入拆分配置文件<import resource="applicationContext-xxx.xml"/> @Import({DataSourceConfiguration.class, MyBatisConfiguration.class}) public class SpringConfiguration { }
-
注意: 由于在配置注解的组件扫描时属性值为
at.gui
,所以此时Spring会扫描包括controller包下的注解,为避免该情况,则有两种解决方式-
将Spring加载的bean设定扫描范围为精准范围,比如:
@ComponentScan(basePackages = {"at.guigu.dao", "at.guigu.service"})
-
将Spring加载的bean设定扫描范围为
at.gui
后排除掉controller包内的bean,该注解改为如下形式@ComponentScan(value = "at.guigu", excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class))
-
-
改进后的Spring核心配置类代码如下
package at.guigu.config;import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Controller;// 该注解代表该类是Spring的核心配置类 @Configuration // 配置注解的组件扫描<context:component-scan base-package="at.guigu.dao, at.guigu.service"></context:component-scan> @ComponentScan(value = "at.guigu",excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class))@MapperScan("at.guigu.dao") // 引入拆分配置文件<import resource="applicationContext-xxx.xml"/> @Import({DataSourceConfiguration.class, MyBatisConfiguration.class}) public class SpringConfiguration { }
-
-
Step5: 在config包下创建SpringMVC核心配置类
SpringMvcConfiguration
,代码如下:package at.guigu.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;// 该注解代表该类是SpringMVC的核心配置类 @Configuration // 配置注解的组件扫描<context:component-scan base-package="at.guigu.controller"></context:component-scan> // 加载controller对应的bean @ComponentScan("at.guigu.controller") // 自动配置SpringMVC的各种配置 @EnableWebMvc public class SpringMvcConfiguration { }
-
Step6: 在web项目核心目录(即
webapp
)下的web.xml中进行全局配置。web.xml完整代码如下- 配置Spring相关的配置
- Spring的全局初始化参数、配置Spring所提供的
ContextLoaderListener
监听器、web配置
- Spring的全局初始化参数、配置Spring所提供的
- 配置SpringMVC的核心前端控制器
DispathcerServlet
- 配置SpringMVC的全局初始化参数,该全局初始化参数用于定义SpringMVC的配置类供监听器使用
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--配置Spring配置类的全局初始化参数--><context-param><param-name>contextClass</param-name><param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value></context-param><context-param><!--定义参数的名称,必须是唯一的--><param-name>contextConfigLocation</param-name><!--定义参数的值--><param-value>at.guigu.config.SpringConfiguration</param-value></context-param><!--监听器--><!--配置Spring所提供的`ContextLoaderListener` 监听器--><listener><!--监听器类的全限定名--><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--配置SpringMVC的前端控制器的Servlet--><servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 配置 Spring MVC 的核心配置类 --><init-param><param-name>contextClass</param-name><param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value></init-param><init-param><param-name>contextConfigLocation</param-name><!--写入SpringMVC核心配置类的全限定名--><param-value>at.guigu.config.SpringMvcConfiguration</param-value></init-param><load-on-startup>1</load-on-startup></servlet><!--将URL模式映射到特定的Servlet上(即DispatcherServlet)--><servlet-mapping><!--指定的Servlet的类名--><servlet-name>DispatcherServlet</servlet-name><!--给指定的Servlet设置url,相当于@WebServlet("/")--><url-pattern>/</url-pattern></servlet-mapping> </web-app>
- 配置Spring相关的配置
-
客户端发起请求测试:Tomcat运行该Web项目后输入地址映射的url后会自动跳转到
success.jsp
页面 -
完整包结构如下
替代web.xml文件方式一
AbstractDispatcherServletInitializer 类中的抽象方法 | 解释 |
---|---|
WebApplicationContext createServletApplicationContext() | 创建Servlet容器时来加载SpringMVC对应的bean并放入WebApplicationContext 对象范围中(作用范围为ServletContext范围,即整个web容器),即加载SpringMVC的配置 |
String[] getServletMappings() | 设置SpringMVC对应的请求映射路径,当为/ 时表示拦截所有请求,此时任意请求都将转入到SpringMVC中进行处理 |
AbstractDispatcherServletInitializer 父类AbstractContextLoaderInitializer 中的抽象方法 | 解释 |
WebApplicationContext createRootApplicationContext() | 用于加载非SpringMVC对应的bean,比如加载Spring配置。其使用方法与createServletApplicationContext() 相同 |
- 为实现完全注解形式,可创建一个继承
AbstractDispatcherServletInitializer
类的子类ServletContainerInitConfiguration
来替代web.xml文件,从而实现全注解形式的开发
快速入门
此处只进行web.xml配置文件对应的配置类的编写,其它步骤可详见SpringMVC注解代码实现
-
Step1: 在config包下创建web.xml配置文件对应的配置类,即继承
AbstractDispatcherServletInitializer
类的子类ServletContainerInitConfiguration
,并重写其中的三个方法原始代码如下:package at.guigu.config;import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;// 定义一个Servlet容器启动的配置类,来加载Spring的配置 public class ServletContainerInitConfiguration extends AbstractDispatcherServletInitializer {// 加载SpringMVC的配置@Overrideprotected WebApplicationContext createServletApplicationContext() {return null;}// 设置哪些请求归SpringMVC处理@Overrideprotected String[] getServletMappings() {return new String[0];}// 加载非SringMVC的配置,比如:加载Spring的配置@Overrideprotected WebApplicationContext createRootApplicationContext() {return null;} }
-
Step2: 在
createServletApplicationContext()
方法中加载SpringMVC配置,并在getServletMappings()
方法中设置SpringMVC对应的请求映射路径,代码如下:package at.guigu.config;import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;// 定义一个Servlet容器启动的配置类,来加载Spring的配置 public class ServletContainerInitConfiguration extends AbstractDispatcherServletInitializer {// 加载SpringMVC的配置@Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();context.register(ServletContainerInitConfiguration.class);return context;}// 设置哪些请求归SpringMVC处理@Overrideprotected String[] getServletMappings() {// 代表将所有请求都交给前端控制器处理return new String[]{"/"};}// 加载非SringMVC的配置,比如:加载Spring的配置@Overrideprotected WebApplicationContext createRootApplicationContext() {return null;} }
-
Step3: 在
createRootApplicationContext()
方法中加载Spring配置,代码如下:package at.guigu.config;import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;// 定义一个Servlet容器启动的配置类,来加载Spring的配置 public class ServletContainerInitConfiguration extends AbstractDispatcherServletInitializer {// 加载SpringMVC的配置@Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();context.register(SpringMvcConfiguration.class);return context;}// 设置哪些请求归SpringMVC处理@Overrideprotected String[] getServletMappings() {// 代表将所有请求都交给前端控制器处理return new String[]{"/"};}// 加载非SringMVC的配置,比如:加载Spring的配置@Overrideprotected WebApplicationContext createRootApplicationContext() {AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();context.register(SpringConfiguration.class);return context;} }
-
Step5: 删除web.xml文件
运行截图如下
完整包结构如下
替代web.xml文件方式二
AbstractAnnotationConfigDispatcherServletInitializer 类中的抽象方法 | 解释 |
---|---|
Class<?>[] getServletConfigClasses() | 加载SpringMVC的配置 |
Class<?>[] getRootConfigClasses() | 加载非SpringMVC对应的bean,比如加载Spring配置 |
AbstractAnnotationConfigDispatcherServletInitializer 父类AbstractDispatcherServletInitializer 中的抽象方法 | 解释 |
String[] getServletMappings() | 设置SpringMVC对应的请求映射路径,当为/ 时表示拦截所有请求,此时任意请求都将转入到SpringMVC中进行处理 |
快速入门
此处只进行web.xml配置文件对应的配置类的编写,其它步骤可详见SpringMVC注解代码实现
-
Step1: 在config包下创建web.xml配置文件对应的配置类,即继承
AbstractAnnotationConfigDispatcherServletInitializer
类的子类ServletContainerInitConfiguration
,并重写其中的三个方法,代码如下:package at.guigu.config;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;// 定义一个Servlet容器启动的配置类,来加载Spring的配置 public class ServletContainerInitConfiguration extends AbstractAnnotationConfigDispatcherServletInitializer {// 加载SpringMVC的配置@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[]{SpringMvcConfiguration.class};}// 设置哪些请求归SpringMVC处理@Overrideprotected String[] getServletMappings() {return new String[]{"/"};}// 加载非SringMVC的配置,比如:加载Spring的配置@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[]{SpringConfiguration.class};} }
-
Step2: 删除web.xml文件
运行截图如下
完整包结构如下
SpringMVC的执行流程
-
执行流程图解释
- 用户发送请求到前端控制器DispatcherServlet
- 前端控制器DispatcherServlet收到请求后调用处理器映射器HandlerMapping
- 处理器映射器HandlerMapping找到具体的处理器(可通过xml配置、注解进行查找)后会生成处理器对象以及处理器拦截器,然后将其返回给前端控制器DispatcherServlet
- 前端控制器DispatcherServlet收到后将会调用处理器适配器Handler Adapter
- 处理器适配器HandlerAdapter经过适配会调用具体的==处理器Controller(即控制器,也叫作后端控制器)==来处理
- 处理器Controller(即控制器,也叫作后端控制器)执行完成后会返回ModelAndView(即模型和视图)
- 处理器适配器HandlerAdapter会将处理器Controller(即控制器,也叫作后端控制器)返回的ModelAndView(即模型和视图)返回给前端控制器DispatcherServlet
- 前端控制器DispatcherServlet会将ModelAndView(即模型和视图)传给视图解析器View Resolver
- 视图解析器ViewResolver解析后会返回给前端控制器DispatcherServlet具体的视图View
- 前端控制器DispatcherServlet会根据模型Model来渲染视图View(即将模型数据填充到视图中)
- 最终由前端控制器DispatcherServlet将完整的响应页面响应给用户
即:首先,会通过核心前端控制器DispatcherServlet获取到所有客户端发送的Http请求,然后通过处理器映射器HandlerMappingjia那个请求分别发送给对应的控制器进行处理,处理完后会返回一个ModelAndView对象,包含模型数据和视图。然后前端控制器DispatcherServlet会通过视图解析器将视图解析为实际的视图对象,然后将模型数据填充到视图中进行渲染,并将结果返回给客户端。
SpringMVC解析
SpringMVC组件解析
-
DispatcherServlet(前端控制器)
-
SpringMVC的核心组件,充当前端控制器(Front Controller)。
它拦截所有传入的请求,并将它们分发到适当的控制器进行处理。
配置
web.xml
文件或Spring Boot的自动配置以注册DispatcherServlet
。
-
-
Controller(处理器、控制器、后端控制器)
- 用于处理用户请求,并返回相应的模型和视图。
- 通过注解(如
@Controller
和@RequestMapping
)定义 @RequestMapping
用于映射URL到控制器的方法。
@Controller public class MyController {@RequestMapping("/hello")public String sayHello(Model model) {model.addAttribute("message", "Hello, SpringMVC!");return "hello"; // 返回视图名称} }
-
Model(模型)
- 用于存储数据和业务逻辑。
- 控制器将数据添加到模型中,然后传递给视图进行展示
-
View(视图):
- 负责显示模型中的数据。
- 常见的视图技术包括JSP、Thymeleaf、Freemarker等。
- 视图解析器(View Resolver)用于解析视图名称并渲染最终的视图。
-
View Resolver(视图解析器):
- 负责将控制器返回的视图名称解析为实际的视图对象。
- 可以配置不同的视图解析器,如
InternalResourceViewResolver
(用于JSP)、ThymeleafViewResolver
(用于Thymeleaf)等。
// @Bean使用在方法上,将方法的返回值存储到容器中 @Bean public InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/WEB-INF/views/");resolver.setSuffix(".jsp");return resolver; }
-
Handler Mapping(处理器映射器):
- 负责将传入的请求映射到对应的控制器。
- Spring提供了多种处理器映射,如
BeanNameUrlHandlerMapping
、RequestMappingHandlerMapping
等。
-
Handler Adapter(处理器适配器):
- 负责调用控制器中的方法。
- 不同类型的控制器需要不同的处理器适配器,如
HttpRequestHandlerAdapter
、SimpleControllerHandlerAdapter
等
-
Exception Handling(异常处理):
- 通过
@ExceptionHandler
注解处理控制器中的异常。 - 还可以配置全局异常处理器,如
@ControllerAdvice
。
@ControllerAdvice public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ModelAndView handleException(Exception ex) {ModelAndView model = new ModelAndView("error");model.addObject("message", ex.getMessage());return model;} }
- 通过
- 通过以上组件的协同工作,SpringMVC可以高效地处理Web请求,并实现清晰的代码分离,使得Web应用程序更加模块化和易于维护。
SpringMVC注解解析
注解 | 解释 |
---|---|
@RequestMapping | 用于建立请求URL和处理请求方法之间的对应关系。使用在类上: 请求URL的第一级访问目录。此处不写的话就相当于应用的根目录;使用在方法上: 请求URL的第二级访问目录,与类上使用该注解标注的一级目录一起构成虚拟路径 |
@EnableWebMvc | 用于启用 Spring MVC 的一系列配置功能的核心注解。它通常与 Java 配置类结合使用,来自动配置 Spring MVC 的各种特性 。 |
@ResponseBody | 设置当前控制器方法相应内容为当前返回值,无需解析。可详见SpringMVC回写数据部分内容 |
@RequestParam(value, required, defaultValue) | 用于 获取请求参数 的注解 |
@RequestBody | 将 HTTP 请求的 请求体(body)中包含的数据传递给请求参数,比如:JSON数据、XML、表单数据等 |
@DateTimeFormat(pattern) | 设置日期时间的数据格式,patter 为要设置的日期时间格式的字符串。可详见获取日期类型的代码示例 |
@PathVatiable | 用于Rest风格,绑定路劲参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应。可详见Rest风格部分示例 |
@RestController | 设置当前控制器类为Restful风格,等同于@Controller +@ResponseBody |
@GetMapping(value) | 设置当前控制器方法Get请求访问路径以及Restful风格的动作,等同于@RequestMapping(value, method=RequestMethod.Get) |
@PostMapping(value) | 设置当前控制器方法Post请求访问路径以及Restful风格的动作,等同于@RequestMapping(value, method=RequestMethod.Post) |
@PutMapping(value) | 设置当前控制器方法Put请求访问路径以及Restful风格的动作,等同于@RequestMapping(value, method=RequestMethod.Put) |
@DeleteMapping(value) | 设置当前控制器方法Delete请求访问路径以及Restful风格的动作,等同于@RequestMapping(value, method=RequestMethod.Delete) |
@RequestMapping 属性 | 解释 |
---|---|
value | 用于指定请求的URL。与path属性的作用一样 |
method | 用于指定请求的方式,默认为get请求方式 |
params | 用于指定限制请求参数的条件。它支持简单的表达式,要求请求参数的key和value必须与配置的一模一样 |
@EnableWebMvc
可用来自动配置 Spring MVC 的各种特性 ,比如- 类型转换器
- 它可根据类型自动匹配对应的类型转换器,比如时间格式的转换,可详见获取日期类型的代码示例
- 异常处理
- 视图解析器
- 默认的视图解析器会查找
/WEB-INF/views/
下的 JSP 文件
- 默认的视图解析器会查找
- 静态资源处理
- 验证支持
- Spring表单标签支持
- 参数解析和绑定
- 跨域支持
- SpringMVC拦截器支持
- 资源绑定支持
- mvc的注解驱动
<mvc:annotation-driven/>
- 可代替配置处理器适配器
- 类型转换器
@RequestParam
与@RequestBody
的区别- 区别
@RequestParam
用于接收url地址传参,表单传参
@RequestBody
用于接收json数据 - 应用
后期开发中,发送json格式数据为主,@RequestBody
应用较广
如果发送非json格式数据,选用@RequestParam
接收请求参数
- 区别
@RequestMapping
-
@RequestMapping
-
在快速入门中该注解应用在方法上,并未应用在类上,所以URL为:
http://localhost:8080/quick
, -
若该注解既应用在类上也应用在方法上则URL为:
http://localhost:8080/xxx/quick
,代码如下所示- 当加在类上时,其参数值一般按照不同的功能模块进行分类书写,如下代码所示由于是User模块,所以设置为
@RequestMapping("user")
,URL此时即为http://localhost:8080/user/quick
package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;//将Usercontroller放到Spring容器中 @Controller @RequestMapping("/user") public class Usercontroller {//设置请求地址映射@RequestMapping("/quick")public String save() {System.out.println("Usercontroller save...");return "success.jsp";} }
- 当加在类上时,其参数值一般按照不同的功能模块进行分类书写,如下代码所示由于是User模块,所以设置为
-
-
@RequestMapping
与返回值的关系-
当
@RequestMapping
只应用在类或方法上- 返回值为
return "success.jsp"
:此时系统会自动在Web项目核心目录(即webapp)下找success.jsp
文件 - 返回值为
return "/success.jsp"
:系统会自动在Web项目核心目录(即webapp)下找success.jsp
文件 - 返回值为
return "/jsp/success.jsp"
:系统会自动在Web项目核心目录(即webapp)下的jsp目录下找success.jsp
文件
- 返回值为
-
当
@RequestMapping
同时应用在类和方法上-
返回值为
return "success.jsp"
:此时系统会自动在Web项目核心目录(即webapp)下的user目录下找success.jsp
文件- 若想让其直接在Web项目核心目录(即webapp)下找
success.jsp
文件则将返回值改为:return "/success.jsp"
- 若想让其直接在Web项目核心目录(即webapp)下找
-
返回值为
return "/success.jsp"
:系统会自动在Web项目核心目录(即webapp)下找success.jsp
文件 -
返回值为
return "/jsp/success.jsp"
:系统会自动在Web项目核心目录(即webapp)下的jsp目录下找success.jsp
文件
-
-
注意: 当配置了内部资源视图解析器后,此时
return "success"
返回的success.jsp
文件的地址与@RequestMapping
应用在哪里无关,只与内部资源视图解析器中配置的地址有关,以如下代码为例:此时只会去找webapp目录下的jsp目录下的success.jsp
文件// 配置视图解析器 @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/jsp/"); // 设置视图文件路径前缀 resolver.setSuffix(".jsp"); // 设置视图文件后缀 return resolver; }
-
-
value
:用于指定请求的URL- 当
@RequestMapping
注解有多个属性时,该属性名称不可省略,如:@RequestMapping(value="/xxx", method=RequestMethod.GET)
- 当
@RequestMapping
注解只有这一个属性时,该属性名称可省略,如:@RequestMapping("/xxx")
- 当
-
method
:用于指定请求的方式。常用于Rest风格-
该属性值利用枚举类
RequestMethod
来调用,如图所示
-
-
params
:用于指定限制请求参数的条件-
它支持简单的表达式,要求请求参数的key和value必须与配置的一模一样
-
params={"accountName"}
:此时客户端的请求参数中必须有accountName -
params={"money!100"}
:此时客户端的请求参数必须有money
,且该参数值不能为100 -
代码示例如下
package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;//将Usercontroller放到Spring容器中 @Controller @RequestMapping("/user") public class Usercontroller {//设置请求地址映射并限定请求参数的条件@RequestMapping(value = "/quick", params = {"username"})public String save() {System.out.println("Usercontroller save...");return "success.jsp";} }
Tomcat运行该Web项目后若不加限定的请求参数则会报错,如图一所示,加上后才会成功运行,如图二所示
-
SpringMVC 配置文件形式
SpringMVC 配置文件形式的组件扫描
-
在SpringMVC的核心文件
spring-mvc.xml
中配置组件扫描的步骤如下-
mvc命名空间引入
-
引入mvc命名空间:
xmlns:mvc="http://www.springframework.org/schema/mvc"
-
引入mvc的约束路径:
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/context/spring-mvc.xsd
-
-
context命名空间引入
-
引入context命名空间:
xmlns:context="http://www.springframework.org/schema/context"
-
引入context的约束路径:
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-
-
配置组件扫描代码:
<context:component-scan base-package="at.guigu.controller"></context:component-scan>
-
SpringMVC是基于Spring容器的,所以在进行SpringMVC操作时就要利用
@Controller
注解将Controller存储到Spring容器中,若要使用@Controller
注解标注的话就需要用组件扫描代码进行组件扫描 -
配置组件扫描的代码有两个书写方法
<!--配置Controller层的注解的组件扫描,方法一--> <context:component-scan base-package="at.guigu.controller"></context:component-scan>
<!--配置Controller层的注解的组件扫描,方法二--> <context:component-scan base-package="at.guigu"><!--type指定要扫描的内容为注解,expression指定要扫描的对应注解@Controller的全限定名--><!--只扫描at.guigu包下有@Controller注解的类--><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
-
-
-
注意
- Spring和SpringMVC注解的组件扫描:要各自扫描各自的模块,互不干扰。所以在配置注解的组件扫描时:
- 若是Spring的:就在Spring的核心配置文件中进行注解的组件扫描
- 若是SpringMVC的:就在SpringMVC的核心配置文件中进行注解的组件扫描
- Spring和SpringMVC注解的组件扫描:要各自扫描各自的模块,互不干扰。所以在配置注解的组件扫描时:
SpringMVC配置文件形式的核心配置文件spring-mvc.xml解析
-
注意
-
SpringMVC有默认组件配置,默认组件都是在
DispatherServlet.properties
配置文件中配置的,该配置文件在External Libraries
下,如图所示
-
-
配置Controller层的注解的组件扫描
-
方式一:
<context:component-scan base-package="at.guigu.controller"></context:component-scan>
-
方式二:
<context:component-scan base-package="at.guigu"><!--type指定要扫描的内容为注解,expression指定要扫描的对应注解的全限定名--><!--只扫描at.guigu包下有@Controller注解的类--><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
-
注意:配置Controller层的注解的组件扫描时需要引入命名空间,可详见SpringMVC组件扫描
-
-
额外知识点
Controller包下Usercontroller代码如下
package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;//将Usercontroller放到Spring容器中 @Controller @RequestMapping("/user") public class Usercontroller {//设置请求地址映射@RequestMapping("/quick")public String save() {System.out.println("Usercontroller save...");return "/success.jsp";} }
-
Tomcat运行该Web项目后,运行截图如下,从截图中可看出我们输入完URL回车后显示了success.jsp页面的代码,在此过程中URL并没有改变。说明
return "/success.jsp"
默认使用的是 请求转发 的技术(可详见Web&Http&Servlet&Request&Response
)- 所以
return "/success.jsp"
相当于return "forward:/success.jsp"
- 所以
-
若我们将
return "/success.jsp"
改为return "redirect:/success.jsp"
,则此时运行Web项目后截图如下- 从截图中可知此时就变成了使用 重定向 技术(可详见
Web&Http&Servlet&Request&Response
)
- 从截图中可知此时就变成了使用 重定向 技术(可详见
-
-
配置内部资源视图解析器
InternalResourceViewResolver
-
当返回值为
return "/jsp/success.jsp"
时:系统会自动在Web项目核心目录(即webapp)下的jsp目录下找success.jsp
文件- 我们可以在SpringMVC的核心配置文件中配置内部资源视图解析器来将以上返回值简化为
return "success"
- 我们可以在SpringMVC的核心配置文件中配置内部资源视图解析器来将以上返回值简化为
-
配置步骤如下
<!--配置内部资源视图解析器--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--将InternalResourceViewResolver类中的视图名称前缀属性prefix的值设为/jsp/--><property name="prefix" value="/jsp/"></property><!--将InternalResourceViewResolver类中的视图名称后缀属性suffix的值设为.jsp--><property name="suffix" value=".jsp"></property> </bean>
-
配置完成后,Tomcat运行该Web项目输入URL后,系统会将返回值
return "success"
中的success拿出来,然后自动与/jsp/
以及.jsp
进行拼接,拼接为/jsp/success.jsp
即return /jsp/success.jsp
。然后系统会自动在Web项目核心目录(即webapp)下的jsp目录下找success.jsp
文件,并将该jsp文件显示在客户端页面上,配置代码截图如下
-
SpringMVC注解形式
SpringMVC注解形式的组件扫描
-
在SpringMVC的核心类
SpringMvcConfiguration
中利用@ComponentScan
注解来配置组件扫描,如下代码所示package at.guigu.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc;// 该注解代表该类是SpringMVC的核心配置类 @Configuration // 配置注解的组件扫描<context:component-scan base-package="at.guigu.controller"></context:component-scan> // 加载controller对应的bean @ComponentScan("at.guigu.controller") @EnableWebMvc public class SpringMvcConfiguration { }
-
需要注意的是在配置Spring核心配置类中的注解组件扫描时
@ComponentScan
属性值为at.gui
,所以此时Spring会扫描包括controller包下的注解,为避免该情况,则有两种解决方式-
将Spring加载的bean设定扫描范围为精准范围,比如:
@ComponentScan(basePackages = {"at.guigu.dao", "at.gui.service"})
-
将Spring加载的bean设定扫描范围为
at.gui
后排除掉controller包内的bean,该注解改为如下形式@ComponentScan(value = "at.guigu", excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class))
-
SpringMVC注解形式的核心配置类解析
SpringMVC有默认组件配置,默认组件都是在DispatherServlet.properties
配置文件中配置的,该配置文件在External Libraries
下,如图所示
-
在入门案例中使用了
@EnableWebMvc
注解来自动配置 SpringMVC 的各种特性,若想要修改则可以在SpringMVC的核心配置类中利用@Bean
注解来配置一个返回值为相应类的对象,此处以配置内部资源视图解析器为例 -
配置内部资源视图解析器
InternalResourceViewResolver
-
当返回值为
return "/jsp/success.jsp"
时:系统会自动在Web项目核心目录(即webapp)下的jsp目录下找success.jsp
文件- 我们可以在SpringMVC的核心配置文件中配置内部资源视图解析器来将以上返回值简化为
return "success"
- 我们可以在SpringMVC的核心配置文件中配置内部资源视图解析器来将以上返回值简化为
-
解决方式:在SpringMVC的核心配置类中配置内部资源视图解析器,代码如下
package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 @Configuration // 配置注解的组件扫描<context:component-scan base-package="at.guigu.controller"></context:component-scan> // 加载controller对应的bean @ComponentScan("at.guigu.controller") // 自动配置 Spring MVC 的各种特性 @EnableWebMvc public class SpringMvcConfiguration {// 配置视图解析器@Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/jsp/"); // 设置视图文件路径前缀resolver.setSuffix(".jsp"); // 设置视图文件后缀return resolver;} }
-
SpringMVC数据响应
该部分示例项目
MvcRespXmlDemo
及MvcRespClaDemo
已上传至Gitee,可自行下载
- SpringMVC的数据响应方式
- 方式一:页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
- 方式二:回写数据
- 直接返回字符串
- 返回对象或集合
- 方式一:页面跳转
- 环境准备等工作可详见快速入门
SpringMVC页面跳转
SpringMVC页面跳转——直接返回字符串
- 在我们之前的示例中均是直接返回字符串的形式,比如
return "success.jsp"
return "/success.jsp"
return "/jsp/success.jsp"
- 此处不在对直接返回字符出串的形式做详细解释
- 注意:
- 若我们配置了内部资源视图解析器,此时我们直接返回的字符串会与视图解析器的前后缀拼接到一起后跳转(可详见SpringMVC的核心配置文件解析)
- 在一下示例中均默认已配置内部资源视图解析器,来完成示例操作
SpringMVC页面跳转——通过ModelAndView对象返回
-
通过ModelAndView对象返回有四种方式,代码示例如下
-
controller
包下的UserController类代码如下package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;//将Usercontroller放到Spring容器中 @Controller @RequestMapping("/user") public class Usercontroller {/*** SpringMVC页面跳转——直接返回字符串* @return*/@RequestMapping(value = "/quick1")public String save1() {System.out.println("Usercontroller save...");return "success";// 等同于return "/user/success.jsp";}/*** SpringMVC页面跳转——返回ModelAndView对象 方式一* @return*/@RequestMapping("/quick2")public ModelAndView save2() {/*Model:模型 用来封装数据View:视图 用来展示数据*/ModelAndView mv = new ModelAndView();// 设置模型数据mv.addObject("username", "zhangsan");// 设置视图名称mv.setViewName("success");return mv;}/*** SpringMVC页面跳转——返回ModelAndView对象 方式二* @return*/@RequestMapping("/quick3")public ModelAndView save3(ModelAndView mv) {/*Model:模型 用来封装数据View:视图 用来展示数据*/// 设置模型数据mv.addObject("username", "zhangsan");// 设置视图名称mv.setViewName("success");return mv;}/*** SpringMVC页面跳转——返回ModelAndView对象 方式三* @return*/@RequestMapping("/quick4")public String save4(Model model) {/*Model:模型 用来封装数据View:视图 用来展示数据*/// 设置模型数据model.addAttribute("username", "zhangsan");// 返回jsp视图文件return "success";}/*** SpringMVC页面跳转——返回ModelAndView对象 方式四* 方式四不常用,了解知道即可* @return*/@RequestMapping("/quick5")public String save5(HttpServletRequest request) {/*Model:模型 用来封装数据View:视图 用来展示数据*/// request代替model来设置模型数据request.setAttribute("username", "zhangsan");// 返回jsp视图文件return "success";} }
-
success.jsp代码如下
- 注意:jsp文件中使用EL表达式时要在JSP页面顶部
<%@...%>
标签体内加上isELIgnored="false"
,作用:防止Tomcat配置禁用EL表达式
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html><head><title>Title</title></head><body><h1>...Success Running...</h1><h2>${username}</h2></body> </html>
Tomcat运行该Web项目后截图如下所示
- 注意:jsp文件中使用EL表达式时要在JSP页面顶部
-
-
注意
public ModelAndView save3(ModelAndView mv)
是通过参数传入ModelAndView
对象以供使用,原理是: SpringMVC会自动根据方法的参数进行相应的注入,以该save3
为例,当SpringMVC检测到其参数为ModelAndView
,而这个类是SpringMVC所有的,此时SpringMVC框架就会自动为其提供一个ModelAndView
对象以供该方法使用public String save5(HttpServletRequest request)
的原理也是Spring会根据方法的参数进行相应的注入
SpringMVC回写数据
SpringMVC回写数据——直接返回字符串
-
在Web基础阶段,客户端访问服务器端,若想直接回写字符串作为响应体返回的话,只需要使用
response.getWriter("Hello World")
方法即可,而在Controller中若想直接返回字符串的方式如下:- 方式一: 通过SpringMVC框架注入
response
对象(即参数为response
对象),然后使用response
对象的getWriter().print("Hello World")
方法回写数据即可- 注意:此时不需要视图跳转,且业务方法返回值为
void
- 注意:此时不需要视图跳转,且业务方法返回值为
- 方式二: 将需要回写的字符串直接返回,但此时需要使用
@ResponseBody
注解告知SpringMVC框架,该方法返回的是字符串不是页面跳转(即它是直接在http响应体中返回的字符串)@ResponseBody
注解作用:标注该注解的方法的返回值会直接写入 HTTP 响应体中。该注解通常用于 RESTful Web 服务或 AJAX 请求处理,以便返回 JSON、XML 或其他格式的数据。- 总结:代表不进行页面跳转,直接回写数据
- 方式一: 通过SpringMVC框架注入
-
方式一的代码示例如下
-
在controller包下重现创建一个示例类
UserControllerTwo
,代码如下package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*** SpringMVC回写数据*/ //将Usercontroller放到Spring容器中 @Controller @RequestMapping("/userTwo") public class UserControllerTwo {/*** SpringMVC回写数据——直接返回字符串方式一* @param response* @throws IOException*/@RequestMapping(value = "/quick1")public void save(HttpServletResponse response) throws IOException {response.getWriter().print("Hello World!");} }
-
-
方式二的代码示例如下
package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*** SpringMVC回写数据*/ //将Usercontroller放到Spring容器中 @Controller @RequestMapping("/userTwo") public class UserControllerTwo {/*** SpringMVC回写数据——直接返回字符串方式一* @param response* @throws IOException*/@RequestMapping(value = "/quick1")public void save(HttpServletResponse response) throws IOException {response.getWriter().print("Hello World!");}/*** SpringMVC回写数据——直接返回字符串方式二* @return*/@ResponseBody@RequestMapping(value = "/quick2")public String save2(){return "Hello World!";} }
-
方式二中我们一般会返回指定格式的字符串,比如JSON格式,代码步骤示例如下(以对象转为JSON格式为例)
-
注意:将对象转换为JSON格式进行输出时我们需要借助JSON的转换工具将对象转换为JSON格式的字符串,然后在返回
-
Step1: 在pom.xml文件中导入坐标
jackson-core
、jackson-databind
、jackson-annotations
<!--jackson-core--> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.17.1</version> </dependency> <!--jackson-databind--> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.17.1</version> </dependency> <!--jackson-annotations--> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.17.1</version> </dependency>
-
Step2: 创建一个pojo包,在该包下创建一个User类,代码如下
package at.guigu.pojo;public class User {private String name;private int age;public User() {}public User(String name, int age) {this.name = name;this.age = age;}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;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';} }
-
Step3:
UserControllerTwo
类代码如下package at.guigu.controller;import at.guigu.pojo.User; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*** SpringMVC回写数据*/ //将Usercontroller放到Spring容器中 @Controller @RequestMapping("/userTwo") public class UserControllerTwo {/*** SpringMVC回写数据——直接返回字符串方式一* @param response* @throws IOException*/@RequestMapping(value = "/quick1")public void save(HttpServletResponse response) throws IOException {response.getWriter().print("Hello World!");}/*** SpringMVC回写数据——直接返回字符串方式二:直接返回普通字符串数据* @return*/@ResponseBody@RequestMapping(value = "/quick2")public String save2(){return "Hello World!";}/*** SpringMVC回写数据——直接返回字符串方式二:返回JSON格式响应字符串数据* @return* @throws JsonProcessingException*/@ResponseBody@RequestMapping(value = "/quick3")public String save3() throws JsonProcessingException {User user = new User();user.setName("zhangsan");user.setAge(18);//使用JSON的转换工具将对象转换为JSON格式的字符串,然后在返回ObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(user);return json;} }
-
-
注意:我们可以利用
@RestController
注解来代替@Controller
和@ResponseBody
这两个注解-
原因:在类级别使用
@RestController
注解,就不需要在每个方法上单独使用@ResponseBody
注解。@RestController
本质上是@Controller
和@ResponseBody
的组合。 -
此时
UserControllerTwo
类中方式二的代码可更改如下package at.guigu.controller;import at.guigu.pojo.User; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*** SpringMVC回写数据*/ //将Usercontroller放到Spring容器中 @RestController @RequestMapping("/userTwo") public class UserControllerTwo {/*** SpringMVC回写数据——直接返回字符串方式二:直接返回普通字符串数据* @return*/@RequestMapping(value = "/quick2")public String save2(){return "Hello World!";}/*** SpringMVC回写数据——直接返回字符串方式二:返回JSON格式响应字符串数据* @return* @throws JsonProcessingException*/@RequestMapping(value = "/quick3")public String save3() throws JsonProcessingException {User user = new User();user.setName("zhangsan");user.setAge(18);//使用JSON的转换工具将对象转换为JSON格式的字符串,然后在返回ObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(user);return json;} }
-
SpringMVC回写数据——返回对象或集合
-
在 SpringMVC回写数据——直接返回字符串 的示例中
使用JSON的转换工具将对象转换为JSON格式的字符串,然后在返回
这种方式每次都需要如下两句代码ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(user);
这样就造成了代码冗余,为避免冗余我们可对其进行优化,已便于达到如下目的:SpringMVC自动将对象或集合转为JSON格式的字符串
-
原理:找到SpringMVC默认组件配置的配置文件
DispatherServlet.properties
(可详见SpringMVC核心配置文件解析),然后找到处理器适配器HandlerAdapter
接口下的RequestMappingHandlerAdapter
类,该类下有一个public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters)
方法可用来设置一个JSON转换的转换器- 该类的作用:处理使用
@RequestMapping
注解的控制器方法。它是HandlerAdapter
接口的一个具体实现,负责调用带有@RequestMapping
注解的方法来处理 HTTP 请求。 - 可通过SpringMVC的核心配置文件来更改(配置代码及步骤可详见SpringMVC核心配置文件解析)
- 该类的作用:处理使用
-
-
优化步骤如下
-
Step1: SpringMVC核心配置文件代码如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--配置Controller层的注解的组件扫描--><context:component-scan base-package="at.guigu.controller"></context:component-scan><!--等同于<context:component-scan base-package="at.guigu">type指定要扫描的内容为注解,expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有@Controller注解的类<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>--><!--配置内部资源视图解析器--><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/--><property name="prefix" value="/user/"></property><!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp--><property name="suffix" value=".jsp"></property></bean><!--配置处理器适配器--><bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/></list></property></bean> </beans>
配置内部资源视图解析器以及处理器适配器都用到了setter方法注入,只是说一个是普通数据类型注入,一个是集合注入。具体注入方法解释可详见Spring完整知识点汇总一中的依赖注入
-
Step2: 直接返回字符串方式二:返回JSON格式响应字符串数据的代码更改如下
package at.guigu.controller;import at.guigu.pojo.User; import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;//将Usercontroller放到Spring容器中 @Controller @RequestMapping("/userTwo") public class UserControllerFour {/*** SpringMVC回写数据——直接返回字符串方式二:返回JSON格式响应字符串数据* @return* @throws JsonProcessingException*/@ResponseBody@RequestMapping(value = "/quick3")public User save3() throws JsonProcessingException {User user = new User();user.setName("zhangsan");user.setAge(18);return user;} }
-
除此之外还可返回集合数据,代码如下:
package at.guigu.controller;import at.guigu.pojo.User; import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import java.util.ArrayList; import java.util.List;/*** 将Usercontroller放到Spring容器中* 测试:经配置后,SpringMVC自动将对象或集合转为JSON格式的字符串*/ @Controller @RequestMapping("/userFour") public class UserControllerFour {/*** SpringMVC回写数据——直接返回字符串方式二:返回JSON格式响应字符串数据* @return* @throws JsonProcessingException*/@ResponseBody@RequestMapping(value = "/quick3")public User save3() throws JsonProcessingException {User user = new User();user.setName("zhangsan");user.setAge(18);return user;}/*** SpringMVC回写数据——直接返回字符串方式二:返回JSON格式响应集合数据* @return* @throws JsonProcessingException*/@ResponseBody@RequestMapping(value = "/quick4")public List<User> save4() throws JsonProcessingException {User user1 = new User();user1.setName("zhangsan");user1.setAge(15);User user2 = new User();user2.setName("lisi");user2.setAge(12);List<User> userList = new ArrayList<User>();userList.add(user1);userList.add(user2);return userList;}}
-
-
在SpringMVC核心配置文件中进行处理器适配器的配置还稍显麻烦,我们可以在SpringMVC核心配置文件中使用mvc的注解驱动来代替对处理器适配器进行的配置
-
mvc的注解驱动代码:
<mvc:annotation-driven/>
- 它能够自动加载处理器映射器
RequestMappingHandlerMapping
和处理器适配器RequestMappingHandlerAdapter
,并且它的底层会继承jackson进行对象或集合的JSON格式字符串的转换
- 它能够自动加载处理器映射器
-
此时SpringMVC的核心配置文件代码如下
注意:mvc的注解驱动代码需要引入mvc的命名空间以及约束路径(可详见Spring快速入门代码实现)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--配置Controller层的注解的组件扫描--><context:component-scan base-package="at.guigu.controller"></context:component-scan><!--等同于<context:component-scan base-package="at.guigu">type指定要扫描的内容为注解,expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有@Controller注解的类<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>--><!--配置内部资源视图解析器--><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/--><property name="prefix" value="/user/"></property><!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp--><property name="suffix" value=".jsp"></property></bean><!--mvc的注解驱动--><mvc:annotation-driven/><!--等同于配置处理器适配器--><!--<bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/></list></property></bean>--> </beans>
-
SpringMVC的核心配置文件对应的SpringMVC核心配置类代码如下
package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 @Configuration // 配置注解的组件扫描<context:component-scan base-package="at.guigu.controller"></context:component-scan> // 加载controller对应的bean @ComponentScan("at.guigu.controller") // 自动配置 Spring MVC 的各种特性,比如mvc的注解驱动<mvc:annotation-driven/> @EnableWebMvc public class SpringMvcConfiguration {// 配置视图解析器@Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/user/"); // 设置视图文件路径前缀resolver.setSuffix(".jsp"); // 设置视图文件后缀return resolver;} }
-
相关文章:

SpringMvc完整知识点一
SpringMVC概述 定义 SpringMVC是一种基于Java实现MVC设计模型的轻量级Web框架 MVC设计模型:即将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。这种分离…...

STM32G4系列MCU双ADC多通道数据转换的应用
目录 概述 1 STM32Cube配置项目 1.1 基本参数配置 1.1.1 ADC1参数配置 1.1.2 ADC2参数配置 1.2 项目软件架构 2 功能实现 2.1 ADC转换初始化 2.2 ADC数据组包 3 测试函数 3.1 Vofa数据接口 3.2 输入数据 4 测试 4.1 ADC1 通道测试 4.2 ADC2 通道测试 概述 本文…...

【工具】音频文件格式转换工具
找开源资源、下载测试不同库的效果,然后找音频、下载音频、编写代码、测试转换、流程通畅。写一个工具花的时间越来越多了!这个 5 天 这个工具是一个音频文件格式转换工具,支持对 mp3.aac.wav.caf.flac.ircam.mp2.mpeg.oga.opus.pcm.ra.spx.…...

ssl证书过期,nginx更换证书以后仍然显示过期证书
记一次nginx部署异常 今天提示ssl证书过期了,然后重新申请了一个证书 反反复复折腾了一个上午,还更换了好几个平台,发现怎么更换都没用,百度上的解决方法都试过了,发现都没用,证书还是显示的原来那一个&…...

原型模式(Prototype Pattern)——对象克隆、深克隆与浅克隆及适用场景
原型模式(Prototype Pattern)是设计模式中的一种创建型模式,目的是通过复制现有的对象来创建新的对象,而不是通过传统的实例化方式。原型模式常常用于需要创建大量类似对象的场景,可以提高性能并减少资源的消耗。下面将…...

从工标网网站解析标准信息
import requests from bs4 import BeautifulSoup 将标准搜索关键词转化成GBK格式,并用%连接转化后16进制,转化成工标网的查询网址url text “GB/T 9755” utf8_encoded_text text.encode(‘GBK’) #print(utf8_encoded_text) hex_representation ‘…...

如何在MySQL中开启死锁日志及查看日志
在数据库的多用户环境中,死锁是一个常见的问题,它可能会影响到数据库的性能和稳定性。MySQL提供了一些工具和命令来帮助我们识别和解决死锁问题。本文将介绍如何在MySQL中开启死锁日志以及如何查看这些日志。 一、为什么需要死锁日志 死锁是指两个或多…...

VCP-CLIP A visual context prompting modelfor zero-shot anomaly segmentation
GitHub - xiaozhen228/VCP-CLIP: (ECCV 2024) VCP-CLIP: A visual context prompting model for zero-shot anomaly segmentation 需要构建正样本,异常样本,以及对应的Mask...

分类算法中的样本不平衡问题及其解决方案
一、样本不平衡问题概述 在机器学习的分类任务中,样本不平衡是指不同类别训练样本数量存在显著差异的现象。这一差异会给模型训练和性能评估带来挑战,尤其在处理少数类样本时,模型可能难以有效学习其特征。 以二分类为例,理想情况…...

博物馆导览系统方案(一)背景需求分析与核心技术实现
维小帮提供多个场所的室内外导航导览方案,如需获取博物馆导览系统解决方案可前往文章最下方获取,如有项目合作及技术交流欢迎私信我们哦~撒花! 一、博物馆导览系统的背景与市场需求 在数字化转型的浪潮中,博物馆作为文化传承和知…...

[创业之路-169]:《BLM战略规划》- 战略洞察 (战略能力中最最核心的能力) - 市场洞察 -1- 看宏观/行业 - 行业:激光器行业的详细分析
目录 一、激光器行业的详细分析 1. 行业总容量分析 2. 行业成长性分析 3. 行业的供需结构 4. 行业的发展阶段与动态S曲线 5. 行业集中度 6. 关键成功因素 二、对深紫外激光器进行如下分析 1、行业总容量分析 2、行业成长性分析 3、行业的供需结构 4、行业的发展阶段…...

抽象工厂模式的理解和实践
在软件开发中,设计模式是解决常见问题的最佳实践。抽象工厂模式是一种创建型设计模式,提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。本文将详细解释抽象工厂模式的概念、结构、优点、缺点,并通过Java代…...

WIDER FACE数据集转YOLO格式
1. 引出问题 本人最近在做毕设相关内容,第一阶段目标是通过目标检测来统计课堂人数,因此需要对人脸和人头进行目标检测。模型方面没什么好说的无脑用YOLO,数据集方面,人脸部分找到了来自港中文的WIDER FACE数据集。但是解压后发现…...

项目启动的基本配置
开启驼峰命名 如果字段名与属性名符合驼峰命名规则,MyBatis会自动通过驼峰命名规则映射。 在application.yml配置文件中,可以添加以下配置来开启驼峰命名规则: mybatis:configuration:map-underscore-to-camel-case: true 这段配置的作用…...

Ubuntu桌面突然卡住,图形界面无反应
1.可能等待几分钟,系统会自动反应过来。你可以选择等待几分钟。 2.绝大多数情况系统是不会反应过来的,这时候可以进入tty终端直接注销用户。 (1)Ubuntu有6个tty终端,按住CtrlAltF1可以进入tty1终端,(同理CtrlAltF2&a…...

Next.js系统性教学:拦截路由与路由处理器
更多有关Next.js教程,请查阅: 【目录】Next.js 独立开发系列教程-CSDN博客 目录 1. 路由拦截 (Intercepting Routes) 1.1 什么是路由拦截? 1.2 配置拦截路由 1.3 示例:模态框预览 1.4 使用场景 2. 路由处理器 (Route Handl…...

Python编码风格
Python代码的常用排版格式主要遵循PEP 8规范,这是Python社区广泛接受的编码风格指南。以下是一些关键的排版格式要求: 一、缩进 使用4个空格作为缩进级别,不要使用Tab键,更不能混合使用Tab和空格。 二、行长度 每行代码的最大…...

flask创建templates目录存放html文件
首先,创建flask项目,在pycharm中File --> New Project,选择Flask项目。 然后,在某一目录下,新建名为templates的文件夹,这时会是一个普通的文件夹。 然后右击templates文件夹,选择Unmark as …...

微信小程序里的小游戏研发需要什么技术栈
研发小程序里的小游戏通常需要以下技术栈: 前端技术 HTML5 / CSS3:用于构建游戏的界面布局和样式。JavaScript:作为核心编程语言,实现游戏的逻辑和交互。小程序开发框架:如微信小程序的开发框架,了解其 API…...

2024年上半年网络工程师案例分析真题及答案解析
2024年上半年网络工程师案例分析真题及答案解析 1、试题一(20分) 阅读以下说明,回答问题。 [说明]某高校网络拓扑如下图所示,两校区核心(CORE-1,CORE-2),出口防火墙(NGFW-1,NGFW-2)通过校区间光缆互联,配置OSPF实现全校路由收效,校区相距40km。两校区默认由本地出…...

Ant Design Vue v4版本如何解决1px没有被postcss-px2rem转成rem的问题
背景说明 如果你的 Ant Design Vue 项目有要做适配的需求,那首先要选择一种适配方案。笔者选择的是用 postcss-px2rem 进行适配。笔者在配置了 postcss-px2rem的相关配置后,发现 postcss-px2rem 没有对 Ant Design Vue 进行适配。在网上看了一些文章之后…...

武汉科技大学《2024年814自动控制原理真题》 (完整版)
本文内容,全部选自自动化考研联盟的:《武汉科技大学814自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2024年真题 Part1:2024年完整版真题 2024年真题...

【锂电池实战】A123磷酸铁锂在线参数识别-一阶戴维南模型
A123磷酸铁锂在线参数识别-一阶戴维南模型 提要 理论介绍:一篇就够了,为你答疑解惑:锂电池一阶模型-在线参数辨识(附代码)_在线参数辨识方法-CSDN博客 数据源:Battery Data | Center for Advanced Life Cycle Engineering 打包下载地址:A123-DST-US06-FUDS-25.zip资源…...

Java多线程与线程池技术详解(四)
接受失败:“失败是什么?没有什么,只是更走近成功一步;成功是什么?就是走过了所有通向失败的路,只剩下一条路,那就是成功的路。”这句话很好地诠释了如何看待失败的问题,即每一次跌倒…...

树莓派开发笔记
一. 登录方式 1.1 方式一:HDMI视频线 1.2 方式二:串口 查看串口有否被加密,默认情况下树莓派串口和蓝牙连接,需先断开蓝牙连接,串口才能用于数据通信。 1.2.1 如何使用串口登录 打开SD卡根目录的"config.txt"文件,将以下内容添加在最后并且保存。这样就停止…...

【数据结构】遍历二叉树
遍历二叉树的算法描述(递归定义) 先序遍历 若二叉树为空,则空操作; 否则 (1)访问根节点 (2)先序遍历左子树 (3)先序遍历右子树 中序遍历 若二叉树为空…...

嵌入式蓝桥杯学习7 产生PWM
Cubemx配置 打开cubemx,前面的配置看上文,这里主要配置定时器产生PWM波。 以PA1的TIM2-CH2通道为例进行演示。 1.在Timers中打开TIM2,将Channel2配置为PWM Generation CH2。 2.将Clock Source 选择为Internal Clock。 3.配置Paramater Settings中的参…...

档案学实物
档案工作 档案工作的性质 服务性 文化性 管理性 政治性 科学性 档案工作的地位 档案工作的效益 社会性,隐蔽性,滞后性 档案工作的发展规律 档案收集 档案收集工作的内容意义 档案收集工作的具体要求 档案室的档案收集工作 档案馆的档案收集工作 档案…...

数据清洗代码:缺失值,异常值,离群值Matlab处理
目录 基本介绍程序设计参考资料基本介绍 一、过程概述 本过程适用于处理SCADA系统采集到的数据,以及具有类似需求的数据集。处理步骤包括缺失值处理、异常值处理和离群值处理,旨在提升数据质量,增强数据的相关性,同时保持数据的原始特征和随机性。 二、缺失值处理 对于SC…...

Windows设备go环境安装配置
一、下载go安装包 官网链接:All releases - The Go Programming Language (google.cn) 安装过程比较简单,这里不再赘述,可参考这位博主的文章。本文重点在环境配置。golang环境详细安装、配置_golang安装-CSDN博客 二、环境变量配置 1.添…...