entitymanger return null when putting in generic dao - seam

I am using seam with tomcate and icefaces the problem is when I inject entity manager in component bean it works well but if put it in generic DAO it returns null my code is like that:
this the bean
#Scope(ScopeType.PAGE)
#Name("TestBean")
public class TestBean {
public void test(ActionEvent actionEvent) {
Roles entity = new Roles();
entity.setName("cons");
RolesDao dao = new RolesDao();
dao.emPrisit(entity);
}
}
DAO
public class RolesDao {
#In
EntityManager em;
public void emPrisit(Roles entity) {
em.persist(entity);
}
}
Component.xml
<persistence:entity-manager-factory name="bookingDatabase"/>
<persistence:managed-persistence-context name="em"
auto-create="true"
entity-manager-factory="#{bookingDatabase}"/>
persistence.xml
<persistence-unit name="bookingDatabase"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence </provider>
<jta-data-source>java:comp/env/AP</jta-data-source>
<properties>
<property name="transaction.flush_before_completion" value="true" />
<property name="transaction.factory_class"
value="org.hibernate.transaction.JDBCTransactionFactory" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<!--
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
-->
</properties>
</persistence-unit>
if I inject entitymanger in bean not dao it runs well the second problem when I add this annotation before entitymanger
#In
#PersistenceContext(type = PersistenceContextType.EXTENDED)
EntityManager em;
it give this exception
caused by: java.lang.IllegalArgumentException: #PersistenceContext may only be used on session bean or message driven bean components: TestBean
at org.jboss.seam.Component.checkPersistenceContextForComponentType(Component.java:901)
at org.jboss.seam.Component.scanField(Component.java:877)
at org.jboss.seam.Component.initMembers(Component.java:557)
at org.jboss.seam.Component.<init>(Component.java:244)
at org.jboss.seam.Component.<init>(Component.java:205)
at org.jboss.seam.init.Initialization.addComponent(Initialization.java:1186)
... 13 more

You don't need both #In and #PersistenceContext on your EntityManager. It is enough with one of them.

Injection only occurs in Beans, so your DAO should have a #Name("something"), otherwise Seam doesn't knows what to do with your class.
#Name("RolesDao")
public class RolesDao {
#In
EntityManager em;
public void emPrisit(Roles entity) {
em.persist(entity);
}
}
Then to use this class you should either do:
#In(value="RolesDao") // value="..." is optional
private RolesDao rolesDao;
or
org.jboss.seam.Component.getInstance(RolesDao.class)
Sorry if the sample code has some errors, didn't had eclipse to try it.
Hope this helps

Related

SPRING MVC - Error with autowired beans

I have this maven project with its modules
Parent
|_____Model
|_____Persistence
|_____Service
|_ service-context.xml
|_____View
|_ spring/app-config.xml
I have this controller
controllers.HomeController in the View module
#Controller
public class HomeController {
protected final Log logger = LogFactory.getLog(getClass());
private IServicioService servicioService;
#RequestMapping(value="/home.htm")
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
logger.info("Returning hello view");
return new ModelAndView("home.jsp");
}
#Autowired
public void setServicioService(IServicioService servicioService) {
this.servicioService = servicioService;
}
And my service servicios.ServicioService in the services module
#Service
public class ServicioService implements IServicioService{
private ServicioDao servicioDao;
public ServicioService(){}
/*************************** Gett&Sett ****************************/
public ServicioDao getServicioDao() {
return servicioDao;
}
public void setServicioDao(ServicioDao servicioDao) {
this.servicioDao = servicioDao;
}
}
The IServicioService hasnt a #Service
The ServicioService bean is defined in service-context.xml like this
<bean id="servicioService" class="servicios.ServicioService">
<property name="servicioDao" ref="servicioDao" />
</bean>
**And my app-config.xml is importing the service-context.xml **
<import resource="classpath*:service-context.xml" />
<context:component-scan base-package="controllers" />
Idk why is giving me this
No matching bean of type [servicios.ServicioService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
Help!!
Your problem probably lies inside of xml configuration.
Try adding in your app-config.xml line:
<context:component-scan base-package="servicios" />
After that you should do the same with your daos

MockMVC Integrate test controller with session scoped bean

I am trying to integrate test a Spring Controller method that uses a spring session scoped bean which is injected into the controller. In order for my test to pass I must be able to access my session bean to set some values on it before I make my mock call to this controller method. Issue is a new session bean is created when I make the call instead of using the one I pulled of the mock application context. How can I make my controller use the same UserSession bean?
Here is my test case
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration("src/main/webapp")
#ContextConfiguration({"file:src/main/webapp/WEB-INF/applicationContext.xml",
"file:src/main/webapp/WEB-INF/rest-servlet.xml",
"file:src/main/webapp/WEB-INF/servlet-context.xml"})
public class RoleControllerIntegrationTest {
#Autowired
private WebApplicationContext wac;
protected MockMvc mockMvc;
protected MockHttpSession mockSession;
#BeforeClass
public static void setupClass(){
System.setProperty("runtime.environment","TEST");
System.setProperty("com.example.UseSharedLocal","true");
System.setProperty("com.example.OverridePath","src\\test\\resources\\properties");
System.setProperty("JBHSECUREDIR","C:\\ProgramData\\JBHSecure");
}
#Before
public void setup(){
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
mockSession = new MockHttpSession(wac.getServletContext(), UUID.randomUUID().toString());
mockSession.setAttribute("jbhSecurityUserId", "TESTUSER");
}
#Test
public void testSaveUserRole() throws Exception {
UserSession userSession = wac.getBean(UserSession.class);
userSession.setUserType(UserType.EMPLOYEE);
userSession.setAuthorizationLevel(3);
Role saveRole = RoleBuilder.buildDefaultRole();
Gson gson = new Gson();
String json = gson.toJson(saveRole);
MvcResult result = this.mockMvc.perform(
post("/role/save")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
.session(mockSession))
.andExpect(status().isOk())
.andReturn();
MockHttpServletResponse response = result.getResponse();
}
Here is my controller method I am needing tested
#Resource(name="userSession")
private UserSession userSession;
#RequestMapping(method = RequestMethod.POST, value = "/save")
public #ResponseBody ServiceResponse<Role> saveRole(#RequestBody Role role,HttpSession session){
if(userSession.isEmployee() && userSession.getAuthorizationLevel() >= 3){
try {
RoleDTO savedRole = roleService.saveRole(role,ComFunc.getUserId(session));
CompanyDTO company = userSession.getCurrentCompany();
It is not passing this line because the UserSession Object is not the same
if(userSession.isEmployee() && userSession.getAuthorizationLevel() >= 3){
This is the declaration of my user session bean.
#Component("userSession")
#Scope(value="session",proxyMode= ScopedProxyMode.INTERFACES)
public class UserSessionImpl implements UserSession, Serializable {
private static final long serialVersionUID = 1L;
Both controlle and bean are created using component scan in my applicationContext.xml
<context:annotation-config />
<!-- Activates various annotations to be detected in bean classes -->
<context:component-scan
base-package="
com.example.app.externalusersecurity.bean,
com.example.app.externalusersecurity.service,
com.example.app.externalusersecurity.wsc"/>
<mvc:annotation-driven />
Add the following bean configuration, which adds a session context for each thread
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="session">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
An equivalent in Java's configuration class would the following bean declaration
#Bean
public CustomScopeConfigurer scopeConfigurer() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
Map<String, Object> workflowScope = new HashMap<String, Object>();
workflowScope.put("session", new SimpleThreadScope());
configurer.setScopes(workflowScope);
return configurer;
}
For more details, see
http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-custom-using
Using different Bean definition profiles for test and production worked for me - here's how a XML based setup could look like:
<beans profile="production">
<bean id="userSession" class="UserSessionImpl" scope="session" >
<aop:scoped-proxy/>
</bean>
</beans>
<beans profile="test">
<bean id="userSession" class="UserSessionImpl" >
</bean>
</beans>
To use the test profile for your test, add #ActiveProfiles to your test class:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration("src/main/webapp")
#ContextConfiguration({"file:src/main/webapp/WEB-INF/applicationContext.xml",
"file:src/main/webapp/WEB-INF/rest-servlet.xml",
"file:src/main/webapp/WEB-INF/servlet-context.xml"})
#ActiveProfiles(profiles = {"test"})
public class RoleControllerIntegrationTest {
[...]

consuming a web service - JaxWsPortProxyFactoryBean or Controller not configured right

Java 1.7
Spring 3.1.1 with Spring-WS 2.1.1
Joda
Hibernate 3.6
MySQL 5.0.57
Maven 3
Tomcat 7
Eclipse 3.7
So the SOAP web service is up and running.
And my standalone Java app can access it.
Now I'm trying to build a Spring MVC web client to access it. So by my way of thinking I can just replace the standard webapp's service layer with the web service endpoint .
Patterning after this
http://ankeetmaini.wordpress.com/2013/03/04/jax-ws-client-consuming-the-jax-ws-webservice
after switching his naming conventions to be more canonical I wound up with
FormsEndpointImplService
#WebServiceClient(name = "FormsEndpointImplService",
wsdlLocation = "http://localhost:8080/dept_forms_webservice/formsService?wsdl",
targetNamespace = "http://endpoint.web.forms.azdeq.gov/")
public class FormsEndpointImplService extends Service
{
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://endpoint.web.forms.azdeq.gov/", "FormsEndpointImplService");
public final static QName FormsEndpointImplPort = new QName("http://endpoint.web.forms.azdeq.gov/", "FormsEndpointImplPort");
static {
URL url = null;
try {
url = new URL("http://localhost:8080/dept_forms_webservice/formsService?wsdl");
} catch (MalformedURLException e) {
java.util.logging.Logger.getLogger(FormsEndpointImplService.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "http://localhost:8080/dept_forms_webservice/formsService?wsdl");
}
WSDL_LOCATION = url;
}
public FormsEndpointImplService(URL wsdlLocation) {
super(wsdlLocation, SERVICE);
}
public FormsEndpointImplService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public FormsEndpointImplService() {
super(WSDL_LOCATION, SERVICE);
}
//This constructor requires JAX-WS API 2.2. You will need to endorse the 2.2
//API jar or re-run wsdl2java with "-frontend jaxws21" to generate JAX-WS 2.1
//compliant code instead.
public FormsEndpointImplService(WebServiceFeature ... features) {
super(WSDL_LOCATION, SERVICE, features);
}
//This constructor requires JAX-WS API 2.2. You will need to endorse the 2.2
//API jar or re-run wsdl2java with "-frontend jaxws21" to generate JAX-WS 2.1
//compliant code instead.
public FormsEndpointImplService(URL wsdlLocation, WebServiceFeature ... features) {
super(wsdlLocation, SERVICE, features);
}
//This constructor requires JAX-WS API 2.2. You will need to endorse the 2.2
//API jar or re-run wsdl2java with "-frontend jaxws21" to generate JAX-WS 2.1
//compliant code instead.
public FormsEndpointImplService(URL wsdlLocation, QName serviceName, WebServiceFeature ... features) {
super(wsdlLocation, serviceName, features);
}
/**
*
* #return
* returns FormsEndpoint
*/
#WebEndpoint(name = "FormsEndpointImplPort")
public FormsEndpoint getFormsEndpointImplPort() {
return super.getPort(FormsEndpointImplPort, FormsEndpoint.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* #return
* returns FormsEndpoint
*/
#WebEndpoint(name = "FormsEndpointImplPort")
public FormsEndpoint getFormsEndpointImplPort(WebServiceFeature... features) {
return super.getPort(FormsEndpointImplPort, FormsEndpoint.class, features);
}
}
FormsEndpoint ( the SEI )
#WebService(targetNamespace = "http://endpoint.web.forms.azdeq.gov/", name = "FormsEndpoint")
#XmlSeeAlso({ObjectFactory.class})
public interface FormsEndpoint
{
#RequestWrapper(localName = "insertCompletedForm", targetNamespace = "http://endpoint.web.forms.azdeq.gov/", className = "gov.azdeq.forms.web.endpoint.InsertCompletedForm")
#WebMethod
#ResponseWrapper(localName = "insertCompletedFormResponse", targetNamespace = "http://endpoint.web.forms.azdeq.gov/", className = "gov.azdeq.forms.web.endpoint.InsertCompletedFormResponse")
public void insertCompletedForm(
#WebParam(name = "arg0", targetNamespace = "")
gov.azdeq.forms.web.endpoint.CompletedForm arg0
);
....
}
and my servlet-context.xml
...
<bean id="formsWebServiceProxy" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="wsdlDocumentUrl" value="http://localhost:8080/dept_forms_webservice/formsService?wsdl"/>
<property name="serviceInterface" value="gov.azdeq.forms.web.endpoint.FormsEndpoint"/>
<property name="serviceName" value="FormsEndpointImplService"/>
<property name="portName" value="FormsEndpointImplPort"/>
<property name="namespaceUri" value="http://endpoint.web.forms.azdeq.gov/"/>
<!-- <property name="endpointAddress" value="http://endpoint.web.forms.azdeq.gov/" /> -->
</bean>
<bean id="baseController" class="gov.azdeq.forms.web.controller.BaseController">
<property name="service" ref="formsWebServiceProxy" />
</bean>
...
and Base Controller
#RequestMapping
#Controller
public class BaseController
{
private static final Logger logger = Logger.getLogger( BaseController.class);
#Resource
FormsEndpoint service; // should come in from bean
...
}
So this all compiles and deploys to Tomcat just fine.
But when I click on dept_forms_webclient in localhost:8080/manager it throws this:
org.springframework.beans.NotWritablePropertyException: Invalid property 'service' of bean class [gov.azdeq.forms.web.controller.BaseController]: Bean property 'service' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Seems like the proxy bean is being injected ok, it seems like I should not be setting it to FormsEndpoint regardless of what various tuts say.
So, more configuration confusion, can anyone spot what's wrong here?
TIA,
Still-learning Stev
I got it all working by losing the dependency-injection in the context file and using #Autowired in the controller like so:
<!-- controllers -->
<bean id="baseController" class="gov.azdeq.forms.web.controller.BaseController" />
and
#RequestMapping
#Controller("baseController")
public class BaseController
{
#Autowired
#Resource(name="formsWebServicePortProxy")
FormsEndpoint formsWebServicePortProxy;
Not sure why using #Autowired works but manual property injection does not. Huh.
Thanks to all who replied, it did give me a bit of insight.
CASE CLOSED
Still-learning Steve

Issue on implementing jdbc dao support in spring application

I was trying to access database using jdbcdao as per the following example:
http://www.mkyong.com/spring/spring-jdbctemplate-jdbcdaosupport-examples/
userdao, userdaoimpl,daocontext and datacontext.xml are as follows:
DAOIMPL
public class UserDAOImpl extends JdbcDaoSupport implements UserDAO {
/*Creates User */
public void insertUser(User user){
String sql = "INSERT INTO Users " +
"(id, username, password,role) VALUES (?, ?, ?,?)";
getJdbcTemplate().update(sql, new Object[] { user.getUserId(),
user.getUserName(),user.getPassWord()
});
}
}
DAO
import java.util.List;
import spring.web.models.User;
public interface UserDAO {
public void insertUser(User user);
}
DAOCONTEXT.XML
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="userDAO" class="spring.web.dao.impl.UserDAOImpl">
<property name="primaryDataSource" ref="oracleDataSource" />
</bean>
</beans>
DATA-CONTEXT.XML
<?xml version="1.0"?>
<beans
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans">
<bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property value="oracle.jdbc.OracleDriver" name="driverClassName" />
<property value="jdbc:oracle:thin:#192.168.72.68:1521:d2he"
name="url" />
<property value="aaryal_1" name="username" />
<property value="oracle" name="password" />
</bean>
</beans>
The error I am facing is as follows:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDAO' defined in class path resource [dao-context.xml]:
Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException:
Invalid property 'primaryDataSource' of bean class [spring.web.dao.impl.UserDAOImpl]:
Bean property 'primaryDataSource' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the getter?
Please suggest me what did I miss.
You need a setPrimaryDataSource method in UserDAOImpl class. The error says it all. It's expecting a property called primaryDataSource in your class, but can't find it. Hence the error.
You'll need to do this:
private DataSource dataSource;
public void setPrimaryDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
EDIT:
If you go through the API of JdbcDaoSupport, the setDataSource method already exists. So to solve your error, you can either do the above, or simply rename your DataSource bean name to dataSource

Spring Security without web.xml

What is the recommended way to add Spring Security to a web application that is using Spring's new WebApplicationInitializer interface instead of the web.xml file? I'm looking for the equivalent of:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
UPDATE
The provided answers are reasonable but they both assume that I've got a servletContext instance. I've looked through the hierarchy of WebApplicationInitializers and I don't see any access to the servlet context unless I choose to override one of Spring's initializer methods. AbstractDispatcherServletInitializer.registerServletFilter seems like the sensible choice but it doesn't default to URL pattern mapping and I'd hate to change filter registration for everything if there is a better way.
This is the way that I have done it:
container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
container is an instance of ServletContext
The Spring Security Reference answers this question and the solution depends on whether or not you are using Spring Security in conjunction with Spring or Spring MVC.
Using Spring Security without Spring or Spring MVC
If you are not using Spring Security with Spring or Spring MVC (i.e. you do not have an existing WebApplicationInitializer) then you need to provide the following additional class:
import org.springframework.security.web.context.*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SecurityConfig.class);
}
}
Where SecurityConfig is your Spring Security Java configuration class.
Using Spring Security with Spring or Spring MVC
If you are using Spring Security with Spring or Spring MVC (i.e. you have an existing WebApplicationInitializer) then firstly you need to provide the following additional class:
import org.springframework.security.web.context.*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}
Then you need to ensure that your Spring Security Java configuration class, SecurityConfig in this example, is declared in your existing Spring or Spring MVC WebApplicationInitializer. For example:
import org.springframework.web.servlet.support.*;
public class MvcWebApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {SecurityConfig.class};
}
// ... other overrides ...
}
Dynamic securityFilter = servletContext.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class);
securityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
EnumSet.allOf(DispatcherType.class) to be sure that you add a mapping not only for default DispatcherType.REQUEST, but for DispatcherType.FORWARD, etc...
After a bit of work, I've discovered that it's actually quite simple:
public class Initialiser extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {
#Override
protected Class< ? >[] getRootConfigClasses() {
return new Class[] { RootConfig.class };
}
#Override
protected Class< ? >[] getServletConfigClasses() {
return new Class[] { WebAppConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
return new Filter[] { new DelegatingFilterProxy("springSecurityFilterChain") };
}
}
The most important thing, though, is that you must have a root context (e.g. RootConfig in this case), and that must contain a reference to all the spring security information.
Thus, my RootConfig class:
#ImportResource("classpath:spring/securityContext.xml")
#ComponentScan({ "com.example.authentication", "com.example.config" })
#Configuration
public class RootConfig {
#Bean
public DatabaseService databaseService() {
return new DefaultDatabaseService();
}
#Bean
public ExceptionMappingAuthenticationFailureHandler authExceptionMapping() {
final ExceptionMappingAuthenticationFailureHandler emafh = new ExceptionMappingAuthenticationFailureHandler();
emafh.setDefaultFailureUrl("/loginFailed");
final Map<String, String> mappings = new HashMap<>();
mappings.put(CredentialsExpiredException.class.getCanonicalName(), "/change_password");
emafh.setExceptionMappings(mappings);
return emafh;
}
}
And spring/securityContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:noNamespaceSchemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<security:http security="none" pattern="/favicon.ico"/>
<!-- Secured pages -->
<security:http use-expressions="true">
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
<security:form-login default-target-url="/index" login-processing-url="/login_form" login-page="/login" authentication-failure-handler-ref="authExceptionMapping" />
</security:http>
<security:authentication-manager>
<security:authentication-provider ref="customAuthProvider" />
</security:authentication-manager>
</beans>
I could not get it to work if I merged the RootConfig and WebAppConfig classes into just WebAppConfig and had the following:
#Override
protected Class< ? >[] getRootConfigClasses() {
return null;
}
#Override
protected Class< ? >[] getServletConfigClasses() {
return new Class[] { WebAppConfig.class };
}
public class SIServerSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
#Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
Dynamic registration = servletContext.addFilter("TenantServletFilter", TenantServletFilter.class);
EnumSet<DispatcherType> dispatcherTypes = getSecurityDispatcherTypes();
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
}
}
This scenario is for executing a filter before executing other filters.
If you want to execute a filter after other filers pass true in registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");. Also check the DispatcherType ASYNC, FORWARD etc.
Faced with the same problem. Merge RootConfig and WebAppConfig - not best way - because this i did not try this solution. Tried all other solutions - everty time got "org.apache.catalina.core.StandardContext.startInternal Error filterStart". After some work, got something like this:
FilterRegistration.Dynamic enc= servletContext.addFilter("encodingFilter",
new CharacterEncodingFilter());
encodingFilter .setInitParameter("encoding", "UTF-8");
encodingFilter .setInitParameter("forceEncoding", "true");
encodingFilter .addMappingForUrlPatterns(null, true, "/*");
But is not working with DelegatingFilterProxy(). Continue finding for best common solution for all filters.
UPDATE:
I did it.
So, the main issue is: if you want add filters using java config, especially if you want to add security filter, such as DelegatingFilterProxy, then you have to create WebAppSecurityConfig:
#Configuration
#EnableWebSecurity
#ImportResource("classpath:security.xml")
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
}
In this case i create WebAppSecurityConfig and make import resource ("security.xml").
This let me to do that in Initializer class:
servletContext.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
This is related to those interested in Spring Boot with security: You don't need anything, Spring Boot picks up the #components and solves the other issues

Resources