I have a problem with me web service which I created in Java. This web service is to send data to my mobile application created in Swift.
For now I just want to test communication between application and WebService, so I create one simple method which returns a string.
My WebService:
#WebService(serviceName = "mSetiWebService", targetNamespace = "http://javawebservices.dawidratajczak.pl")
#SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL, parameterStyle = ParameterStyle.WRAPPED)
public class mSetiWebService {
#WebMethod(operationName = "getMyOtherStuff", action="getMyOtherStuffAction")
public String getMyOtherStuff() {
return "Hello from WebService !";
}
}
The java package(namespace) name is pl.dawidratajczak.webservices. I test this WebService by Boomerang Plugin for chrome and it works fine. But when I use SOAPEngine for Swift a get an error.
My Swift code:
let soap = SOAPEngine()
soap.userAgent = "SOAPEngine"
soap.actionNamespaceSlash = true
soap.version = SOAPVersion.VERSION_1_1
soap.responseHeader = true // use only for non standard MS-SOAP service
soap.requestURL("http://localhost:8080/mSetiSoapService/mSetiWebService",
soapAction: "getMyOtherStuff",
completeWithDictionary: { (statusCode : Int,
dict : [NSObject : AnyObject]!) -> Void in
let result:Dictionary = dict as Dictionary
NSLog("%#", result)
}) { (error : NSError!) -> Void in
NSLog("%#", error)
}
The error is simple: (I change . in address to _)
SOAPEngine Server response: Unexpected wrapper element getMyOtherStuff found. Expected {[httpjavawebservices_dawidratajczak_pl}getMyOtherStuff.
2016-08-26 20:24:59.835 SETI Mobile[4658:200526] Error Domain=NSOSStatusErrorDomain Code=0 "Unexpected wrapper element getMyOtherStuff found. Expected {http://javawebservices_dawidratajczak_pl}getMyOtherStuff." UserInfo={NSLocalizedDescription=Unexpected wrapper element getMyOtherStuff found. Expected {javawebservices_dawidratajczak_pl}getMyOtherStuff.}**
When I put the soapAction like the error expect {url}getMyOtherStuff I get another error that character { is unrecognized. At the end when I put all url and soapActionme function is not found.
What I do wrong?
Related
I am having the below JAVA Class :
#WebService()
#SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL, parameterStyle = ParameterStyle.BARE)
public class Demo extends JaxWsWebService
{
#WebMethod(operationName = "createMethod")
#WebResult(targetNamespace = "xyz.com/")
#RequestWrapper(localName = "Testing", targetNamespace = "xyz.com/", className = "com.Test")
public void createMethod(Testing testingData) throws SOAPException {
System.out.println(" createMethod service --- xId = " + testingData.getXId() "); // xId is coming as NULL
System.out.println(" createMethod service --- name = " + testingData.getName() "); // name is coming as NULL
}
}
Now I am calling the above JAVA method using my SOAP XML Request which is below :
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS1="xyz.com/">
<x:Header/>
<x:Body>
<NS1:createMethod>
<NS1:Testing>
<xId>12345</xId>
<name>abcd</name>
</NS1:Testing>
</NS1:createMethod>
</x:Body>
</x:Envelope>
Now, when I am calling the SOAP request using the SOAP client, the call is successful and is going inside the JAVA method but the main issue is the "testingData" instance of "Testing" class is not getting initialized.
Due to this, I am getting the value of 'xId' and 'name' variable as NULL in my JAVA method. Any suggestions on this would be helpful it looks like I am making mistake in my SOAP request calling but unable to figure it out.
Please suggest. TIA
Got the place where I was going wrong :
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS1="xyz.com/">
<x:Header/>
<x:Body>
<NS1:createMethod>
<xId>12345</xId>
<name>abcd</name>
</NS1:createMethod>
</x:Body>
</x:Envelope>
In the XML request , I removed the <NS1:Testing> starting and ending </NS1:Testing> tags and finally it started working for me.
I'm trying to send a PUT request from angular5 to to spring API , but i'm getting an error .
This is angular intervention.service.ts :
updateIntervention(id:number){
if(this.authService.getToken()==null) {
this.authService.loadToken();
}
return this.http.put(this.host+"/updateIntervention/"+id,
{headers:new
HttpHeaders({'Authorization':this.authService.getToken()})});
}
Intervention.component.ts
valider(ref: Intervention){
this.intervService.updateIntervention(ref.id)
.subscribe((data:any)=>{
console.log('there is no error ! ');
},err=>{
console.log('there is an error ! ');
})
ref.valid = !ref.valid;
}
In Spring-boot :
#RequestMapping(value="/updateIntervention/{id}",method = RequestMethod.PUT)
public Intervention update(#PathVariable Long id){
System.out.println("in intevention update");
Intervention I = new Intervention();
I = interventionRepo.getOne(id);
I.setValid(true); // it's boolean , this is the goal from this update
interventionRepo.save(I);
return I
}
As error i get in angular :
{"timestamp":1527443447949,"status":401,"error":"Unauthorized"}
As error In spring-boot :
access.AccessDeniedException: Access is denied
PS : this works when i send in angular both id and the object Ref , in spring , i write
public Intervention update(#PathVariable Long id , #RequestBody Intervention I){ ... }
But i don't need this as all what i want is to modify the attribut valid in the entity Intervention .
I'm using httpClient .
Any idea ?
The put method you are using has the following definition:
put(url: string, body: any | null, options)
You are providing the options object as a body parameter.And that's why you are getting unauthorized 401 which stands for "unauthenticated". Means that you have wrong or missing credentials.
You should change
return this.http.put(this.host+"/updateIntervention/"+id,
{headers:new
HttpHeaders({'Authorization':this.authService.getToken()})});
}
To:
return this.http.put(this.host+"/updateIntervention/"+id,
null,
{headers:new
HttpHeaders({'Authorization':this.authService.getToken()})});
}
I´m using graphDSL of akka stream to create a DSL for my test framework, but now that I´m looking how works I dont think it fit well.
My concern is that it seems like when I make an assert(false) in one of the flows instead of propagate the error in the test it´s getting stuck
I dont know if I´m doing something wrong
My DSL implementation looks like:
def given(message: String, musVersion: MUSVersion = ONE) = Source.single(new message(message, musVersion))
def When(sentence: String) = Flow[message].map(message => {
try {
HttpClient.request(message._1, message._2)
} catch {
case e: Exception => {
HttpResponse[String](e.getMessage, 500, Map())
}
}
})
def Then(sentence: String) = Sink.foreach[HttpResponse[String]](response => {
assert(false)
thenAction(sentence, response)
println(s"######## $x")
})
Like I said my test it get stuck instead mark the test as failure because of the assert.
Here my Test code:
class TestDSL extends MainDSL {
private def generateKey(): String = s"""${UUID.randomUUID().toString}"""
implicit val config = this.getRequestConfig("cassandra")
val message: String = Messages.message(path = "cassandra", key = "Cassandra " + generateKey())
info("This test has as requirement create and find an Entity using cassandra connector")
feature("First DSL") {
scenario(s"This is a prove of concept of the DSL") {
RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>
given(message) ~> When("I make a request") ~> Then("The return code='200'") ~> AndThen("The payload is not empty")
ClosedShape
}).run()
}
}
}
Any idea what´s wrong?.
Regards.
Following is the log of my current json body. And I want to add new property to this body. "NewPropertyName": "value". Since the value is in a database I am using a class mediator to add this property.
[2015-05-18 05:47:08,730] INFO - LogMediator To: /a/create-project, MessageID: urn:uuid:b7b6efa6-5fff-49be-a94a-320cee1d4406, Direction: request, _______BODY_______ =
{
"token": "abc123",
"usertype":"ext",
"request": "create"
}
Class mediator's mediate method,
public boolean mediate(MessageContext mc) {
mc.setProperty("key", "vale retrived from db");
return true;
}
but this doesn't work as I expected. I couldn't find any guide to add property to json body using class mediator, please help.
To inject a property to the body you have to use following code snippet,
JsonUtil.newJsonPayload(
((Axis2MessageContext) context).getAxis2MessageContext(),
transformedJson, true, true);
inside a class mediator. Following is an example of mediate method.
/**
* Mediate overridden method to set the token property.
*/#Override
public boolean mediate(MessageContext context) {
try {
// Getting the json payload to string
String jsonPayloadToString = JsonUtil.jsonPayloadToString(((Axis2MessageContext) context)
.getAxis2MessageContext());
// Make a json object
JSONObject jsonBody = new JSONObject(jsonPayloadToString);
// Adding the name:nameParam.
jsonBody.put("name", getNameParam());
String transformedJson = jsonBody.toString();
// Setting the new json payload.
JsonUtil.newJsonPayload(
((Axis2MessageContext) context).getAxis2MessageContext(),
transformedJson, true, true);
System.out.println("Transformed JSON body:\n" + transformedJson);
} catch (Exception e) {
System.err.println("Error occurred: " + e);
return false;
}
return true;
}
You will need json and other libraries for this. This is fully explained in following blog post.
json-support-for-wso2-esb-class-mediator
mc.setProperty is used to create a new property as if you were using property mediator.
If you want to add a new element inside your message, in java, you can handle it as if it were a XML message (for exemple, to get the first element :
OMElement element = (OMElement) context.getEnvelope().getBody().getFirstOMChild(); )
Sample to add a new element with a javascript :
<script language="js"><![CDATA[
var payloadXML = mc.getPayloadXML();
payloadXML.appendChild(new XML(<NewPropertyName>value</NewPropertyName>));
mc.setPayloadXML(payloadXML);
]]></script>
Log the message in XML with <log level="full"> and you get :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<jsonObject>
<token>abc123</token>
<usertype>ext</usertype>
<request>create</request>
<NewPropertyName>value</NewPropertyName>
</jsonObject>
</soapenv:Body>
</soapenv:Envelope>
Log the message in JSON with
<log>
<property name="JSON-Payload" expression="json-eval($.)"/>
</log>
and you get :
JSON-Payload = {"token":"abc123","usertype":"ext","request":"create","NewPropertyName":"value"}
I am trying to get the request url without values of path parameters into it.
Consider my complete url is
URl: http://localhost:8080/aaa/mock/abcd/1234/true
Path parameters: abcd, true
Output needed: /aaa/mock/abcd
My web service method looks like this.
#Path(value = "/aaa/mock")
#Component
public class MockService
{
private static Log log = LogFactory.getLog(MockService.class);
//address
#GET
#Path(value = "/{mockrequest}/{status}")
#Produces(MediaType.JSON)
public String mockEngagement(#Context ContainerRequestContext request,#PathParam("mockrequest") String mockrequest,#PathParam("status") String status )
{
log.info("The mock url is"+request.getUriInfo().getRequestUri());
log.info("The mock url is"+request.getUriInfo().getAbsolutePath());
log.info("The mock url is"+request.getUriInfo().getBaseUri());
log.info("The mock url is"+request.getUriInfo().getMatchedURIs());
**//Out put needed /aaa/mock/abcd**
return "ajaja";
}
}
None of the above calls return the required info.
I am thinking if there is a generic process to get the desired output irrespective of number of path parameters.
Any such methods.
Try UriInfo#getPath(), UriInfo#getPath(boolean), or UriInfo#getPathSegments(). The boolean argument is whether the path should be encoded or not.
https://jersey.java.net/apidocs/2.3.1/jersey/index.html
You could also get the absolute path and the base path and then use URI#relativize(URI).
Try this:
request.getUriInfo().getPathSegments().get(0).getPath()
public void filter(ContainerRequestContext context) throws IOException {
Message message = PhaseInterceptorChain.getCurrentMessage();
Set<Map.Entry<String, Object>> o = (Set<Map.Entry<String, Object>>)message.entrySet();
for (Map.Entry<String, Object> oo : o) {
String key = oo.getKey();
Object val = oo.getValue();
// Thises two properties gives the path of web service
//path_to_match_slash
//org.apache.cxf.request.uri
if(key.equals("path_to_match_slash"))
{ String v = (String)val;
System.out.println (key);
System.out.println (v);
}
if(key.equals("org.apache.cxf.request.uri"))
{ String v = (String)val;
System.out.println (key);
System.out.println (v);
}
}
}
this code could work only for apache cxf rest
we can found path_to_match_slash , org.apache.cxf.request.uri properties in the ContainerRequestContext