The idea is to use some kind of (custom) design pattern (or any other Java constructs such as parametrized types etc) to make @Configuration
and @Service
classes more generic and general.
The problem:
Part of my Spring Boot application acts like a client, i.e. it uses some SOAP Web services. I'm using exactly seven (in future possibly more) services. Classes which I'm using to send request and receive response are generated by the Maven JAXB2 plugin based on WSDL. In this post, I'm gonna outline the simplest services:
HelloWorld
Controller layer:
@Autowired
private HelloWorldClient helloWorldClient;
@RequestMapping(value = "/helloWorld", method = RequestMethod.POST)
@ResponseBody
public HelloWorldResponse helloWorldRequest(@RequestParam(value = "myValue") String myValue) {
HelloWorldResponse response = helloWorldClient.getValue(myValue);
return response;
}
Configuration for service class
@Configuration
public class HelloWorldConfiguration {
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.zesium.arvato.model"); //this is package where I placed generated classes from wsdl scheme
return marshaller;
}
@Bean
public HelloWorldClient helloWorldClient(Jaxb2Marshaller marshaller) {
HelloWorldClient client = new HelloWorldClient();
client.setDefaultUri("");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
Service class
@Service
public class HelloWorldClient extends WebServiceGatewaySupport {
@Autowired
private ObjectFactory objectFactory;
public HelloWorldResponse getValue(String myValue) {
HelloWorld request = objectFactory.createHelloWorld();
JAXBElement<String> value = objectFactory.createHelloWorldMyValue(myValue);
request.setMyValue(value);
HelloWorldResponse response = (HelloWorldResponse) getWebServiceTemplate()
.marshalSendAndReceive("https://clienttesthorizon.horizonafs.com/AFSServices/AFSService.svc/basicHttpBinding",
request, new SoapActionCallback("http://tempuri.org/IAFSService/HelloWorld"));
return response;
}
}
Now, as I mentioned I have seven more of these "triplets" for each service one triplet. As expected, other services in the getValue()
are accepting different number of parametears (String, ints and BigDecimals).
The question is, is there some kind of design pattern or Spring "way" of making this more generic? Meaning, to write some kind of "template" @Serivce
class, along with @Configuration
class to facilitate the idea?
Something roughly like this:
public class GenericClient<R,C> extends WebServiceGatewaySupport {
R response; //R would represent response (like HelloWorldRespons)
//C would represent different serivce class clients
public GenericClient<R, T>(R r, C c){
this.response = r;
}
@Autowired
private ObjectFactory objectFactory;
public R getValue(String myValue) {
C request = objectFactory.createC(C.class);
//Call to some method which will dynamically during runtime figure out which implementation to call
R response = (R) getWebServiceTemplate()
.marshalSendAndReceive("https://clienttesthorizon.horizonafs.com/AFSServices/AFSService.svc/basicHttpBinding",
request, new SoapActionCallback("http://tempuri.org/IAFSService/ServiceName"));
return response;
}
}
I know this is wrong, but I don't have any idea on how to approach this, and I've been doing backend for one and a half year at this point. I know this is very broad question, but if anyone could give me any pointers where to look for, maybe a specific design pattern or something similar, that would be excellent.
Aucun commentaire:
Enregistrer un commentaire