the difference between the Calling Object and the Target Object? - spring-aop

I'm learning Spring AOP and there are some termonolgies of this concept like Advice , PointCut , JoinPoint .. One of them is AOP Proxy and I found that a proxy is an intermediary object, introduced by the AOP framework, between the calling object and the target object. So my question is what is the difference between the Calling Object and the Target Object ?

Plese go through the reference document section : Understanding AOP Proxies
Following image depicts the concept of a proxy.
Consider a class TestService with method run() and a class Pojo with method foo(). Also consider Spring framework creates a proxy for Pojo .
#Component
public class TestService{
#Autowired
Pojo pojo;
public void run(){
pojo.foo()
}
}
Here the instance of TestService is the Calling Object and instance of Pojo is the Target object.

Related

#AfterReturning from ExceptionHandler not working

I have a GlobalExceptionHandler class which contain multiple methods annotated with #ExceptionHandler.
#ExceptionHandler({ AccessDeniedException.class })
public final ResponseEntity<Object> handleAccessDeniedException(
Exception ex, WebRequest request) {
return new ResponseEntity<Object>(
"Access denied message here", new HttpHeaders(), HttpStatus.FORBIDDEN);
}
I have a AOP which is suppose to be triggered after the exception handler returns response.
#AfterReturning(value="#annotation(exceptionHandler)",returning="response")
public void afterReturningAdvice(JoinPoint joinPoint, Object response) {
//do something
}
But the #AfterReturning is not triggered after the handler returns a valid response.
Tried full qualified name but not working
#AfterReturning(value = "#annotation(org.springframework.web.bind.annotation.ExceptionHandler)", returning = "response"){
public void afterReturningAdvice(JoinPoint joinPoint, Object response) {
//do something
}
Please go through the documentation to understand the proxying mechanisms in Spring framework.
Assuming the ExceptionHandler code written was of the following format
#ControllerAdvice
public class TestControllerAdvice {
#ExceptionHandler({ AccessDeniedException.class })
final public ResponseEntity<Object> handleAccessDeniedException(
Exception ex, WebRequest request) {
return new ResponseEntity<Object>(
"Access denied message here", new HttpHeaders(), HttpStatus.FORBIDDEN);
}
}
key points from the documentation pertaining to the question are
Spring AOP uses either JDK dynamic proxies or CGLIB to create the
proxy for a given target object.
If the target object to be proxied implements at least one
interface, a JDK dynamic proxy is used. All of the interfaces
implemented by the target type are proxied. If the target object
does not implement any interfaces, a CGLIB proxy is created.
With CGLIB, final methods cannot be advised, as they cannot be overridden in runtime-generated subclasses.
OP identified the issue based on the comments and hints , this answer is for any future references.

Instantiate one Routebuilder from inside a route in another RouteBuilder in Camel

I am relatively new to Camel. I have a use case where I need to instantiate a RouteBuilder only when it receives get an exchange to kickstart the process from an Orchestration module. I am trying to do this mainly because, the exchange carries information required to instantiate the new RouteBuilder. Is there a way where I could instantiate this new RouteBuilderB from inside a route in the existing RouteBuilderA.
public class RouteBuilderA extends RouteBuilder {
public void configure(){
//So, something like this?
from("direct:A")
.process(//new RouteBuilderB())
.to("direct:B")
}
Is there a way to accomplish this?
Yes its just Java code, so write a Processor that creates the RoutBuilder instance you want, and do any configuration with setter/getter etc. And then you can add that as routes to CamelContext using the addRoutes method.

Spring RestTemplate and JSON how to ignore empty Arrays deserialization?

I am currently using Spring 4.1.6 with a RestTemplate to consume a third party webservice with JSON which I cannot change its behavior.I am using Jackson databind v2.6.0.
Problem: Sometimes the service returns for a member a hashmap {member:{"key":"value",...}} sometimes the same member is just an empty array {member:[]}. So I can not ignore the property by default.
Is there a way to configure the deserialization to ignore empty arrays? I saw a jackson property "WRITE_EMPTY_JSON_ARRAYS" but I am not quite sure how I can use it with my restTemplate and spring configuration.
Are there other possiblities e.g. use some combination of #JsonXXX Annotations? I saw #JsonSerialize which can be used on class level, but I don't like to write a deserializer for all my classes just to handle this situation (However if there is no other way of course I will do)
Example responses to llustrate the behavior of the service:
response with a hashmap
{"id":170,"categories":{"13":"caro"}}
response with empty array of the same member
{"id":170,"categories":[]}
Example of my RestTemplate usage:
BasicAuthRequestFactory requestFactory = new BasicAuthRequestFactory(httpClient);
restTemplate = new RestTemplate(requestFactory);
Article a = restTemplate.getForObject(new URI("http://..."), Article.class);
Error:
caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token
at [Source: java.io.PushbackInputStream#4aa21f9d; line: 1, column: 1456] (through reference chain: ResponseArticleWrapper["data"]->Article["categories"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
Example of my current annotated class:
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonInclude(Include.NON_NULL)
public class Article {
#JsonProperty("id")
private Integer id;
#JsonProperty("categories")
private Map<Integer,String> categories = new HashMap<Integer,String>();
}
Thank you in advance for any hints and examples.
Since jackson-databind 2.5 there is DeserializationFeature for handling this case. It's turned off by default, so you need to configure it in your ObjectMapper:
#Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
return objectMapper;
}
You can see how the custom ObjectMapper for RestTemplate is configured here: How can we configure the internal Jackson mapper when using RestTemplate?
After you're done with the configuration, you can just let Spring wire it for you in your class:
#Autowired
private RestOperations restTemplate;
and use the provided restTemplate instance.

Not able to serialize List<Object> to json using resteasy jackson provider and jaxb annotations

I have added resteasy-jackson provider jar in my pom.xml
I have one pojo class annotated with jaxb annotations :
Request.java
#XmlElement
public List<Object> getListSO() {
return listSO;
}
I have written an resteasy client to access a rest webservice. I am passing this request object as a parameter to webservice.
Rest Webservice
#POST
#Path("/authorizefields")
#Produces("application/json; charset=ISO-8859-1")
#Consumes("application/json; charset=ISO-8859-1")
public Reply getFields(Request request) {
}
Now from rest client if i add some object to list say
listSO.add(new Sample());
request.setListSO(listSO);
and pass it to the rest webservice I am not able to get sample object in ws.
Is there any jaxb or jackson annotation needed to put on list of object to support polymorphism?

Why Don't DomainService Constructor Overloads Show Up as DomainContext Constructor Overloads?

I wrote an overload for my DomainService class. Problem is, when I recompile, it's not showing up as an overload for my DomainContext. What's wrong? Here is a code sample:
[EnableClientAccess]
public class FoodDomainService : LinqToEntitiesDomainService<FoodEntities>
{
public FoodDomainService(CultureInfo cultureInfo)
{
Thread.CurrentThread.CurrentCulture = cultureInfo;
}
}
And this doesn't work:
FoodDomainContext _foodContext = new FoodDomainContext(Thread.CurrentThread.CurrentCulture);
I get an error that there is no overload matching that. Am I not allowed to do this? Do I need an attribute of some kind?
You are not allowed to do this. When newing up the context from your Silverlight client, you are not directly intantiating your service. Instead, you instantiate a proxy class that was generated by RIA Services, and that proxy class will then call your service. This is why you don't see your constructor: because RIA did not generate it in your proxy.
Doing what you're trying to do would also implicate that there is a round-trip to the server at the time of newing up that FoodDomainContext class, which is not going to happen, because you need to complete the initialisation of that object before you can do so.
Anyway, instead of that you can create a method called SetCurrentCulture() and then call it after initializing the proxy.
This will not work because DomainContext is generated on client code of silverlight, click on view all folders or jump to definition and you will see that code generated will not contain your extra constructor.
Instead you will have to create a method in your domain service and pass information to server.
public SetCultreInfo(int lang,...)
{
.. set culture info
}
On your client, inside constructor you should call,
public MyDomainContext()
{
this.SetCulture(....);
}

Resources