SSH执行过程和配置详解
SSH架构是指 Struts2、Spring、Hibernate 这3个框架来搭建的项目。
SSH框架在稳定性与生产效率上获得了极佳的平衡,是目前比较流行的企业级开发架构。
其实三个框架的整合,就是将Hibernate的session创建交给Spring,将Struts2的Action交给Spring。
Struts2作用:主持交互;
Spring作用:管理组件间的依赖关系并提供事务管理等服务;
Hibernate作用:负责数据持久化;
SSH框架结构
- action,biz,dao之间的依赖
-
-
来自 <https://blog.****.net/jstxzhangrui/article/details/52825873>
-
-
以下是我自己配置成功的。
-
Web.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置ContextLoaderListener启动容器才能为其他框架提供服务-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--配置Spring的ContextLoaderListener监听器,初始化Spring容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--OpenSessionInViewFilter的过滤器,可以和前面提到的事务管理器HibernateDaoSupport很好的配合,其作用是把一个HibernateSession和一次完整的亲求过程绑定,在亲求开始时开启Session,
在请求开始时开启Session,请求结束时关闭Session。这使得在一次请求的完整周期中,所使用的HibernateSession是唯一的且一直保持开启的可用状态,解决了延迟加载等问题-->
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>/page/login.jsp</welcome-file>
</welcome-file-list>
</web-app>
resources里的配置
applicationContext.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scanbase-package="cn.houserent"/>
<!--定义dbcp数据源-->
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource">
<!--指定JDBC驱动类-->
<propertyname="driverClassName"value="oracle.jdbc.driver.OracleDriver"/>
<!--提供连接数据库的URL地址-->
<propertyname="url"value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--提供连接数据库的用户名和密码-->
<propertyname="username"value="scott"/>
<propertyname="password"value="123"/>
</bean>
<!--定义SessionFactoryBean-->
<beanid="sessionFactory"class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<!--!为AnnotationSessionFactoryBean注入定义好的数源-->
<propertyname="dataSource">
<refbean="dataSource"/>
</property>
<!--添加Hibernate配置参数-->
<propertyname="hibernateProperties">
<props>
<propkey="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect
</prop>
<propkey="hibernate.show_sql">true</prop>
<propkey="hibernate.format_sql">true</prop>
</props>
</property>
<!--添加对象关系映射文件所在路径-->
<propertyname="mappingDirectoryLocations">
<list>
<value>classpath:cn/houserent/entity/</value>
</list>
</property>
</bean>
<!--配置DAO-->
<!--<beanid="userDao"class="cn.houserent.dao.impl.UserDaoImpl">-->
<!--<propertyname="sessionFactory"ref="sessionFactory"/>-->
<!--</bean>-->
<!--配置业务层-->
<!--<beanid="userBiz"class="cn.houserent.service.impl.UserBizImpl">-->
<!--<propertyname="userDao"ref="userDao"></property>-->
<!--</bean>-->
<!--定义事务管理器-->
<beanid="txManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<propertyname="sessionFactory"ref="sessionFactory"/>
</bean>
<!--通过<tx:advice>标签定义事务增强,并指定事务管理器设置完事务规则还要定义切面,将事务规则应用到指定的方法上-->
<tx:adviceid="txAdvice"transaction-manager="txManager">
<!--定义事务属性,声明事务规则-->
<tx:attributes>
<tx:methodname="find*"read-only="true"/>
<tx:methodname="search*"read-only="true"/>
<tx:methodname="query*"read-only="true"/>
<tx:methodname="add*"propagation="REQUIRED"/>
<tx:methodname="register"propagation="REQUIRED"/>
<tx:methodname="del*"propagation="REQUIRED"/>
<tx:methodname="update*"propagation="REQUIRED"/>
<tx:methodname="do*"propagation="REQUIRED"/>
<tx:methodname="*"propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--定义切面-->
<aop:config>
<!--定义切入点-->
<aop:pointcutid="serviceMethod"expression="execution(*cn.houserent.service..*.*(..))"/>
<!--将事务增强与切入点组合-->
<aop:advisoradvice-ref="txAdvice"pointcut-ref="serviceMethod"/>
</aop:config>
</beans>
hibernate.cfg.xml
<?xmlversion='1.0'encoding='utf-8'?>
<!DOCTYPEhibernate-configurationPUBLIC
"-//Hibernate/HibernateConfigurationDTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--数据库URL-->
<propertyname="connection.url">jdbc:oracle:thin:@localhost:1521:ORCL</property>
<!--数据库用户-->
<propertyname="connection.username">scott</property>
<!--数据库用户密码-->
<propertyname="connection.password">123</property>
<!--数据库JDBC驱动-->
<propertyname="connection.driver_class">oracle.jdbc.OracleDriver</property>
<!--每个数据库都有其对应的方言(Dialect)以匹配其平台特性-->
<propertyname="dialect">
org.hibernate.dialect.Oracle10gDialect
</property>
<!--指定当前session范围和上下文-->
<propertyname="current_session_context_class">thread</property>
<!--是否将运行期生成的SQL输出到日志以供调试-->
<propertyname="show_sql">true</property>
<!--是否格式化-->
<propertyname="format_sql">true</property>
<mappingresource="cn/houserent/entity/District.hbm.xml"/>
<mappingresource="cn/houserent/entity/House.hbm.xml"/>
<mappingresource="cn/houserent/entity/Type.hbm.xml"/>
<mappingresource="cn/houserent/entity/User.hbm.xml"/>
<mappingresource="cn/houserent/entity/Street.hbm.xml"/>
<!--映射文件配置,注意文件名必须包含其相对于classpath的全路径-->
</session-factory>
</hibernate-configuration>
struts.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constantname="struts.ui.theme"value="simple"/>
<constantname="struts.i18n.encoding"value="UTF-8"/>
<!--<constantname="struts.enable.DynamicMethodInvocation"value="true"/>-->
<packagename="default"namespace="/"extends="struts-default">
<interceptors>
<interceptorname="myAuthorization"class="cn.houserent.interceptor.AuthorizationInterceptor">
</interceptor>
<interceptor-stackname="myStack">
<interceptor-refname="myAuthorization">
</interceptor-ref>
<interceptor-refname="defaultStack"/>
</interceptor-stack>
</interceptors>
<!--定义默认的拦截器-->
<default-interceptor-refname="myStack"/>
<!--默认的action-->
<default-action-refname="defaultAction"/>
<!--通用的result结果-->
<global-results>
<resultname="error">/error.jsp</result>
<resultname="403">/403.jsp</result>
<resultname="login"type="redirect">/page/login.jsp</result>
</global-results>
<actionname="defaultAction">
<result>/404.jsp</result>
</action>
<actionname="*Action"class="cn.houserent.action.UserAction"method="{1}">
<resultname="success"type="redirectAction">${nextDispose}</result>
<resultname="input">/page/{1}.jsp</result>
</action>
<!--<actionname="house"class="cn.houserent.action.HouseAction">-->
<!--<resultname="success">/page/house_list.jsp</result>-->
<!--</action>-->
<actionname="add"class="cn.houserent.action.AddAction">
<resultname="success"type="redirectAction">manager</result>
<resultname="input">/page/add.jsp</result>
</action>
<actionname="defaultAction">
<result>/page/error.jsp</result>
</action>
<actionname="common"class="cn.houserent.action.HouseAction">
<resultname="success">/page/house_list.jsp</result>
</action>
<actionname="manager"class="cn.houserent.action.HouseAction">
<resultname="success">/page/manage.jsp</result>
</action>
<actionname="search"class="cn.houserent.action.HouseAction"method="lookup">
<resultname="success">/page/house_list.jsp</result>
<resultname="manager">/page/manage.jsp</result>
<resultname="error">/page/fail.jsp</result>
</action>
<actionname="show"class="cn.houserent.action.DetailAction">
<resultname="success">/page/show.jsp</result>
<resultname="error">/page/fail.jsp</result>
</action>
<actionname="downFile"class="cn.houserent.action.AddAction"method="downFile">
<resultname="success"type="stream">
/page/show.jsp
<paramname="bufferSize">1024</param>
<paramname="contentDisposition">attachment;filename=${fileName}</param>
<paramname="inputStream">inputStream</param>
</result>
<resultname="error">/page/fail.jsp</result>
</action>
</package>
<!--<packagename="user"namespace="/user"extends="struts-default">
<actionname="list"class="cn.houserent.action.UserAction">
<resultname="success">/userlist.jsp</result>
</action>
</package>-->
</struts>
message.properties
xwork.default.invalid.fieldvalue=字段"{0}"的值无效
xwork-conversion.properties
java.util.Date=cn.houserent.util.DateConverter
log4j.properties 日志
log4j.rootLogger=info,CONSOLE,file
#log4j.rootLogger=ERROR,ROLLING_FILE
log4j.logger.cn.houserent=info
log4j.logger.org.apache.ibatis=info
log4j.logger.org.mybatis.spring=info
log4j.logger.java.sql.Connection=info
log4j.logger.java.sql.Statement=info
log4j.logger.java.sql.PreparedStatement=info
log4j.logger.java.sql.ResultSet=info
######################################################################################
#ConsoleAppender\u65e5\u5fd7\u5728\u63a7\u5236\u8f93\u51fa\u914d\u7f6e
######################################################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=info
log4j.appender.CONSOLE.DatePattern=yyyy-MM-dd
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=-(%rms)-%d{yyyy-M-dHH:mm:ss}%x[%5p](%F:%L)%m%n
######################################################################################
#RollingFile\u6587\u4ef6\u5927\u5c0f\u5230\u8fbe\u6307\u5b9a\u5c3a\u5bf8\u7684\u65f6\u5019\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6
######################################################################################
#log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
#log4j.appender.ROLLING_FILE.Threshold=INFO
#log4j.appender.ROLLING_FILE.File=${baojia.root}/logs/log.log
#log4j.appender.ROLLING_FILE.Append=true
#log4j.appender.ROLLING_FILE.MaxFileSize=5000KB
#log4j.appender.ROLLING_FILE.MaxBackupIndex=100
#log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
#log4j.appender.ROLLING_FILE.layout.ConversionPattern=%d{yyyy-M-dHH:mm:ss}%x[%5p](%F:%L)%m%n
######################################################################################
#DailyRollingFile\u6bcf\u5929\u4ea7\u751f\u4e00\u4e2a\u65e5\u5fd7\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u683c\u5f0f:log2009-09-11
######################################################################################
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern=yyyy-MM-dd
log4j.appender.file.File=${AppInfoSystem.root}/logs/log.log
log4j.appender.file.Append=true
log4j.appender.file.Threshold=info
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=-(%rms)-%d{yyyy-M-dHH:mm:ss}%x[%5p](%F:%L)%m%n
#DWR\u65e5\u5fd7
#log4j.logger.org.directwebremoting=ERROR
#\u663e\u793aHibernate\u5360\u4f4d\u7b26\u7ed1\u5b9a\u503c\u53ca\u8fd4\u56de\u503c
#log4j.logger.org.hibernate.type=DEBUG,CONSOLE
#log4j.logger.org.springframework.transaction=DEBUG
#log4j.logger.org.hibernate=DEBUG
#log4j.logger.org.acegisecurity=DEBUG
#log4j.logger.org.apache.myfaces=TRACE
#log4j.logger.org.quartz=DEBUG
#log4j.logger.com.opensymphony=INFO
#log4j.logger.org.apache.struts2=DEBUG
log4j.logger.com.opensymphony.xwork2=info
cn.houserent.interceptor 代码中的拦截类
AuthorizationInterceptor
packagecn.houserent.interceptor;
importcn.houserent.entity.User;
importcom.opensymphony.xwork2.Action;
importcom.opensymphony.xwork2.ActionInvocation;
importcom.opensymphony.xwork2.interceptor.AbstractInterceptor;
importorg.apache.struts2.ServletActionContext;
importjava.util.Map;
publicclassAuthorizationInterceptorextendsAbstractInterceptor{
publicStringintercept(ActionInvocationactionInvocation)throwsException{
StringtheName=actionInvocation.getInvocationContext().getName();
if(theName.equals("loginAction")){
returnactionInvocation.invoke();
}
//获取用户会话信息
Mapsession=actionInvocation.getInvocationContext().getSession();
Useruser=(User)session.get("user");
if(user==null){
//终止执行,返回登录页面
returnAction.LOGIN;
}else{
Stringuri=ServletActionContext.getRequest().getRequestURI();
if(user.getIsadmin()=="0"&&uri.endsWith("manage.jsp")){
return"403";//跳转权限不够
}
//继续执行剩余的拦截器和Action
returnactionInvocation.invoke();
}
}
}
-
jar包 配置
<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yunfan</groupId>
<artifactId>ch12_sl</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!--https://mvnrepository.com/artifact/antlr/antlr-->
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>2.7.6</version>
</dependency>
<!--https://mvnrepository.com/artifact/aopalliance/aopalliance-->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.aspectj/aspectjweaver-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.9</version>
</dependency>
<!--https://mvnrepository.com/artifact/commons-collections/commons-collections-->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<!--https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp-->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!--https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!--https://mvnrepository.com/artifact/commons-lang/commons-lang-->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.apache.commons/commons-lang3-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<!--https://mvnrepository.com/artifact/commons-logging/commons-logging-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!--https://mvnrepository.com/artifact/commons-pool/commons-pool-->
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
<!--https://mvnrepository.com/artifact/dom4j/dom4j-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!--https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.2.3</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.freemarker/freemarker-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.19</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.0-api-->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<!--https://mvnrepository.com/artifact/javassist/javassist-->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.0.GA</version>
</dependency>
<!--https://mvnrepository.com/artifact/javax.transaction/jta-->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<!--https://mvnrepository.com/artifact/log4j/log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.10.Final</version>
</dependency>
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.0.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.slf4j/slf4j-api-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-aop-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-beans-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-core-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-expression-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-orm-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-tx-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework/spring-web-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.13.RELEASE</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.apache.struts/struts2-core-->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.16.3</version>
</dependency>
<!--https://mvnrepository.com/artifact/javassist/javassist 这个包可能下不到,到网上去下一个-->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.apache.struts.xwork/xwork-core-->
<dependency>
<groupId>org.apache.struts.xwork</groupId>
<artifactId>xwork-core</artifactId>
<version>2.3.16.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--https://mvnrepository.com/artifact/org.apache.struts/struts2-spring-plugin-->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.3.16.3</version>
</dependency>
<!--https://mvnrepository.com/artifact/javax.servlet/jstl-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>