#Autowired HttpServletRequest inside integration tests - spring

Finally I have managed to setup the context for some integration test and to test methods that expect #PathVariable or #ModelAttribute. Still, I cannot figure out how can I setup the HTTPServletRequest used inside the controller.
MyController {
#Autowired
private HttpServletRequest request;
}
The request never updates while I'm running the test.
I might misunderstand something (as far as I'm new to Spring).
How can I achieve this?
Thanks in advance for the answer!

Isn't the HttpServletRequest passed in to the controller via a method parameter?
Use #Autowired to connect an instance variable to a Spring context bean.
Maybe you can have a look at MockHttpServletRequest for testing Web controllers.

I didn't have time to fill in the answer: I am using MockHttpServletRequest and Spring 3.1.2.
I have managed to solve it not by using #Autowired, but by getting the request bean from the controler. Something like this:
mockRequest = (MockHttpServletRequest) applicationContext.getBean ("request");
Hope that this will help someone else ...

Related

Using PersistenceContext in a Quartz Job

We're using Spring 3.1, JPA (via Hibernate) and Quartz. Typically we interact with the DB via #PersistenceContext annotation on Service beans, and either SpringMVC controllers, or GraniteDS-managed service invocation.
I'm working on writing a Quartz job that needs to interact with the database. I've tried everything I can find to get this working. I tried passing in a Spring-managed component (annotated with #PersistenceContext and #Transactional) via the jobMap, the call to entityManager.persist(o) executes, but nothing happens in the database. I also tried similar to this answer, creating a factory class to call autowireBean() on the job object. I set up the job class like so:
public class CreateAlertJob implements Job {
#PersistenceContext
EntityManager entityManager;
#Override
#Transactional
public void execute(JobExecutionContext context) throws JobExecutionException {
SomeEntity entity = new SomeEntity();
entityManager.persist(entity);
}
}
Same result, the method executes but the database is unaltered. I found this blog post which references a GitHub project. There he is using JpaInterceptor to establish a Hibernate session, but this uses the DAO pattern and I'd like to stick with using #PersistenceContext.
Clearly there is something about the Quartz thread that is preventing this from working properly? I'm about out of ideas and considering making a web service call to a SpringMVC controller just to get this working.
Since your CreateAlertJob is not created by Spring, #Transactional in it doesn't take effect.
You have the following options:
Delegate actual work to Spring bean and put #Transactional there
Use programmatic transaction management
Use AspectJ-based AOP implementation instead of Spring default implementation (but it would be overkill for such a simple problem)

What does context annotation do in Spring?

In Rest API design, I am wondering what the exact purpose of the context annotation is?
private HttpServletRequest request;
#Context
public void setRequest(final HttpServletRequest req) {
request = req;
}
The purpose is to indicate that the request property should be set from the context.
#Context is used to inject various HTTP-ish contextual data, from here:
In general #Context can be used to obtain contextual Java types related to the request or response.
API docs (Not horribly useful IMO. Or, perhaps more accurately, horribly-useful.)
This annotation is used to inject information into a class field, bean property or method parameter.
JAX-RS #Context to get the ServletContext, and WebApplicationContextUtils to get the Spring application context, with this Spring application context, you are able to access and get beans from Spring container

AbstractTransactionalJUnit4SpringContextTests http request

i try to write a test with
AbstractTransactionalJUnit4SpringContextTests
somewhere deep in my beans
FacesContext currentInstance = FacesContext.getCurrentInstance();
is called, but there is no request so it returns null.
Is there a way to fake a complete http request in my tests?
Of course there's a way, there is always a way. Spring provides a whole hierarchy of servlet mock objects in the spring-test artifact. You can use a MockHttpRequest. But how you can tie that to FacesContext.getCurrentInstance() is beyond my understanding of JSF. You'll probably need a Mock JSF implementation somewhere along the way.

#Context HttpServletRequest scope in Jersey

I'm building an API using Jersey on the Glassfish 3.1 server and need to get access to the HttpServletRequest object in order to get certain headers, caller's ip, etc. I could just inject it into every API method call but it seems more efficient to just do it globally. Is it safe to inject it at the class level like in the snippet below or will this cause some kind of concurrency issues with Glassfish?
#Path("/myapi")
#RequestScoped
public class MyApiResource {
#Context private UriInfo context;
#Context private HttpServletRequest request;
It is safe. Don't use the #RequestScoped annotation - JAX-RS resources are request scoped by default. That means a new instance gets created for each request hence no concurrency issues.

Spring3 deserialization - singleton injection

i am developing a Webapplication with JSF2 and Spring3 and have a problem with deserialization.
I have some session-scoped beans defined like so:
#Controller(value = "admin")
#Scope(value = "session")
public class AdminBean implements Serializable {
...
also i have some singletons defined like so:
#Repository
public class Repo {
Singletons are injected into the session-beans like this
#Resource
private transient Repo repo;
After i added transient, my problems with serialization/deserialization went away. But now i have the problem that after deserialzing the dependencies (repo in this case) are null. I searched a lot on this problem and found some workarounds, but i still wonder what the best solution for this problem is?
It seems to me that using application-scoped beans in session-beans is a quite common case, isn't there a clean solution for this? I came arround a solution with #Configurable, but do i really need some load-time-weaving stuff? The targets of the injection are already spring-managed, so it doesn't make sense to me..
Please enlight me
update 2 years later: You CAN transparently inject session-scoped beans into application-scoped-beans (might not be a good idea in most cases though). I just had to set the proxyMode on #Scope accordingly.
Try getting AutowireCapableBeanFactory through applicationContext.getAutowireCapableBeanFactory() and there are some methods like autowireBeanProperties, autowireBean and configureBean that should be able to reconfigure your ban after deserialization. Choose a method best for you (one of them triggers post processing, others not etc..)
Second idea is to wrap Repo in a proxy, that is serializable. It'll serialize with AdminBean and deserialize. This proxy should hold 'real' transient reference and if it gets null after deserialization, it should lookup it from the Application Context.
I heard that Spring 3 automaticaly wraps beans with such a proxy, but I've never managed to make it work.
I faced similar problem using #ViewScoped of JSF where backing bean has to serializable which in turn wants all dependencies to be serializable, which in all scenarios is not possible to get all. As #Peter mentioned about Spring 3 have a look at link # stackoverflow discussing same here. I used transient for some dependencies(Spring) and for deserialization process I hooked bean to
private void writeObject(java.io.ObjectOutputStream stream)
and private void readObject(java.io.ObjectInputStream stream)
in view scoped bean and tweaked them to get proper reference.

Resources