Forward SOAP request base on QName from client Java - java

Currently, I created a project webservice which I provide 2 webservices endpoint corresponding with 2 versions is MyWebserviceV1 and MyWebserviceV2.
However, I would like to have only one access url and I will forward the request base on targetNamspace.
URL example: localhost:8080/my-project/MyWebservice
I have 2 files wsdl for these versions, each file wsdl I have different targetNamespace:
- MyWebserviceV1: the targetNamespace com.test/myservice-v1.0
- MyWebserviceV2: the targetNamespace com.test/myservice-v2.0
My idea is that: When I receive the SOAP request, base on the targetNamespace (QName from client request) attribute, I will forward to corresponding endpoint.
I intended to use the javax.servlet.Filter for pre-process request but I could not get the target targetNamspace.
How can I get the targetNamespace from SOAP request message, or any configuration available to use for my case.

Related

how to receive SOAP envelope thru REST?

I have a system that returns SOAP envelope message
<soap:Envelope>
<soap:Body>
<ns2:myResponse>
And i have classes generated from WADL and XSD files (by cxf-wadl2java-plugin and JAXB), also i have an interface generated (imports from javax.ws.rs ):
#Path("/case/{id}")
public interface MyService {
#GET
#Produces("application/xml")
Response getCase(#PathParam("id") String id);
How should the client looks like ?
I've tried with Jersey:
com.sun.jersey.api.client.Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080/case");
and CXF:
MyService service = JAXRSClientFactory.create("http://localhost:8080", MyService.class, providers);
but during a call i have (i'm not surprised) a problem with unmarshalling:
unexpected element (uri:"http://www.w3.org/2003/05/soap-envelope", local:"Envelope"). Expected elements are <{}myResponse>
how to create working client for this?
it was a WS before (with WSDL, binding file and XSDs with cxf-codegen-plugin plugin)

Verifying the path of a web service resource

I am writing some unit tests for a web service written years ago. The root class has a path like:
#Path("v1/path/")
public class RootResource {
...
}
The methods inside the class have their respective path. One working path is:
#GET
#Path("orders/{order_num}.xml")
#Produces(MediaType.APPLICATION_XML)
public Response getXML() {
...
}
This is working fine at root_path/v1/path/orders/123123.xml.
However, there is another method:
#POST
#Path("orders/{order_numer}/status.xml")
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public Response getStatusXML() {
Logger.info(CALLER, "orderStatusXML", "XML Request received");
...
}
When I try to access this at root_path/v1/path/orders/123423/status.xml I get 404 in return. Even the first line with the logger is missing from the logs.
I am on Weblogic 12 and we used Jersey REST API for these web services.
I have tried a number of things to make sure the path listed in the test case is the correct one. Any hints/ideas on how to check for the correct path?
There is no reason for the root_path/v1/path/orders/123423/status.xml path to give a 404 unless something else is acting on that URL.
Things to try:
look into your web.xml file and see what URL pattern Jersey handles. That particular URL might be handled by some other servlet;
again look into the web.xml and see if you have any filters declared. What URLs do does filters intercept and what do the filters do to the request once intercepted?
this might not be the case but I'll add it anyway... is it a "404 - Not found" that you get back or is it actually a "405 - Method not allowed" that is returned? If you try to access the root_path/v1/path/orders/123423/status.xml URL with a GET, like from the browser, you get 405 because your method is annotated with #POST. Are you using a POST?
My bet is on a filter!

How to protect restful webservice from unauhtorised access

I have a JAX-RS Restful webservice. This resource/webservice is asset for us. I am exposing this service url to third party client that would call this service resource. I want to protect this service from another authorised client/vendors.
Thus my question is -
How to protect this.
I thought to include an API key and the API key should be matched with a perticuler client API Key. And I also need to match the client url address means from whcih url the request is coming.
How to do this. How to get the URL that is calling the our rest service. I am deploying my rest in Tomcat 7.0.
Thanks
Update --
#Path("report")
#Produces(javax.ws.rs.core.MediaType.APPLICATION_XML)
public class DnaReportResource {
#GET
#Produces(javax.ws.rs.core.MediaType.APPLICATION_XML)
public void getDnaReport(#Context UriInfo uri) {
System.out.println(uri.getRequestUri());
System.out.println(uri.getPath());
System.out.println(uri.getAbsolutePath());
System.out.println(uri.getBaseUri());
//MultivaluedMap<String, String> queryParams = uri.getQueryParameters();
}
}
From your servlet handler you can call
String url = request.getRequestURL().toString();
Getting request URL in a servlet
EDIT
did you try
String url = uri.getRequestUri().toString();
What does it return?
You can make use of Tomcat Realm configuration to achieve authenticate your clients.

Why are error pages ignored in RESTEasy web service running on Tomcat?

I'm developing a REST-ful web service using RESTEasy deployed on Tomcat. I've configured an error page which takes the exception's message and generates an XML based on it when any exception occurs during the request.
This works fine for any application generated exceptions. However, if client sends an invalid XML which cannot be unmarshalled correctly, an javax.xml.bind.UnmarshalException is thrown and Tomcat's default error page is used instead of mine.
I have configured my error page to the error-code 500 in web.xml.
Is using error pages the correct way to handle errors when using RESTEasy or is there an alternative way?
The best way is to use an ExceptionMapper. You create a class UnmarshalExceptionMapper that implements ExceptionMapper. You annotate this with "#Provider" and in your Application constructor you do "classes.add(UnmarshalExceptionMapper.class)" or "singletons.add(new UnmarshalExceptionMapper())".
Your exception mapper will look something like this:
#provider
public class UnmarshalExceptionMapper
implements ExceptionMapper<UnmarshalException> {
public Response toResponse(UnmarshalException exception) {
ResponseBuilder rb =
Response.status(
Response.Status.BAD_REQUEST) // Most appropriate HTTP status code
.entity(your xml goes here)
.type("application/xml");
return rb.build();
}
}
Note that you must set the type to "application/xml" because currently content negotiation is NOT done for exception mappers. To do your own content negotiation, get the HttpHeaders from the request, find the "accept" header, and set the type accordingly.

jax-ws: how to get a handle to start/end of processing incoming soap message

Situation: jax-ws web service on Weblogic appserver; wsdl first development, jaxb customizations in external binding file.
I would like to get a handle to the actual jaxb context that will process the incoming soap xml message, before it has been unmarshalled into java objects.
Then I would like to get the unmarshaller of this jaxb context - the one that actually will be used during the unmarshalling. And then setup some properties of this unmarshaller (e.g. listener and idresolver).
The new #UsesJAXBContex annotation JAXBContextFactoryin jaxws 2.1.5 - jaxb 2.2 is probably what I need for that.
However weblogic 10.3.1 uses jaxws 2.1.1, jaxb 2.1.3.
Another solution is to use:
#WebServiceProvider(portName = "Port", serviceName = "Service", targetNamespace = "tns", wsdlLocation = "/wsdls/x.wsdl")
#BindingType(value = "http://schemas.xmlsoap.org/wsdl/soap/http")
#ServiceMode(value = javax.xml.ws.Service.Mode.MESSAGE)
public class ServiceProvider implements Provider<SOAPMessage>
This gives access to the soap xml message. I still have to figure out where the method name can be found.
Instead of:
#WebService(portName = "Port", serviceName = "Service", targetNamespace = "tns",
wsdlLocation = "/wsdls/x.wsdl", endpointInterface = "tns.PortType")
#BindingType("http://schemas.xmlsoap.org/wsdl/soap/http")
public class ServicePort implements PortType

Categories

Resources