spring mvc exception handler with #RequestBody - java

In my Spring MVC application I have a number of methods that use #RequestBody to bind to domain objects I've defined (specifically, from JSON using Jackson).
I'm currently using a simple view for exceptions as follows:
<bean id="exceptionHandler" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="errorXmlView" />
</bean>
<bean id="errorXmlView" class="com.example.MyCustomXmlView" />
My question is, inside MyCustomXmlView, which currently just extends AbstractView, is there a way I can get access to the object that was bound with #RequestBody? Assuming, that is, that it got that far and it wasn't a binding exception. For example, is there some kind of request-scoped bean I could call upon, or a way to get the object injected into the model for my exception view? If not, is there a different way of defining an exception resolver that would allow me to do that?

Have you considered the #ExceptionHandler annotation? The spring documentation has an example of its usage, and I imagine you can create a custom exception that will hold onto your model, which you should then be able to access in your exception handling method.

I often times capture controller method parameters with a ThreadLocal, and then store them for later use in logging, etc. The best way I've found is to use an #Aspect (or whatever AOP strategy you prefer) to intercept the controller methods and store the method parameters for later use.

Related

Is it possible to outhouse ShutdownStrategy for CamelContext into a central OSGi bundle?

I am trying to outhouse central beans of my OSGi bundles into a central bundle, which provides them as a service. This works fine with the ErrorHanlders and Processors, but not with the ShutdownStrategy and RedeliveryPolicy. The Error Message I receive is
org.osgi.service.blueprint.container.ComponentDefinitionException: A class org.apache.camel.processor.RedeliveryPolicy was found in the interfaces list, but class proxying is not allowed by default. The ext:proxy-method='classes' attribute needs to be added to this service reference.
I could try to follow the instrutction and add the ext:proxy-method, but first I want to understand the clue here. Maybe it's not a good idea to centralize strategies and policies?
[EDIT] The mistake here was to use the class in the service instead of an interface. So interface="org.apache.camel.spi.ShutdownStrategy" should be the correct Interface here (for the ShutdownStrategy). The bundle with my camel route references this service so:
<reference
id="shutdownStrategy"
interface="org.apache.camel.spi.ShutdownStrategy"
component-name="shutdownStrategy" />
But now I get the following error:
java.lang.IllegalArgumentException: CamelContext must be specified
[EDIT] I want to confine this question to the ShutdownStrategy, because the RedeliveryPolicy works fine when I referenc it in the ErrorHandlers inside my central bundle.
So is it possible to outhouse the ShutdownStrategy, too? Maybe not, because it needs a CamelContext.
When using Spring XML you then just define a spring bean which implements the org.apache.camel.spi.ShutdownStrategy and Camel will look it up at startup and use it instead of its default.
I found the answer in the Camel documentation
You can implement your own strategy to control the shutdown by implementing the org.apache.camel.spi.ShutdownStrategy and the set it on the CamelContext using the setShutdownStrategy method.
When using Spring XML you then just define a spring bean which implements the org.apache.camel.spi.ShutdownStrategy and Camel will look it up at startup and use it instead of its default.
So if you have your own implementation of the ShutdownStrategy you can use it as a bean.
<bean id="shutdownStrategy"
class="org.apache.camel.spi.ShutdownStrategy">
</bean>

Spring 4 Webservice HTTP 500 - IllegalStateException: The mapped controller method class is not an instance of the actual controller bean

so I am working on a school project and I am trying to build a JSON Rest Webservice application. I am using Spring 4 and Hibernate 4 with Jackson 2.
I have a lot of hard times with this app, but now I have a problem I cannot overgo. I am using Cloudbees as my cloud service provider and from time to time (which is important to state, because it sometimes work and sometimes not!) I get a HTTP 500 error :/.
The best part is - I never had it locally.
It goes more or less like this:
HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalStateException: The mapped controller method class 'pl.lodz.pp.controllers.crud.impl.UserController' is not an instance of the actual controller bean instance 'com.sun.proxy.$Proxy47'. If the controller requires proxying (e.g. due to #Transactional), please use class-based proxying.
And I am so confused. I never get this locally and usually if I restart the application on cloud (one or more time) it will work for some time again.
I had made some errors, like
#Autowire
private ClassType variable
instead of
#Autowire
private ClassInterface variable
but I fixed them all. I am NOT USING #Transactional annotation anymore. At least not in my class. Maybe the GenericDao have it somewhere (https://code.google.com/p/hibernate-generic-dao/) but I never had this problem before.
Transaction management:
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
Please, find the full code here:
https://github.com/atais/PP-JSON
Bottom line
I am not using #Transactional and I inject everything with the Interface type. So what am I possibly doing wrong? And what's the best - it works sometimes, but sometimes I get this error :/
The only thing you need to do is to add
#EnableAspectJAutoProxy(proxyTargetClass = true)
to your Spring Configuration.
In many cases the framework applies for your classes some proxying mechanisms: TX, Cache, Async etc. - depends on annotations, which you are using on your classes or its methods.
So it is good practice to introduce for those classes interfaces and use exactly that contract, not classes.
I understand that it looks like overhead for all #Service classes, but introduce interfaces at least for those classes which use some AOP aspects
I got the same exception when i implemented a interface (controller extends x implements interface) in my controller. Removing the interface solved the problem. I suspect implementing a specific interface is not supported for controllers.

Spring injecting one property dynamically

I am new to Spring and i am stuck with a scenario where i need help.
My Scenario is i have a bean definition for some specific module like this.
<bean name="ruleEngineAction" class="com.xxxxx.yyyy.UserAction" scope="prototype">
<property name="userManager">
<ref bean="userManager" />
</property>
<property name="userDto">
<ref bean="userDto" />
</property>
</bean>
now within this bean i want to use one more property but that depends on the application flow like
<property name="roleManager">
<ref bean="roleManager">
</property>
so should i include this property with in the bean definition itself or i can do it dynamically in code because i don't want this property to be used a lot.
Please suggest me the right and efficient approach.
From what I understood from question, there is only one bean of type roleManager but the usage of roleManager is based on application flow.
In this scenario, I would recommend you to inject roleManager to ruleEngineAction as you would do with any other bean but use the bean only when it is necessary.
It is a bad practice to needless dependency to spring in normal classes like adding reference to applicationContext for fetching the bean dynamically at runtime.
Whether or not, you inject this bean, it'll anyways be created by Spring. Why not just include the property in your UserAction and whether to use it or not, can be decided in your class. No harm in having the bean injected, because you'll anyways use it for some scenarios.
Had the scenario been like, the object won't be created, if you don't inject/use, then it would make sense to consider this situation, but since Spring will create the object anyways, it really shouldn't be a problem to just inject it.
Well you need to add new property with getter and setter in your class com.xxxxx.yyyy.UserAction for roleManager like :
class UserAction {
// your previous properties userManager, userDto, etc.
private RoleManager roleManager; // assuming interface/class as RoleManager for roleManager
// getter and setter for roleManager
// your other action methods which will use roleManager
}
There is no problem if you inject also.Whenever you access that class only it will create the object of that class.

Setting Values of enum via Spring Integration

I have a system where I have an enum of Shops for example. These shows each have their own ShopCommand property (some of which share the same type of command class). from a method in the command class I then want to call send on a Spring Integration gateway. Where I'm confused is how to actually insantiate this gateway in spring. Ideally what I want is to construct the enum via XML configuration with command property being created also in spring, which has the property outGateway set via Spring. I'm not sure if I've made myself very clear with this descrition, if clarification is needed then just ask!
I think this is what you are asking for:
Say I have an enum for ShopType
public enum ShopType {
GROCERY, DEPARTMENT, MALL;
}
Then I have some Store bean that I want to setup via spring configuration. You can instantiate and use the enum like this:
<bean id="DEPTARTMENT_STORE" class="my.package.ShopType" factory-method="valueOf">
<constructor-arg value="DEPARTMENT"/>
</bean>
<bean id="searsStore" class="my.package.Store">
<property name="shopType" ref="DEPTARTMENT_STORE"/>
</bean>
The factory-method points to a static method that is used to create the object. So you can use the enum's method "valueOf" as a factory method.

Are there Compound property values in Spring

I read about Compound property names in the "The Spring Framework (2.5) - Reference Documentation - chapter 3.3.2.7"
Can i use the same concept to set values of properties? Can i use a compound string as a value expression?
<bean id="service1" class="a.b.c.Service1Impl" scope="prototype">
<property name="service2" ref="service2"/>
<property name="service2.user" value="this-service1-instance.user"/>
</bean>
<bean id="service2" class="a.b.c.Service2Impl" scope="prototype">
...
</bean>
User is a property of a.b.c.Service1Impl which is not in control of Spring. I want to forward this property to a.b.c.Service2Impl.
Rather than use a plain old factory bean, rather use a factory method to create the bean of the property and then inject that result...
iow
in your case, it would look something like this...
<!-- the bean to be created via the factory bean -->
<bean id="exampleBean"
factory-bean="serviceLocator"
factory-method="createInstance"/>
So the bean of id is created by calling createInstance on bean serviceLocator.
Now spring does not support nested properties out of the box, though you could look at creating a custom editors which might provide that support - possible but tricky. Possibly not worth the effort.
One mechanism you could look at using is nesting using the factory-bean factory-method technique...
Something like:
<bean id="c" class="C" />
<bean id="b" factory-bean="c" factory-method="getB"/>
<bean id="a" factory-bean="b" factory-method="getA"/>
This will effectively expose: a.b.c where C has a method getB and A has a method getB
I had to do something similar, and I'm afraid it's not possible. I had to write a [FactoryBean][1] to expose the property.
It would look something like this:
public class UserFactory implements BeanFactory {
private Service2 service2;
// ... setter and getter for service2
public Object getObject() {
return getService2().getUser();
}
public Class getObjectType() {
return User.class;
}
public boolean isSingleton() {
// Since it's a prototype in your case
return false;
}
}
Come to think of it, in your case, you'd probably define the factory itself as a prototype, in which case your isSingleton() may return true, you'll need to play around with this a little bit.
Spring's XML wiring syntax supports lists, maps and properties objects, and you can create other 'data' objects via property editors.
Edit: (Oh I see what you are asking.) I think that the answer is no. I don't recall having seen any mention of calling getters on a bean or non-bean object in the Spring documentation, let alone a syntax for doing this in the wiring file. It tends to go against the grain. Spring wiring is declarative, and calling a getter would lead to patterns that are bordering on procedural.

Categories