SSM 整合

文章目录

  • SSM 整合(代码配置)
    • 1. 基本形式
    • 2. 无 web.xml 的理论基础
    • 3. WebInitializer 替代 web.xml
    • 4. SpringWebConfig 替代 spring-web.xml
    • 5. 配置『静态资源不拦截』
      • 方案一
      • 方案二
    • 6. 配置 URL 后缀生效/失效
    • 7. 整合 Service 层
    • 8. 整合 Dao 层
    • 9. Mybatis 相关配置文件
    • 10. 其它

SSM 整合(代码配置)

1. 基本形式

Spring 的 Java 代码配置与 XML 配置文件配置有对应关系,本质上太大区别。

核心关键点有两处:

  • .xml 配置文件演变为一个配置类,其头上标注 @Configuation 注解;

  • <bean> 配置演变为配置类中的一个方法,其头上标注 @Bean 注解。

2. 无 web.xml 的理论基础

为了支持脱离 web.xml,Servlet 定义了一个 javax.servlet.ServletContainerInitializer 的接口,并且要求在 Servlet 容器启动 web 项目时,在项目的的 jar 包中的 META-INF/services 去找一个名字是它的完全限定名的文件。

在 Spring MVC 项目中,spring-web 包下的 META-INF/services 目录下就存在这样一个 javax.servlet.ServletContainerInitializer 的文件。

按照约定,这个文件的内容可以放 ServletContainerInitializer 接口的实现类的完全限定名,在 Spring MVC 中这个实现了是 org.springframework.web.SpringServletContainerInitializer

Servlet 容器在启动时会创建这个文件中所记载的 ServletContainerInitializer 接口的实现类的对象,并调用它的 onStartup

SpringServletContainerInitializeronStartup 方法中,它会去查找、调用 Spring MVC 项目中所有 WebApplicationInitializer 接口直接(或间接)实现类的 onStartup 方法。

所以,我们需要直接(或间接)实现 WebApplicationInitializer,并在 onStartup 方法中实现我们曾将在 web.xml 中所实现的内容。

3. WebInitializer 替代 web.xml

当然,我们通常并不会直接实现 WebApplicationInitializer 接口,我们可以通过继承 AbstractAnnotationConfigDispatcherServletInitializer 来间接实现 WebApplicationInitializer 接口:

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {// 第一次加载配置时机所加载的配置类。@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class<?>[] {SpringServiceConfig.class,SpringDaoConfig.class};}// 第二次加载配置时机所加载的配置类。 @Overrideprotected Class<?>[] getServletConfigClasses() {return new Class<?>[] {SpringWebConfig.class};}// 设置 DispatcherServlet 的映射@Overrideprotected String[] getServletMappings() {return new String[] { "/" };}
}

曾经在 web.xml 中配置过一个 Filter 来解决 GET 请求中文乱码问题,如果要在 WebInitializer 中实现同样的效果,则需要多重写一个父类的方法:

@Override
protected Filter[] getServletFilters() {Filter encodingFilter = new CharacterEncodingFilter("UTF-8", true);return new Filter[] { encodingFilter };
}

4. SpringWebConfig 替代 spring-web.xml

@Configuration
@EnableWebMvc   // 注解驱动
@ComponentScan("xxx.yyy.zzz.web") // 包扫描
public class SpringWebConfig implements WebMvcConfigurer {@Bean   // 视图解析器public InternalResourceViewResolver viewResolver() {InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();viewResolver.setPrefix("/WEB-INF/jsp/");viewResolver.setSuffix(".jsp");return viewResolver;}
}

除了上面三项关键性配置之外,还有一些附加功能配置可供选择。

5. 配置『静态资源不拦截』

当然 DispatcherServlet 配置的是拦截的是 *.后缀 形式,那么就不存在静态资源拦截问题。所以,需要考虑静态资源拦截问题时,通常意味着 DispacherServlet 配置的是 / 。另外,通常不会、不建议使用 /**

实现静态资源不拦截的方式有两种(二选一),一是启用 DefaultServletHandler,二是配置 ResouceHandler

方案一

配置启用 DefaultServletHandler 意味着:像 .js.css 这样的 URL 没有 Controller 处理则由 DefaultServletHandler 处理,而它的处理方式就是在对应目录下找到这些文件并发送给客户端(浏览器)

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();
}

方案二

配置 ResouceHandler 就是明确告诉 Spring MVC 当 URL 路径中出现何种关键词(或后缀)时,去哪个路径下找静态资源文件。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/css/**")// 过滤静态资源路径.addResourceLocations("classpath:/css");// 定位资源registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js");registry.addResourceHandler("/img/**").addResourceLocations("classpath:/img");}
}

6. 配置 URL 后缀生效/失效

常规的 Java Web 一般不会考虑这个问题。在 Restful 的 Java Web 中才会针对『一个奇怪的现象』考虑这个配置。

默认情况下 Spring MVC 会忽略掉 URL 请求中的后缀。也即是说
,在 URL 中使用 hello.do 能触发 @RequestMapping(“/hello”) 的执行。

有时可能需要 Spring MVC 更『严谨』一些。如果是在 .xml 配置文件中是配置成这样:

<mvc:annotation-driven><mvc:path-matching suffix-pattern="false" />
</mvc:annotation-driven>

在代码配置中,对等的配置是如下:

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {// 显而易见,这个值默认是 true 。configurer.setUseSuffixPatternMatch(false);
}

7. 整合 Service 层

这里通过配置类 SpringServiceConfig 来等价替代 spring-service.xml 配置文件。

@Configuration
@ComponentScan("xxx.yyy.zzz.service")   // 包扫描
@EnableTransactionManagement            // 激活/启用事务注解(@Transactional)
public class SpringServiceConfig {// txManager@Beanpublic DataSourceTransactionManager transactionManager(DataSource dataSource) {DataSourceTransactionManager manager = new DataSourceTransactionManager();manager.setDataSource(dataSource);return manager;}}

8. 整合 Dao 层

这里通过配置类 SpringDaoConfig 来等价替代 spring-dao.xml 配置文件。

大体上,以下配置类就是 spring-dao.xml 配置文件的对等转换结果。不过有一处需要注意的地方。

@Configuration
@PropertySource("classpath:jdbc.properties")
public class SpringDaoConfig {@Value("${datasource.driver-class-name}")private String driverClassName;@Value("${datasource.url}")private String url;@Value("${datasource.username}")private String userName;@Value("${datasource.password}")private String password;@Bean   // 数据库连接池public HikariDataSource dataSource() {HikariDataSource ds = new HikariDataSource();ds.setDriverClassName(driverClassName);ds.setJdbcUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}@Bean   // sqlSessionFactorypublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws IOException {SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();sqlSessionFactory.setDataSource(dataSource);sqlSessionFactory.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("mybatis/mapper/*.xml"));return sqlSessionFactory;}@Bean   // 包扫描public MapperScannerConfigurer mapperScannerConfigurer() {MapperScannerConfigurer configurer = new MapperScannerConfigurer();configurer.setBasePackage("com.softeem.dao");return configurer;}
}

如果是 spring-dao.xml 无脑改 SpringDaoConfig,那么

sqlSessionFactory.setConfigLocation("...");
sqlSessionFactory.setMapperLocations("...");

为 sqlSessionFactory 的 configLocation 和 mapperLocations 属性赋值时『想当然地』是提供两个字符换(因为 .xml 配置文件中就是如此)。

但是,在实际中,sqlSessionFactory 的这两个属性需要的是 Resource 对象和 Resource 对象的数组。因此,需要以这两个字符串为依据,生成与之对应的对象和对象的数组,后再使用:

new ClassPathResource("mybatis/mybatis-config.xml"));new PathMatchingResourcePatternResolver().getResources("mybatis/mapper/*.xml")

9. Mybatis 相关配置文件

Mybatis 的核心配置文件和映射文件还是需要以 .xml 形式提供。

略。

10. 其它

@Configuration
@EnableWebMvc
@ComponentScan("com.xja.hemiao.web.controller") // 包扫描
public class SpringWebConfig implements WebMvcConfigurer {@Bean(name = "multipartResolver") // bean 必须写 name 属性且必须为 multipartResolverprotected CommonsMultipartResolver multipartResolver() {CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();commonsMultipartResolver.setMaxUploadSize(5 * 1024 * 1024);commonsMultipartResolver.setMaxInMemorySize(0);commonsMultipartResolver.setDefaultEncoding("UTF-8");return commonsMultipartResolver;}@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {super.configureMessageConverters(converters);FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);fastConverter.setFastJsonConfig(fastJsonConfig);converters.add(fastConverter);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/774524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

07、Lua 流程控制

Lua 流程控制 Lua 流程控制控制结构语句 Lua 流程控制 Lua编程语言流程控制语句通过程序设定一个或多个条件语句来设定。在条件为 true 时执行指定程序代码&#xff0c;在条件为 false 时执行其他指定代码。 以下是典型的流程控制流程图&#xff1a; 控制结构的条件表达式结…

python面试题(1~10)

1、列表&#xff08;list&#xff09;和元组&#xff08;tuple&#xff09;有什么区别&#xff1f; ①列表是不可变的&#xff0c;创建后可以对其进行修改。元组是不可变的&#xff0c;元组一旦创建&#xff0c;就不能对其进行修改。 ②列表表示的顺序&#xff0c;它们是有序…

vscode c++环境配置

1.基础软件安装 安装Visual Studio Code. 安装C拓展。点击在vscode界面最左侧的Extensions图标&#xff08;打开快捷键&#xff1a;ctrlshiftX&#xff09;&#xff0c;搜索“C/C”&#xff0c;点击进行安装。 确保已安装gcc. 一般ubuntu系统会预装gcc.在终端窗口中输入如下…

查立得源码如何去除版权

最近发现很多人百度&#xff1a;查立得源码如何去除版权。 每个源代码/软件都是有版权的&#xff0c;无法去除&#xff0c;我们也得尊重知识产权/劳动成果。 可以去除/修改的是&#xff1a;页面显示的版权信息,查立得底部信息均可自定义(一般conn.php可修改)。 另&#xff1…

Linux-2 Linux的权限

目录 1.什么是权限&#xff1f; 2.权限的本质 3.Linux中的用户 普通用户与root用户相互转换 普通用户不变root&#xff0c;以root身份执行一个命令 LInux中的角色 4.Linux文件的权限 5.快速掌握修改权限的做法 修改权限 6.对比权限有无表现 对于普通用户&#xf…

五分钟,零基础也能入门 Python 图像文字识别

一. 前言 最近在研究 Python 的一些功能 &#xff0c; 也尝试了一些有趣实现&#xff0c; 这一篇就从实践的角度来研究一下 Python 如何实现图片识别。 众所周知 &#xff0c; Python 的库真的老多了&#xff0c;其中在图像识别上比较突出的就是 OpenCV. 那么基于这个库我们…

基于RAG的大模型知识库搭建

什么是RAG RAG(Retrieval Augmented Generation)&#xff0c;即检索增强生成技术。 RAG优势 部分解决了幻觉问题。由于我们可以控制检索内容的可靠性&#xff0c;也算是部分解决了幻觉问题。可以更实时。同理&#xff0c;可以控制输入给大模型上下文内容的时效性&#xff0c…

什么是高阶组件,有哪些场景?

高阶函数是接收一个或者多个函数作为入参,返回一个新的函数。 高阶组件,则是接收一个或者多个组价作为入参,并且返回一个组件。高阶组件的实现方式,本质上是一个装饰者设计模式。 最基本的高阶组件模版如下: import React form react;export default (WrappedComponent…

Day50:WEB攻防-PHP应用文件包含LFIRFI伪协议编码算法无文件利用黑白盒

目录 文件包含-原理&分类&利用&修复 文件读取 文件写入 代码执行 远程利用思路 黑盒利用-VULWEB 白盒利用-CTFSHOW-伪协议玩法 78-php&http协议 79-data&http协议 80-81-日志包含 87-php://filter/write&加密编码 88-data&base64协议 …

17、GateWay和Sentinel继承实现服务限流

注&#xff1a;本篇文章主要参考周阳老师讲解的cloud进行整理的&#xff01; 1、需求说明 cloudalibaba-sentinel-gateway9528 保护 cloudalibaba-provider-payment9001 2、启动nacos服务器8848 startup.cmd -m standalone 3、启动sentinel服务器8080 java -jar sentinel-dash…

Linux系列之统计某个字符串出现次数并排序

业务场景 最近遇到一个流量异常调用的接口&#xff0c;所以需要通过后台日志查看接口调用情况&#xff0c;先统计今天内接口的调用次数&#xff0c;再具体到对应的设备号&#xff0c;就知道哪台设备有问题了&#xff0c;初步想到wc和awk命令来筛选统计&#xff0c;但是真正去写…

企业微信变更主体公证怎么弄?

企业微信变更主体有什么作用&#xff1f;现在很多公司都用企业微信来加客户&#xff0c;有时候辛辛苦苦积累了很多客户&#xff0c;但是公司却因为各种各样的原因需要注销&#xff0c;那么就需要通过企业微信变更主体的方法&#xff0c;把企业微信绑定的公司更改为最新的。企业…

python内置函数 V

python内置函数 V Python 解释器内置了很多函数和类型&#xff0c;任何时候都能使用。 V 名称描述vars返回当前局部符号表的字典。 vars() vars(object) 返回模块、类、实例或任何其它具有 __dict__ 属性的对象的 __dict__ 属性。 模块和实例这样的对象具有可更新的 __d…

恶意勒索软件VirLock,通过ApkAnalyser一键提取安卓应用APK敏感信息

恶意勒索软件VirLock&#xff0c;通过ApkAnalyser一键提取安卓应用APK敏感信息。 ############################# 免责声明&#xff1a;本文仅作收藏学习之用&#xff0c;亦希望大家以遵守《网络安全法》相关法律为前提学习&#xff0c;切勿用于非法犯罪活动&#xff0c;对于恶…

ES集群部署的注意事项

文章目录 引言I ES集群部署前期工作II 部署ES2.1 配置安全组2.2 创建ES用户和组2.3 下载安装ES2.4 修改内存相关配置III es集群添加用户安全认证功能3.1 生成 elastic-certificates.p123.2 创建 Elasticsearch 集群密码3.2 设置kibana的 elasticsearch帐号角色和密码3.3 logsta…

python和c语言的区别是什么

Python可以说是目前最火的语言之一了&#xff0c;人工智能的兴起让Python一夜之间变得家喻户晓&#xff0c;Python号称目前最最简单易学的语言&#xff0c;现在有不少高校开始将Python作为大一新生的入门语言。本萌新也刚开始接触Python&#xff0c;发现Python与其他语言确实有…

linux查找指定目录下包含指定字符串文件,包含子目录

linux查找指定目录下包含指定字符串的文件&#xff0c;包含子目录 linux查找指定目录下包含指定字符串的指定文件格式&#xff0c;包含子目录 指定目录 cd /home/www/linux查找指定目录下包含指定字符串的文件&#xff0c;包含子目录 grep -r "指定字符串"注释 gr…

无代码开发:公贝资产钉钉版助力电商平台和用户运营系统集成

{连接公贝资产钉钉版与营销系统} 公贝资产钉钉版可以轻松连接营销系统&#xff0c;实现资产管理与营销活动的有效结合。通过简单的连接操作&#xff0c;用户可以将公贝资产钉钉版中的资产信息与营销系统进行同步&#xff0c;实现信息的共享和更新。这样一来&#xff0c;营销团…

IntelliJ中的非JVM技术

Markdown&#xff1a;https://www.jetbrains.com/help/idea/markdown.html 支持CommonMark&#xff08;定制Markdown标准&#xff09;&#xff0c;IntelliJ默认捆绑了Markdown插件&#xff0c;所以可以学学这个文章&#xff0c; 以便可以更好的在IntelliJ中使用Markdown。JSON&…

测试开发工程师(QA)职业到底需要干些什么?part6:数据测试工程师QA

常见任务和工作内容 作为数据测试工程师QA&#xff08;Quality Assurance&#xff09;&#xff0c;您的主要职责是确保数据的质量、准确性和一致性。以下是数据测试工程师QA的一些常见任务和工作内容&#xff1a; 数据验证和准确性测试&#xff1a;您将负责验证数据的准确性和…