Struts2-Convention-Plugin: Pom - XML

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 12

Pom.

xml

1) struts2-convention-plugin

The Convention Plugin is bundled with Struts since 2.1 and replaces the Codebehind Plugin and
Zero Config plugins. It provides the following features:

 Action location by package naming conventions


 Result (JSP, FreeMarker, etc) location by naming conventions
 Class name to URL naming convention
 Package name to namespace convention
 SEO compliant URLs (i.e. my-action rather than MyAction)
 Action name overrides using annotations
 Interceptor overrides using annotations
 Namespace overrides using annotations
 XWork package overrides using annotations
 Default action and result handling (i.e. /products will
try com.example.actions.Products as well as com.example.actions.products.Index)

The Convention Plugin should require no configuration to use. Many of the conventions can be
controlled using configuration properties and many of the classes can be extended or overridden.

Convention plugin is able to find our action classes. By default, the Convention plugin will find
all action classes that implement com.opensymphony.xwork2.Action or whose name ends with
the word Action in specific packages.

These packages are located by the Convention plugin using a search methodology. First the
Convention plugin finds packages named struts, struts2, action or actions. Any packages that
match those names are considered the root packages for the Convention plugin. Next, the plugin
looks at all of the classes in those packages as well as sub-packages and determines if the classes
implement com.opensymphony.xwork2.Action or if their name ends
with Action (i.e. FooAction).
How does Spring and Struts integration work?

struts2-spring-plugin-VERSION.jar :

Features

 Allow Actions, Interceptors, and Results to be created by Spring


 Struts-created objects can be autowired by Spring after creation
 Provides two interceptors that autowire actions, if not using the Spring ObjectFactory

The Struts 2 framework provides a plugin called Spring Plugin that enables Spring integration.
This plugin is provided in a jar file named struts2-spring-plugin-VERSION.jar. So remember
to include this jar file in your application (we will tell you the Maven artifacts later).

With Spring plugin enabled, Spring manages all Struts’ action classes as well as other beans
(business classed, DAO classes, etc) via its inversion of control container (declared in Spring’s
application context configuration file).

Configuring Spring and Struts in web.xml

Now, we come to the most interesting part that makes Spring and Struts 2 working together by
configuring these two frameworks in the web deployment descriptor file (web.xml):

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appContext.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
<filter-name>DispatcherFilter</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-
class>
</filter>

<filter-mapping>
<filter-name>DispatcherFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Here, we configure our web application to load Spring and Struts differently:
 Spring is loaded as a listener class when the application is started. Spring will load
configuration from a file named appContext.xml under the /WEB/INF/spring directory.
 Struts 2 is loaded as a filter which intercepts all requests coming through the application.

This configuration is reasonable in case of our application: Spring acts as the dependency
container and Struts acts as the MVC framework.

Enabling Spring integration for other application objects is a two-step process.

1. Configure the Spring listener

web.xml

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

2. Register your objects via the Spring configuration

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframewo
rk.org/dtd/spring-beans.dtd">
<beans default-autowire="autodetect">
<bean id="personManager" class="com.acme.PersonManager" scope="prototype"/>
...
</beans>

More applicationContext configuration files needed?

Since the Spring integration uses a standard Listener, it can be configured to support
configuration files other than applicationContext.xml. Adding the following to your web.xml
will cause Spring’s ApplicationContext to be inititalized from all files matching the given
pattern:

<!-- Context Configuration locations for Spring XML files -->


<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</p
aram-value>
</context-param>

See the Spring documentation for a full description of this parameter.


Web.xml:

ContextLoaderListener -

1. Listens during server start up/shutdown


2. Takes the Spring configuration files as input and creates the beans as per configuration and
make it ready (destroys the bean during shutdown)
3. Configuration files can be provided like this in web.xml
4. <param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>

applicationContext.xml

1) Enable annotation
<task:annotation-driven />
2) Configure rest web services

<jaxrs:server id="restServer" address="/rest/">


<jaxrs:serviceBeans>
<ref bean="qasAddressService"/>
<ref bean="connectionService" />
<ref bean="orgServiceImpl" />
<ref bean="userServiceImpl" />
<ref bean="permissionServiceImpl" />
<ref bean="roleServiceImpl" />
<ref bean="studentServiceImpl" />
<ref bean="testServiceImpl" />
<ref bean="jobServiceImpl" />
<ref bean="serviceObjectServiceImpl" />
<ref bean="studentGroupServiceImpl" />
<ref bean="studentTestServiceImpl" />
<ref bean="tellService" />
<ref bean="tellReportsService" />
<ref bean="sessionWebService" />
<ref bean="subscriptionWebService" />
<ref bean="proctorsWebService" />
<ref bean="atpOperationalReportServiceImpl" />
<ref bean="atpOwatonnaWebService" />
<ref bean="tellJsonService" />
<ref bean="nnat3Service"/>
<ref bean="testNavRegistrationServiceImpl"/>
<ref bean="orderWebService"/>
<ref bean="localNormsJsonService"/>
<ref bean="scoreService"/>
<ref bean="StudentSessionWebService"/>
<ref bean="samlService"/>
</jaxrs:serviceBeans>

<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider">
<property name="mapper">
<bean class="com.fasterxml.jackson.datatype.joda.JodaMapper"/>
</property>
</bean>
<bean class="com.pearson.core.ws.rs.HTTPCacheResponseFilter" />
<ref bean="constraintViolationExceptionMapper" />
</jaxrs:providers>
<jaxrs:extensionMappings>
<entry key="feed" value="application/atom+xml" />
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
<entry key="html" value="text/html" />
</jaxrs:extensionMappings>

</jaxrs:server>
Transaction management:

1) Instantiatate the bean for transactin management in daoContext.xml

<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
<qualifier value="core"/>
</bean>

This bean consist of 2 major properties:

1) entityManagerFactory
2) dataSource

1)entityManagerFactory :

It is a instance of LocalContainerEntityManagerFactoryBean

This is the most powerful way to set


* up a shared JPA EntityManagerFactory in a Spring application context;
* the EntityManagerFactory can then be passed to JPA-based DAOs via
* dependency injection.

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="core" />
<property name="packagesToScan">
<list>
<value>com.pearson.core</value>
<value>com.pearson.session</value>
<value>com.pearson.orders</value>
<value>com.pearson.supportcms</value>
<value>com.pearson.config</value>
<value>com.pearson.ease</value>
<value>com.pearson.reporting</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.
HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="databasePlatform"
value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.cache.region.factory_class"
value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFac
tory" />
<entry key="hibernate.cache.use_query_cache" value="false" />
<entry key="hibernate.cache.use_second_level_cache">
<value>${cache.second.level}</value>
</entry>
<entry key="hibernate.generate_statistics" value="true" />
<entry key="net.sf.ehcache.configurationResourceName">
<value>/META-INF/ehcache-
${cache.config}.xml</value>
</entry>
<entry key="javax.persistence.validation.mode" value="none" />
<entry key="hibernate.ejb.interceptor"
value="com.pearson.core.audittrail.AuditTrailInterceptor">
</entry>
<entry key="hibernate.default_batch_fetch_size"
value="30" />
<entry key="hibernate.jdbc.batch_size" value="30" />
<entry key="hibernate.order_inserts" value="true" />
<entry key="hibernate.order_updates" value="true" />
<entry key="hibernate.jdbc.batch_versioned_data" value="true"
/>
</map>
</property>
</bean>

3) datasource :
<jee:jndi-lookup id="dataSource" jndi-name="core_connection" expected-
type="javax.sql.DataSource" />
It looks up for data source in servers file. In our case context.xml

The persistence context is in JPA the EntityManager, implemented internally using an


Hibernate Session (when using Hibernate as the persistence provider).

The persistence context is just a synchronizer object that tracks the state of a limited set of Java
objects and makes sure that changes on those objects are eventually persisted back into the
database.
This is a very different notion than the one of a database transaction. One Entity Manager can be
used across several database transactions, and it actually often is.
For target beans annotated with @Transactional, Spring will create a TransactionInterceptor, and
pass it to the generated proxy object. So when you call the method from client code, you're
calling the method on the proxy object, which first invokes the TransactionInterceptor (which
begins a transaction), which in turn invokes the method on your target bean. When the
invocation finishes, the TransactionInterceptor commits/rolls back the transaction. It's
transparent to the client code.

As for the "external method" thing, if your bean invokes one of its own methods, then it will not
be doing so via the proxy. Remember, Spring wraps your bean in the proxy, your bean has no
knowledge of it. Only calls from "outside" your bean go through the proxy.

NOTE: Since this mechanism is based on proxies, only 'external' method calls coming in
through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the
target object calling some other method of the target object, won't lead to an actual transaction
at runtime even if the invoked method is marked with @Transactional!
Spring hibernate configuration
LocalContainerEntityManagerFactoryBean is responsible for communication between
Spring and hibernate
Following properties needs to set:
1) dataSource
2) persistenceUnitName
3) packagesToScan
4) jpaVendorAdapter
a. HibernateJpaVendorAdapter bean
i. showSql
ii. generateDdl
iii. databasePlatform
5) jpaPropertyMap
a. hibernate.cache.region.factory_class
b. hibernate.cache.use_query_cache
c. hibernate.cache.use_second_level_cache
d. net.sf.ehcache.configurationResourceName
e. "hibernate.ejb.interceptor

<bean id="sessionFactory" factory-bean="entityManagerFactory" factory-


method="getSessionFactory" />

This will allow the injection of Entity Manager proxies via the persistence context annotation:

@Configuration
public class EntityManagerFactoriesConfiguration {
@Autowired
private DataSource dataSource;

@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean emf() {
LocalContainerEntityManagerFactoryBean emf = ...
emf.setDataSource(dataSource);
emf.setPackagesToScan(new String[] {"your.package"});
emf.setJpaVendorAdapter(
new HibernateJpaVendorAdapter());
return emf;
}
}

The next step is to configure the Transaction Manager and to apply the Transactional Aspect
in @Transactional annotated classes:

@Configuration
@EnableTransactionManagement
public class TransactionManagersConfig {
@Autowired
EntityManagerFactory emf;
@Autowired
private DataSource dataSource;

@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(emf);
tm.setDataSource(dataSource);
return tm;
}
}

The annotation @EnableTransactionManagement tells Spring that classes with


the @Transactional annotation should be wrapped with the Transactional Aspect. With this
the @Transactional is now ready to be used.

You might also like