I've been asked to rebuild our customer portal, using gwt and connecting to our data using various webservices set up on the server.
I generated all the proxy classes usign the WSDL and Jax-WS/wsimport utility, however when i make the below call:
ReportingApiSoap soap = api.getReportingApiSoap();
ArrayOfReport returnValues = soap.getReports(serverCredentials, true);
My returnValues object is null. I know the webservice itself works because I was able to test it with the same parameters I'm passing in now.
I was previously have some issues sending data to the webservice; that turning out to be the namespaces weren't lining up as they needed to. I suspect something similar is happening here, but haven't been able to figure out what yet.
Anyone ever run into something similiar before? Or if not any idea how I can check the raw xml I'm getting out of the webservice call? That way I can track the problem a step furthur.
-Ian
My Credentials object:
public class ApiCredentials {
#XmlElement(name = "Id", namespace="http://mycompany.com")
protected String id;
#XmlElement(name = "Login", namespace="http://mycompany.com")
protected String login;
#XmlElement(name = "Password", namespace="http://mycompany.com")
protected String password;
...
}
ArrayofReport:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ArrayOfReport", propOrder = {
"report"
})
public class ArrayOfReport {
#XmlElement(name = "Report", nillable = true)
protected List<Report> report;
public List<Report> getReport() {
if (report == null) {
report = new ArrayList<Report>();
}
return this.report;
}
}
Webservice call:
#WebMethod(operationName = "GetReports", action = "http://mycompany.com/GetReports")
#WebResult(name = "GetReportsResult", targetNamespace = "http://mycompany.com")
#RequestWrapper(localName = "GetReports", targetNamespace = "http://mycompany.com", className = "com.mycompany.customerportal.server.GetReports")
#ResponseWrapper(localName = "GetReportsResponse", targetNamespace = "http://mycompany.com", className = "com.mycompany.customerportal.server.GetReportsResponse")
public ArrayOfReport getReports(
#WebParam(name = "credentials", targetNamespace = "http://mycompany.com")
ApiCredentials credentials,
#WebParam(name = "includeFields", targetNamespace = "http://mycompany.com")
boolean includeFields);
I recommend creating a mock web service (e.g. using soapUI). This will allow you to see and validate the request XML against your WSDL. You can cut'n'paste/edit mock responses to the client to see the effect.
JAX-WS implementations are a dime-a-dozen, so any further options depend on the client technology in your runtime. I would ensure that validation is enabled (this might be implemented as a feature, for example).
Related
There is an application that was configured and has developed by JAX-WS; the piece of code like this:
#WebService(targetNamespace = "http://webservice.bulk.test.net/", serviceName = "BulkService")
#BindingType(value = SOAPBinding.SOAP12HTTP_BINDING)
#XmlSeeAlso({
ObjectFactory.class
})
public class Bulk {
#WebMethod
#RequestWrapper(localName = "getProvinces", targetNamespace = "http://webservice.bulk.test.net/", className = "test.GetProvinces")
#ResponseWrapper(localName = "getProvincesResponse", targetNamespace = "http://webservice.bulk.test.net/", className = "test.GetProvincesResponse")
#Action(input = "http://webservice.bulk.test.net/Bulk/getProvincesRequest", output = "http://webservice.bulk.test.net/Bulk/getProvincesResponse")
public void getProvinces(
#WebParam(name = "username", targetNamespace = "") #XmlElement(nillable = false, required = true)
String username,
#WebParam(name = "password", targetNamespace = "") #XmlElement(nillable = false, required = true)
String password,
...) {
}
According to this webservice, so many clients(jax-ws clients) are using.
I want to change the jax-ws to jax-rs without changing the client, another hand, the clients have no sens about the changes and do api-call as before.
Is it possible?
I solved this problem by separating soap layer from the application because of some reasons, first, used Jax-rs and Jax-ws endpoints simultaneously and secondly, is technical debt; due to separating soap from application, it is able to migrate to JDK-11 without any problems and thirdly, according to separating Soap from application, it is independent from JAX-WS clients except changing JAX-WS endpoints.
I seem to be butting heads with a limiter somewhere. One of my Spring-Boot REST endpoint (POST) parameters (surveyResults) is looking for a string of JSON:
private static final String SURVEY_RESULTS_ENDPOINT = "/survey/results";
#PostMapping(
value = SURVEY_RESULTS_ENDPOINT,
produces = { "application/hal+json", "application/json" }
)
#ApiOperation(value = "Save one survey results")
public Resource<SurveyResult> createSurveyResults(
#ApiParam(value = "who/what process created this record", required = true) #Valid
#RequestParam(value = "recordCreatedBy", required = true) String createdBy,
#ApiParam(value = "was an issue identified", required = true)
#RequestParam(value = "hadFailure", required = true) Boolean hadFailure,
#ApiParam(value = "JSON representation of the results", required = true)
#RequestParam(value = "surveyResults", required = true) String surveyResult
) ...
If I post to this with about 1500 characters, it works. Somewhere just over that and it will fail with a HTTP 400 error bad request. The whole payload is less than 2K with the other parameters.
I just moved from Wildfly to a new server setup. My company is adopting continuous deployment to cloud servers so i don't have much control nor visibility to this new load balanced server. The server is "server": "openresty/1.13.6.2" - any idea what limit I am running into?
Please use #RequestBody instead of #RequestParam.
#RequestBody annotation maps the HTTP request's body to an object. #RequestParam maps the request parameter in the request, which is in the URL and not in the body.
Most browsers have a limitation to the number of characters supported in a request parameter, and you just hit that limit.
What I would suggest is to create a POJO that looks like this
public class Body {
private String createdBy;
private Boolean hadFailure;
private String surveyResult;
// getters and setters
}
Now your controller will be simpler
#PostMapping(
value = SURVEY_RESULTS_ENDPOINT,
produces = { "application/hal+json", "application/json" }
)
public Resource<SurveyResult> createSurveyResults(#RequestBody Body body) {
}
Wherever you are posting, you will have to now post a JSON (Content-Type = application/json) that looks like the following
{ "createdBy" : "foo", "hadFailure" : false, "surveyResult" : "the foo bar"}
So I'm trying to annotate a method with both JAX-RS and JAX-WS, I've looked at this and FWIW it really isn't a good idea however I got stuck when trying to implement this
#GET
#Path("loginWithEmail")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#WebResult(name = "response")
#WebMethod(operationName = "loginWithEmail")
public BaseResponse loginWithEmail(
#WebParam(name = "sessionId", header = true) String sessionId,
#WebParam(name = "email") String email,
#WebParam(name = "password") String password) {
System.out.println("Session Id is " + sessionId);
}
Passing the sessionId header works perfectly for the SOAP but doesn't for REST - any ideas why and how to resolve?
PS - This is purely experimental and won't be using such in production - just curious to know how to set header - Thank you :)
you have not defined any parameter for restful service you need to make #queryparan or #pathparam or #bean .. it may work
I'm working on a Camel project calling services with CXF.
The services are defined through a wsdl and which I cannot modify it.
I generated classes with wsdl2java: I will have many other remote services, they may change often, so I want to have the POJOs and interfaces to be generated as much as possible.
My generated interface looks like this:
#WebService(targetNamespace = "http://service.company.fr", name = "myService")
#XmlSeeAlso({ObjectFactory.class})
public interface MyService {
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#WebResult(name = "sendMessageResponse", targetNamespace = "http://service.company.fr", partName = "parameters")
#WebMethod
SendMessageResponse sendLetter(
#WebParam(partName = "parameters", name = "sendLetter", targetNamespace = "http://service.company.fr")
SendLetter parameters
) throws MessageServiceException_Exception;
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#WebResult(name = "sendMessageResponse", targetNamespace = "http://service.company.fr", partName = "parameters")
#WebMethod
SendMessageResponse sendWebNotification(
#WebParam(partName = "parameters", name = "sendWebNotification", targetNamespace = "http://service.company.fr")
SendWebNotification parameters
) throws MessageServiceException_Exception;
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#WebResult(name = "sendMessageResponse", targetNamespace = "http://service.company.fr", partName = "parameters")
#WebMethod
SendMessageResponse sendEmail(
#WebParam(partName = "parameters", name = "sendEmail", targetNamespace = "http://service.company.fr")
SendEmail parameters
) throws MessageServiceException_Exception;
}
I defined the CXF Endpoint in an XML file, like this :
<cxf:cxfEndpoint id="serviceEndpoint"
address="http://localhost:9081/soap/service"
serviceClass="fr.company.service.MyService">
<cxf:properties>
<entry key="dataFormat" value="POJO"/>
</cxf:properties>
</cxf:cxfEndpoint>
And finally, I am calling the service in a Camel route :
from(URI_SERVICE)
.process(sendEmailBodyProcessor)
.to("cxf:bean:serviceEndpoint");
The sendEmailBodyProcessor sets the body with a SendEmail object (corresponding to the 3rd service from the interface). If I leave only the service I use in the interface, it works, but if I leave the other services, I get this error:
java.lang.IllegalArgumentException: Part {http://service.company.fr}parameters should be of type fr.company.service.SendLetter, not fr.company.service.SendEmail
at org.apache.cxf.jaxb.io.DataWriterImpl.checkPart(DataWriterImpl.java:292)
at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:220)
at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:117)
at org.apache.cxf.wsdl.interceptors.BareOutInterceptor.handleMessage(BareOutInterceptor.java:68)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
...
I tried using headers like operationName or method etc. but I can't get it to work...
Has anyone a clue on how I can get it to work?
Thanks a lot!
I finally found how to solve my problem!...
In my case, operationName was not enough, I needed to add operationNamespace = "http://service.company.fr" as well!
I use SOAPUI and generate java classes with JAX-WS import.
I have an interface like this
#WebService(name = "test", targetNamespace = "http://lang.java")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
#XmlSeeAlso({
ObjectFactory.class
})
public interface Test{
#WebMethod(action = "https://...action")
#WebResult(name = "getBean", targetNamespace = "http://...getBean", partName = "getBean")
public Bean test(
#WebParam(name = "parameter1", targetNamespace = "http://lang.java", partName = "parameter1")
String parameter1,
#WebParam(name = "parameter2", targetNamespace = "http://lang.java", partName = "parameter2")
String parameter2,
#WebParam(name = "parameter3", targetNamespace = "http://lang.java", partName = "parameter3")
String parameter3,
#WebParam(name = "parameter4", targetNamespace = "http://lang.java", partName = "parameter4")
long parameter4);
}
If I use SOAPBinding.ParameterStyle.WRAPPED the body message generated is
<S:Body>
<ns2:test xmlns:ns2="http://lang.java" xmlns:ns3="http://...getBean">
<ns2:parameter1>1</ns2:parameter1>
<ns2:parameter2>2</ns2:parameter2>
<ns2:parameter3>a</ns2:parameter3>
<ns2:parameter4>1</ns2:parameter4>
</ns2:test>
</S:Body>
If I use SOAPBinding.ParameterStyle.BARE the body message generated is
<S:Body>
<ns2:parameter1 xmlns:ns2="http://lang.java" xmlns:ns3="http://...getBean">1</ns2:parameter1>
</S:Body>
Why is the diference? Why in Bare option it only generates the first parameter? I need that Bare option create all parameters
Its ok! I find the answer here http://www.javajee.com/soap-binding-style-encoding-and-wrapping
Bare option only can use one parameter. When we use Bare, the message request must have zero or one element into Body. The solution is make an object with all parameters we want , and send this object to the method.