说句实话,很久都没使用SSH开发项目了,但是出于各种原因,再次记录一下整合方式,纯注解零配置。
一。前期准备工作
gradle配置文件:
group 'com.bdqn.lyrk.ssh.study' version '1.0-SNAPSHOT' apply plugin: 'war' repositories { mavenLocal() mavenCentral() } dependencies { // https://mvnrepository.com/artifact/org.apache.struts/struts2-core compile group: 'org.apache.struts', name: 'struts2-core', version: '2.5.14.1' // https://mvnrepository.com/artifact/org.apache.struts/struts2-spring-plugin compile group: 'org.apache.struts', name: 'struts2-spring-plugin', version: '2.5.14.1' // https://mvnrepository.com/artifact/org.springframework/spring-context compile group: 'org.springframework', name: 'spring-context', version: '5.0.4.RELEASE' // https://mvnrepository.com/artifact/org.springframework/spring-web compile group: 'org.springframework', name: 'spring-web', version: '5.0.4.RELEASE' // https://mvnrepository.com/artifact/org.hibernate/hibernate-core compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final' // https://mvnrepository.com/artifact/org.hibernate/hibernate-validator compile group: 'org.hibernate', name: 'hibernate-validator', version: '5.4.1.Final' // https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0' // https://mvnrepository.com/artifact/org.springframework/spring-orm compile group: 'org.springframework', name: 'spring-orm', version: '5.0.4.RELEASE' // https://mvnrepository.com/artifact/org.springframework/spring-tx compile group: 'org.springframework', name: 'spring-tx', version: '5.0.4.RELEASE' // https://mvnrepository.com/artifact/com.zaxxer/HikariCP compile group: 'com.zaxxer', name: 'HikariCP', version: '2.7.4' // https://mvnrepository.com/artifact/org.apache.struts/struts2-convention-plugin compile group: 'org.apache.struts', name: 'struts2-convention-plugin', version: '2.5.14.1' testCompile group: 'junit', name: 'junit', version: '4.11' }
结构文件:
注意在classpath下创建META-INF/services/javax.serlvet.ServletContainerInitializer文件,那么在文件中定义的类在servlet容器启动时会执行onStartup方法,我们可以在这里编码创建servlet,fliter,listener等,文件内容如下:
com.bdqn.lyrk.ssh.study.config.WebInitializer
二。具体的集成实现方案
1.定义 MyAnnotationConfigWebApplicationContext
package com.bdqn.lyrk.ssh.study.config; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; /** * 自定义配置,为了在ContextLoaderListener初始化注解配置时使用 * @Author chen.nie */ public class MyAnnotationConfigWebApplicationContext extends AnnotationConfigWebApplicationContext { public MyAnnotationConfigWebApplicationContext(){ this.register(AppConfig.class); } }
2.定义WebInitializer
package com.bdqn.lyrk.ssh.study.config; import org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter; import org.springframework.orm.hibernate5.support.OpenSessionInViewFilter; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import javax.servlet.*; import javax.servlet.annotation.HandlesTypes; import javax.servlet.http.HttpServlet; import java.util.EnumSet; import java.util.Set; /** * 自定义servlet容器初始化,请参考servlet规范 */ @HandlesTypes({HttpServlet.class, Filter.class}) public class WebInitializer implements ServletContainerInitializer { @Override public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException { /* 创建struts2的核心控制器 */ StrutsPrepareAndExecuteFilter strutsPrepareAndExecuteFilter = ctx.createFilter(StrutsPrepareAndExecuteFilter.class); OpenSessionInViewFilter openSessionInViewFilter = ctx.createFilter(OpenSessionInViewFilter.class); /* 向servlet容器中添加filter */ ctx.addFilter("strutsPrepareAndExecuteFilter", strutsPrepareAndExecuteFilter). addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); FilterRegistration.Dynamic dynamic = ctx.addFilter("openSessionInViewFilter", openSessionInViewFilter); dynamic.setInitParameter("flushMode", "COMMIT"); dynamic.setInitParameter("sessionFactoryBeanName","localSessionFactoryBean"); dynamic.setInitParameter("singleSession","true"); dynamic.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); /* 添加监听器 */ ContextLoaderListener contextLoaderListener = new ContextLoaderListener(); ctx.addListener(contextLoaderListener); ctx.setInitParameter("contextClass", "com.bdqn.lyrk.ssh.study.config.MyAnnotationConfigWebApplicationContext"); } }
3.定义AppConfig
package com.bdqn.lyrk.ssh.study.config; import com.zaxxer.hikari.HikariDataSource; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.orm.hibernate5.HibernateTemplate; import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; import java.util.Properties; /** * spring基于注解配置 * * @author chen.nie * @date 2018/3/21 **/ @Configuration @ComponentScan("com.bdqn") @EnableTransactionManagement public class AppConfig { /** * 定义数据源 * @return */ @Bean public HikariDataSource dataSource() { HikariDataSource hikariDataSource = new HikariDataSource(); hikariDataSource.setDriverClassName("com.mysql.jdbc.Driver"); hikariDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/MySchool?characterEncoding=utf-8&useSSL=false"); hikariDataSource.setUsername("root"); hikariDataSource.setPassword("root"); return hikariDataSource; } /** * 定义spring创建hibernate的Session对象工厂 * @param dataSource * @return */ @Bean public LocalSessionFactoryBean localSessionFactoryBean(@Autowired DataSource dataSource) { LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean(); localSessionFactoryBean.setDataSource(dataSource); localSessionFactoryBean.setPackagesToScan("com.bdqn.lyrk.ssh.study.entity"); Properties properties = new Properties(); properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); properties.setProperty("hibernate.show_sql", "true"); localSessionFactoryBean.setHibernateProperties(properties); return localSessionFactoryBean; } /** * 定义hibernate事务管理器 * @param localSessionFactoryBean * @return */ @Bean public HibernateTransactionManager transactionManager(@Autowired SessionFactory localSessionFactoryBean) { HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager(localSessionFactoryBean); return hibernateTransactionManager; } /** * 定义hibernateTemplate * @param localSessionFactoryBean * @return */ @Bean public HibernateTemplate hibernateTemplate(@Autowired SessionFactory localSessionFactoryBean) { HibernateTemplate hibernateTemplate = new HibernateTemplate(localSessionFactoryBean); return hibernateTemplate; } }
4.定义实体类
package com.bdqn.lyrk.ssh.study.entity; import javax.persistence.*; @Table(name = "student") @Entity public class StudentEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) @Id private Integer id; @Column(name = "stuName") private String stuName; @Column(name = "password") private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
5.定义service
package com.bdqn.lyrk.ssh.study.service; import com.bdqn.lyrk.ssh.study.entity.StudentEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate5.HibernateTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class StudentService { @Autowired private HibernateTemplate hibernateTemplate; @Transactional public int save(StudentEntity studentEntity){ hibernateTemplate.save(studentEntity); return studentEntity.getId(); } }
6.定义action 请大家留意关于struts2注解的注意事项
package com.bdqn.lyrk.ssh.study.action; import com.bdqn.lyrk.ssh.study.entity.StudentEntity; import com.bdqn.lyrk.ssh.study.service.StudentService; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; /** * struts2注解配置,注意: * 1.所在的包名必须以action结尾 * 2.Action要必须继承ActionSupport父类; * 3.添加struts2-convention-plugin-xxx.jar * * @author chen.nie * @date 2018/3/21 **/ @Scope("prototype") @ParentPackage("struts-default") //表示继承的父包 @Namespace(value = "/") //命名空间 public class IndexAction extends ActionSupport { @Autowired private StudentService studentService; @Action(value = "index", results = {@Result(name = "success", location = "/index.jsp")}) public String index() { StudentEntity studentEntity = new StudentEntity(); studentEntity.setStuName("test"); studentEntity.setPassword("123"); studentService.save(studentEntity); ActionContext.getContext().getContextMap().put("student", studentEntity); return com.opensymphony.xwork2.Action.SUCCESS; } }
7.index.jsp
<%-- Created by IntelliJ IDEA. User: chen.nie Date: 2018/3/21 Time: 下午6:55 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>ssh基于零配置文件整合</title> </head> <body> 新增的学生id为:${student.id} </body> </html>
启动tomcat,访问http://localhost:8080/index得到如下界面:
总结:前面我写过ssm基于注解零配置整合,那么ssh其思路也大体相同,主要是@Configuration @Bean等注解的使用,但是大家请留意的是struts2的注解与servlet的规范(脱离web.xml,手动添加servlet filter listener等)