Currently I have several services making requests to other services.
In order to build the requests I'm using Spring RestTemplates.
Is there anyway to inject a RestTemplate initialized with some headers...?
I was thinking about Factory injectors.
Any ideas?
I think you are approaching the problem incorrectly.
Instead of injecting a RestTemplate,
consider injecting an HttpEntity<?>.
Setup the HttpEntity<?> bean in your configuration #Bean method.
Then use which ever RestTemplate.exchange() method is appropriate to send your desired request.
Edits
The exchange method sends an HTTP message and returns the response.
Here is the RestTemplate JavaDoc Page
Related
I'm still on the subject of logging http requests. It's been mentioned that using a ClientHttpRequestInterceptor with a rest-template attribute of the http:outbound-gateway can be an approach.
Spring Integration AOP for Logging outbound Http requests
Logging http request in Spring integration http outbound gateway
However, I'm already using request-factory on my http:outbound-gateway objects since I want the Apache httpClient, using HttpComponentsClientHttpRequestFactory. This excludes defining a rest-template attribute on the http:outbound-gateway. Can the ClientHttpRequestInterceptor approach work this way? Or will I need to subclass the factory and produce a HttpClientRequest with an execute() method that does the logging? Thanks for any pointers.
The ClientHttpRequestFactory is a part of the RestTemplate as well. so, you just move that your HttpComponentsClientHttpRequestFactory configuration to the RestTemplate along side with that ClientHttpRequestInterceptor and inject into an http:outbound-gateway only that RestTemplate.
I am reading Spring integration source code, and I have some questions understanding the workflow:
Does the #SpringBootApplication class, when calling application.run(), will call directly beans annotated using #ServiceActivator ? For example in my config file I have :
#Bean
#ServiceActivator(inputChannel = test)
public MessageHandler myHandler() {
return new SomeHandler();
}
when the application.run() is fired, the method handleRequestMessage() of SomeHandler will be called ? Am I understanding it right ?
Well, you need to understand that there are two parts of this matter:
Configuration phase when Spring parses all the annotations to register beans in the AppplicaitonContext. This way even that #ServiceActivator is consulted and a event-driven endpoint is registered as a bean as well.
Runtime part of Spring Integration environment. Here the mentioned endpoint is subscribed to the inputChannel and when message is has arrived the handleRequestMessage() is triggered from that SomeHandler. That's why it is called "service activator".
You probably need to make yourself familiar with EIP first of all: https://www.enterpriseintegrationpatterns.com/ to understand what is messaging and why there are endpoints and channels in between. Then you go to Spring Integration docs: https://docs.spring.io/spring-integration/docs/current/reference/html/index.html and realize for yourself that this framework provides a bunch of out-of-the-box components for this or that EIP which may be registered automaticaly in the application context by just declaring some annotation.
This question is regarding the sample:
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-jersey/src/main/java/sample/jersey/Endpoint.java
Why do we need "#Component" annotation for Jersey resource when using spring-boot -starter-jersey project?
If I remove it, the Jersey servlet can still serve resources.
So what is the need for "#Component"?
You don't need it. Jersey uses HK2 as it's internal DI framework, and HK2 has a Spring bridge. This is what's used internally to bridge Spring components into the HK2 IoC container, so that they can be injected into Jersey components. And Jersey implements an AutowiredInjectionResolver1 that allows for injection of Spring components using #Autowired. You don't even need #Autowired though. All the Spring components can be injected with the normal #Inject.
The only drawback I've ran into, not making the Jersey components a Spring #Component is that it doesn't support #Value when you want to inject property values.
The one thing I don't like is that when you declare something a Spring #Component, it automatically makes it a singleton. But Jersey resources are by default request scoped. You can add a Spring #Scope("request"), and it should change the resource to a request scoped resource. Jersey has declared the Spring RequestScope, so we can use it. How exactly it ties in to Jersey's request scope, I am not a hundred percent sure. I ran into a problem a while back. I can't remember what it was, but that has kept me from ever using the Spring request scope again.
Assuming I want to keep all my resources request scoped, I would take sticking to the normal Jersey request scope, and not being able to inject #Values, over having to use Spring's request scope. Maybe I'm imagining things, and there was no issue using it, but personally I'll just stick to what I know works :-)
UPDATE
Another thing that does't work if you don't make the resource a Spring #Component is Spring's AOP. That's fine with me though as HK2 also has AOP.
1 - An InjectionResolver allows you to use custom annotations to create injection targets.
When you remove #Component jersey takes control of the scope of the instance. With #Component a singleton instance is created, removing it you can use the following jersey annotations:
• Request scope (Default):
By using the #RequestScope annotation or none, we can have a life-cycle till
the request lasts. This is the default scope of the root-resource classes. For
each new request, a new root-resource instance is being created and served
accordingly for the first time. However, when the same root-resource method
is being called, then the old instance will be used to serve the request.
• Per-lookup scope:
The #PerLookup annotation creates root-resource instances for every request.
• Singleton:
The #Singleton annotation allows us to create only a single instance
throughout the application.
Try different behaviors using a counter inside your class...
public class MyWebResource {
private int counter;
#GET
#Path("/counter")
#Produces(MediaType.APPLICATION_JSON)
public Response getCounter() {
counter++;
return Response.status(Status.OK).entity(counter).build();
}
}
I know what is Proxy in network community (server intermediary), but what is proxy in Spring ? Why spring beans are wrapped proxy ? I don't understand the idea of proxy in Spring. Thanks for response.
A proxy is a Spring generated class, that wraps your class for a given purpose, ie: adding transactional behaviour
Take a deeper look at the documentation here
It's a class that wraps your class. It is a proxy because all calls to methods of your class pass through it before actually getting to your class. The goal is to enhance your class with additional functionality, for example as #CristianMeneses said, to add transactional behavior to it, or inject some resources.
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.