POX and SOAP on the same endpoint - spring

I have a requirement where I need to expose the service for both SOAP and POX incoming requests.I included the following code snippet to switch from SOAP to POX and it worked fine
#Bean(name = MessageDispatcherServlet.DEFAULT_MESSAGE_FACTORY_BEAN_NAME)
public WebServiceMessageFactory messageFactory() {
return new DomPoxMessageFactory();
}
But to make the application accept SOAP requests I commented the above code.
Obviously,its not the desired solution and I need my application to accept both SOAP and POX without this code change.Can you please suggest a proper approach?

Related

Prevent direct call to my spring boot rest API

I have several REST services (on spring boot) used by a javascript file (website) and these services can be called directly by anyone (and you can see the API url/parameters with the developper console on any browser).
So I would like to prevent the direct calls to the API, exept of course from the front side of my app.
I saw that I can use an API key with spring security but is it reliable? Since I think you can see the key if you intercept the message with developper console.
What you can do are the following :
Disable CORS in your springboot application by setting the following globally or per endpoint as you wish.
To set the CORS per endpoint :
#CrossOrigin(origins = "http://localhost:9000")
#GetMapping("/greeting")
public Test testing(#RequestParam(required=false, defaultValue="Test") String name) {
System.out.println("in test");
return new Testing(10, String.format(template, name));
}
You can use spring security to preauthorize your controller endpoints to make sure that only the authorized has access to the controller.
Like for example :
#RestController
#RequestMapping({"/v2/"})
public class ExampleTestController {
#PreAuthorize("hasAuthority('ROLE_ADMIN')")
#RequestMapping(value = "/test", method = RequestMethod.GET)
String test() {
return "Hello";
}
}
Using spring security is safe, as the user is always validated before access is granted . Even while using Oath2 the key generated is after validating the user login and the key can be used to validate every request to the controller by passing it in the header or using it in the rest template.
Another way of isolating your rest endpoints is by using the load balancer (or ngnix or anything) to block requests to these endpoints from outside your domain.

SpringBoot get InputStream and OutputStream from websocket

we want to integrate third party library(Eclipse XText LSP) into our SpringBoot webapp.
This library works "interactively" with the user (like chat). XText API requires input and output stream to work. We want to use WebSocket to let users interact with this library smoothly (send/retrieve json messages).
We have a problem with SpringBoot because SpringBoot support for WebSocket doesn't expose input/output streams. We wrote custom TextWebSocketHandler (subclass) but none of it's methods provide access to in/out streams.
We also tried with HandshakeInterceptor (to obtain in/out streams after handshake ) but with no success.
Can we use SpringBoot WebSocket API in this scenario or should we use some lower level (Servlet?) API ?
Regards Daniel
I am not sure if this will fit your architecture or not, but I have achieved this by using Spring Boot's STOMP support and wiring it into a custom org.eclipse.lsp4j.jsonrpc.RemoteEndpoint, rather than using a lower level API.
The approach was inspired by reading through the code provided in org.eclipse.lsp4j.launch.LSPLauncher.
JSON handler
Marhalling and unmarshalling the JSON needs to be done with the API provided with the xtext language server, rather than Jackson (which would be used by the Spring STOMP integration)
Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<String, JsonRpcMethod>();
supportedMethods.putAll(ServiceEndpoints.getSupportedMethods(LanguageClient.class));
supportedMethods.putAll(languageServer.supportedMethods());
jsonHandler = new MessageJsonHandler(supportedMethods);
jsonHandler.setMethodProvider(remoteEndpoint);
Response / notifications
Responses and notifications are sent by a message consumer which is passed to the remoteEndpoint when constructed. The message must be marshalled by the jsonHandler so as to prevent Jackson doing it.
remoteEndpoint = new RemoteEndpoint(new MessageConsumer() {
#Override
public void consume(Message message) {
simpMessagingTemplate.convertAndSendToUser('user', '/lang/message',
jsonHandler.serialize(message));
}
}, ServiceEndpoints.toEndpoint(languageServer));
Requests
Requests can be received by using a #MessageMapping method that takes the whole #Payload as a String to avoid Jackson unmarshalling it. You can then unmarshall yourself and pass the message to the remoteEndpoint.
#MessageMapping("/lang/message")
public void incoming(#Payload String message) {
remoteEndpoint.consume(jsonHandler.parseMessage(message));
}
There may be a better way to do this, and I'll watch this question with interest, but this is an approach that I have found to work.

JAX-RS/Jersey 2 file download - Is there a common API for server and generated client proxy

I autogenerate the JAX-RS interfaces from Swagger.
I use Jersey 2.25.1.
All works fine for most of the use cases. We have the same interface for the server and client parts.
Clients are generated from the interface with org.glassfish.jersey.client.proxy.WebResourceFactory.
Now I need to implement file download via streaming (files gonna be huge, typically in the gigabyte range, so streaming is required).
I can use the following signature for the server:
#GET
#Path("/DownloadFile")
#Produces({"application/octet-stream"})
StreamingOutput downloadFileUniqueId();
But StreamingOutput cannot obviously be used in the client.
Is there any feature in JAX-RS / Jersey to have a common interface between server and client ?
I've seen for the upload, this is possible using FormDataMultiPart, I'd like a similar solution for download...
Ok, found a working solution using a javax.ws.rs.core.Response object as return type:
Server code:
public Response downloadFile(String uniqueId){
InputStream inputStream = filePersistenceService.read(uniqueId);
Response.ok(outputStream -> IOUtils.copy(inputStream, outputStream)).build()
}
Client code:
Response response = client.downloadFile(uniqueId);
InputStream resultInputStream = response.readEntity(InputStream.class);
This works fine with clients generated by org.glassfish.jersey.client.proxy.WebResourceFactory.

How to create soap service using GET method

I'm beginner to the soap web service. When I create soap service don't think about That service is POST or GET .But when we create REST service we initialize that service is POST or GET.
I created soap web service.Here is my code
#WebService(targetNamespace = "http://service.test.hameedia.com/", portName = "HameediaTestServicePort", serviceName = "HameediaTestServiceService")
public class SoapServiceTest{
public String details(String name){
//some thing in here
}
}
But in here we didn't initialize this is POST or GET .But console show this is POST method.My question is
Is soap web services default method type POST
If is it not
How to create soap web service with GET method
I get some idea from this.But I'm not clear with my question.If you have any idea about this please share.
SOAP is an acronym for Simple Object Access Protocol. It is an XML-based messaging protocol for exchanging information among computers. SOAP is an application of the XML specification.
SOAP is not depended upon HTTP and HTTP Method(s), SOAP can extend HTTP for XML messaging.
You can call SOAP Web Service over HTTP and you have to use POST method only because of complex nature of the SOAP Request.
Ref : https://www.tutorialspoint.com/soap/what_is_soap.htm

JAX-RS Jersey - Howto force a Response ContentType? Overwrite content negotiation

Jersey identifies requests by looking at the accept header. I have a request which accepts only text/* - How can i force the response to be for example application/json?
#POST
#Path("/create")
#Produces(MediaType.APPLICATION_JSON)
public MyResponseObject create() {
return new MyResponseObject();
}
If a request is directed to create which only accepts text/* jersey will return a 500. Is there a way to workaround this issue? (I can't change the requests accept header).
Jersey also supports this via ResourceConfig property PROPERTY_MEDIA_TYPE_MAPPINGS that you could configure in your web.xml or programatically via Jersey APIs as shown below:
DefaultResourceConfig rc = new DefaultResourceConfig(MyResource.class);
rc.getMediaTypeMappings().put("json", MediaType.APPLICATION_JSON_TYPE);
rc.getMediaTypeMappings().put("xml", MediaType.APPLICATION_XML_TYPE);
SimpleServerFactory.create("http://localhost:9090", rc);
You can force content type negotiation by suffixing either .json or .xml to your URL.
I solved this by using a servlet filter:
http://www.zienit.nl/blog/2010/01/rest/control-jax-rs-content-negotiation-with-filters

Resources