How to access request scoped bean in controller? - spring-mvc

I'm trying to understand the request scoped beans. Suppose I have a controller and I have a request scoped bean instantiated using spring config xml
<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>
Do I need to add it as a dependency in controller to access it or I can access it directly from request object doing request.getAttribute("loginAction")
I just wanted to know how would I access this request scoped bean.
Thanks.

Use #Autowired annotation for this case.
#Autowired
private LoginAction loginAction;
and then add package for this bean as candidate for autowiring:
<context:annotation-config />
<context:component-scan base-package="com.foo"></context:component-scan>
and don't forget to mark this class as #Component or #Service.

Related

how to inject userContext in JSP pages

how do I retrieve the values of a context in a jsp file? this tutorial is perfect for what I need but I need to retrieve the property values in the jsp file.
http://www.mkyong.com/spring/spring-listfactorybean-example/
is there a specific interceptor that I can use?
You're referring to spring context right?
In general, JSPs should be a template of a page only, so the only interaction with the back-end should be accessing the values of the scoped attributes. This means that whichever bean value you need you should instead store in the model.
This being said, there are a few ways you can expose spring beans to view. Depends on which View resolver you're using, the ones that extend UrlBasedViewResolver have the setExposeContextBeansAsAttributes property
Set whether to make all Spring beans in the application context
accessible as request attributes, through lazy checking once an
attribute gets accessed. This will make all such beans accessible in
plain ${...} expressions in a JSP 2.0 page, as well as in JSTL's c:out
value expressions.
Default is "false".
You would configure it like
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
<property name="exposeContextBeansAsAttributes" value="true" />
</bean>
Inject your bean (or source) of userContext into your controller, so you have access to it in a local variable.
So taking the example maybe this is:
#Autowired
private CustomerBean customerBean;
#RequestMapping(value="/foobar/index.jsp")
public String (HttpServletRequest request) {
Object userContext = customerBean.getLists();
request.setAttribute("userContext", userContext);
return "/foobar/index.jsp"; // expecting JstlView viewResolver to map to JSP file
}
In the CONTROLLER simply add data to the HttpServletRequest (which you just add as argument to the method to introduce it).
Then use request.setAttribute("userContext", userContext); then in JSP simply access it using Expression Language like ${userContext}. There are other ways using Spring model paradigm but they effectively do the above.
Ensure you have your JstlView setup to https://dzone.com/articles/exploring-spring-controller
More info about how to use EL in JSPs to retrieve data attached to request:
How to obtain request / session / servletcontext attribute in JSP using EL?

How to use WAS standard persistence provider with Spring

I'm developing a portlet which runs in WebSphere Application Server ( - I accept the same problem to appear if it was a servlet instead of a portlet). At the moment it depends on Hibernate. As WAS provides a JPA implementation itself, which is a modified version of OpenJPA 2.0, I want to get rid of Hibernate.
This is my setup. persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
>
<persistence-unit name="default" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/myDb</jta-data-source>
<properties>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform" />
<property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect" />
</properties>
</persistence-unit>
</persistence>
myPortlet-portlet.xml
<!-- ... -->
<tx:jta-transaction-manager />
<jee:jndi-lookup jndi-name="jdbc/myDb" cache="true" id="dataSource" expected-type="javax.sql.DataSource" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="default" />
</bean>
In my DAO-classes I access the entityManager by using annotations:
#PersistenceContext(unitName = "default")
private EntityManager entityManager;
Everything works fine using Hibernate.
According to WebSphere Application Server docs, the default persistence provider is used if you don't specify it by using the <provider/>-tag in persistence.xml. But after commenting out the provider specification, Spring throws an exception due not being able to find the provider-class:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in PortletContext resource [/WEB-INF/myPortlet-portlet.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No PersistenceProvider specified in EntityManagerFactory configuration, and chosen PersistenceUnitInfo does not specify a provider class name either
How can I use the provided JPA implementation together with Spring (Portlet) MVC?
Short answer
You cannot use WebSphere's default provider by omitting the provider, if you want to use LocalContainerEntityManagerFactoryBean.
Long answer
Normally an entity manager is created by an entity manager factory provided by the container. You retrieve it by doing a context loopkup (EntityManager em = (EntityManager) ctx.lookup(...)) manually or use Springs jndi-lookup capability:
<beans>
<jee:jndi-lookup id="myEmf" jndi-name="persistence/myPersistenceUnit"/>
</beans>
In the question, a different approach is used, a LocalContainerEntityManagerFactoryBean, which creates an entity manager factory itself. This entity manager factory is a proxy that implements all the interfaces of the native entity manager factory. For creating such a proxy, Spring must know the class of the native entity manager factory. Spring uses three different ways to determine the class:
Detect it by the <provider/>-entry in persistence.xml
Asking a jpaVendorAdapter (specified in the equally named property of the factory bean)
Using the entityManagerFactoryInterface-property of the factory bean
And that's why you cannot completely omit the specification of your provider.
This is most likely happening because the Spring JAR(s) that you include with your application contains a different implementation of the Persistence class, or other JPA classes, used to "bootstrap" JPA.
If you'd like to use WebSphere's default provider (or, more precisely, to use whichever JPA provide configured through WebSphere's administration screens), then you must ensure that the JPA "bootstrapping" code being called during runtime is WebSphere's, not yours.
You should look for a Spring distribution JAR that doesn't mess with JPA.

SpringSecurity multiple namespaces and secured-annotations. Great confusion

I'm making a Spring MVC web-app with some RESTfull resources as an API.
I need the RESTfull part to have some custom filters as I do not want any redirection and I want any exception to be translated with the corresponding HTTP error code and a basic JSON description.
On the other hand, the rest of the website have to be more common and redirect people when they are not logged in etc.
One more thing, I wish to use the #Secured annotations and a post-authentication in some case.
How do I define the multiple http namespaces correctly (on Spring 3.1)?
Here is my erroneous configuration:
<global-method-security secured-annotations="enabled" />
<http pattern="/rest/**" authentication-manager-ref="authenticationManager" entry-point-ref="restAuthenticationEntryPoint">
<form-login login-page="/rest/login" login-processing-url="/rest/postlogin"
authentication-success-handler-ref="restAuthenticationSuccessHandler"
authentication-failure-handler-ref="restAuthenticationFailureHandler"
username-parameter="username" password-parameter="password" />
<logout logout-url="/rest/logout" invalidate-session="true" />
</http>
<http pattern="/**" authentication-manager-ref="authenticationManager">
<form-login login-page="/login" login-processing-url="/postlogin"
username-parameter="username" password-parameter="password" />
<logout />
</http>
The funny part is that this configuration works partially as I can login with /rest/login and I get the response from my custom success handler. I can also login from /login and I get the proper redirection to /. The logout are working both fine too.
Next, all the controllers beans have #Secured("ROLE_USER") in the secured methods. But all the secured methods don't ever get secured. Why is that so?
#Secured({"ROLE_USER"})
#RequestMapping(method = RequestMethod.GET, headers = { "Range" })
public #ResponseBody
HttpEntity<List<T>> list(#RequestHeader("Range") String range) {
I've read documentations everywhere and I'm more confused than ever.
Why are my methods not being secured?
Must the http namespace define an access so that the #Secured annotations work?
Are the http namespace overwriting my #Secured annotations? If it's so, how can I define multiple "login pages" with custom filters and being able to use annotations?
Here are some facts:
* I'm using Spring and SpringSecurity 3.1
* I have a custom AuthenticationManager to retrieve user details from hibernate daos.
* Some controllers are extending an abstract class where the #Secured annotations lies. But it still doesn't work for a simple controller.
* My controllers are discovered with a context:component-scan and a base-package.
* The security works fine with one http namespace.
please help, i'm getting mad with this!
Check out this answer about making sure the web context is visible to the global-method-security declaration and possibly using class proxying.
To answer your other questions, no the http namespace shouldn't affect the use of #Secured annotations, other than that the user is authenticated by the web part of the application and that information will be used by the method security interceptor when making an access decision. Unless you override it (using access-decision-manager-ref), method security will use a standard AccessDecisionManager which grants or denies access based on the roles a user has.

How to intercept all the requests for all the controller without HandlerInterceptor in Spring?

I have a requirement to intercept all the request in spring 2.5. I don't want to use HandlerInterceptor to intercept the request because it requires to configure it with every SimpleUrlHandlerMapping bean in the context files. Is there another way to intercept all the request without using HandlerInterceptor?
You could implement a filter and map it to the DispatcherServlet in web.xml. Then you should be able to intercept all request made to Spring MVC.
In short:
Create an implementation of javax.servlet.Filter
Add the filter to web.xml
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>mypackage.MyFilter</filter-class>
</filter>
and then map it to the DispatcherServlet (servlet-name should be the same that is defined for the Spring Dispatcher servlet.
<filter-mapping>
<filter-name>MyFilter</filter-name>
<servlet-name>DispatcherServlet</servlet-name>
</filter-mapping>
If you need access to the Spring ApplicationContext in the filter, use the static method
org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext()

Configuring interceptor in Spring

I am using Spring 3.0
I need to write an interceptor which intercepts all urls. in my application
I wrote one intercptor
public class HelloInterceptor extends HandlerInterceptorAdapter {
how can i configure it in spring-servlet.xml.
Using <mvc:interceptors> (see docs), e.g.
An example of registering an interceptor applied to all URL paths:
<mvc:interceptors>
<bean class="x.y.HelloInterceptor" />
</mvc:interceptors>

Resources