Deserializing SOAP response into generated classes C# - java

We are integrating with a third party and are having trouble deserializing the response we get from a request. From fiddler, I can see the response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>
<ns2:updateItemsResponse xmlns:ns2="http://ThirdParty/dmn/items/1.1">
<fileId>bd6e7d83-8bfu-4573-fe32-c67c04355dd0</fileId>
<fileName>12345.MBG_Items.002.2016-10-26-16-23-35.xml</fileName>
</ns2:updateItemsResponse>
But we cannot deserialize it properly into an updateItemsResponse object. The object is created but the fileId and fileName are both null.
We generated the classes for this request and response and below is the class that was generated:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName = "updateItemsResponse", WrapperNamespace = "http://ThirdParty/dmn/items/1.1", IsWrapped = true)]
public partial class updateItemsResponse
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace = "http://ThirdParty/dmn/items/1.1", Order = 0)]
public string fileName;
[System.ServiceModel.MessageBodyMemberAttribute(Namespace = "http://ThirdParty/dmn/items/1.1", Order = 1)]
public string fileId;
public updateItemsResponse()
{
}
public updateItemsResponse(string fileId, string fileName)
{
this.fileId= fileId;
this.fileName= fileName;
}
}
We know the web service was written in Java, and we had some issues generating the class files - the wsdl we were provided needed some jiggery pokery before we were able to create the class files using svcutil.exe. So I think there is just some tweak I need to make in the generated file.
I've done some searching around this and I am guessing the issue here is the namespaces but I cannot get this to work. I've tried changing the namespace, removing the namespace, changing the order for fileId and fileName - but none of these have made any difference.
Anyone able to see anything obvious I might be missing? It's driving me crazy!!!
EDIT: Have tried this changing the fileId and fileName to XmlElement too but still getting null responses.

Eureka!!!
So it was the attributes that were wrong - on fileId and fileName. Just needed to change them to
[System.ServiceModel.MessageBodyMemberAttribute(Name = "fileId", Namespace = "", Order = 0)]
public string fileId;
[System.ServiceModel.MessageBodyMemberAttribute(Name = "fileName", Namespace = "", Order = 1)]
public string fileName;
and I can now deserialize the response.

Related

How to parse dynamic nested paths in spring controller

Hi all I am writing a spring controller to printout the contents of a directory so my controller signature is
#RequestMapping(value = "/listdir/{dirname}")
public ResponseEntity<List<DirectoryItem>> listDirectory(#PathVariable String dirname){
List<DirectoryItem> directories = util.getDirectoryItems(rootFolder + dirname);
I call it with a get:
/listdir/dirname
and it returns a json of the contents of the directory. eg
file1,
file2,
dir1,
dir2,
and so on.
So next what i want is that in the view if the user clicks a directory name, the same method is called.
This time i imagine the call would be
listdir/dirname/dir1
and so on for the next would be
listdir/dirname/dir1/childdir
Does anyone know what's the correct way of accomplishing this?
Thanks
You can use a wildcard in a mapping like this
#GetMapping("listdir/**")
public String listDirectory(HttpServletRequest request) {
String dirname = request.getRequestURI().split(request.getContextPath() + "/listdir/")[1];
// ...
}
but basically for such request you should not use path parameters at all. Instead of this just send the parameter through the request parameter
#GetMapping("all")
public String listDirectory(#RequestParam("dirname") String dirname) {
// ...
}

Spring request mapping with regex like in javax.ws.rs

I'm trying rewrite this Google App Engine maven server repository to Spring.
I have problem with URL mapping.
Maven repo server standard looks like this:
URL with slash at the end, points to a folder, example:
http://127.0.0.1/testDir/
http://127.0.0.1/testDir/testDir2/
all others (without slash at the end) point to files, example:
http://127.0.0.1/testFile.jar
http://127.0.0.1/testFile.jar.sha1
http://127.0.0.1/testDir/testFile2.pom
http://127.0.0.1/testDir/testFile2.pom.md5
Original app mapping for directories and for files.
There were used annotations #javax.ws.rs.Path which supports regexy differently than Spring.
I tried bunch of combinations, for example something like this:
#ResponseBody
#GetMapping("/{file: .*}")
public String test1(#PathVariable String file) {
return "test1 " + file;
}
#ResponseBody
#GetMapping("{dir: .*[/]{1}$}")
public String test2(#PathVariable String dir) {
return "test2 " + dir;
}
But I can't figure out how to do this in right way in Spring application.
I'd like to avoid writing a custom servlet dispatcher.
I had a similar problem once, also regarding a Spring implementation of a maven endpoint.
For the file endpoints, you could do something like this
/**
* An example Maven endpoint for Jar files
*/
#GetMapping("/**/{artifactId}/{version}/{artifactId}-{version}.jar")
public ResponseEntity<String> getJar(#PathVariable("artifactId") String artifactId, #PathVariable("version") String version) {
...
}
This gives you the artifactId and the version, but for the groupId you would need to do some string parsing. You can get the current requestUri with the help of the ServletUriComponentsBuilder
String requestUri = ServletUriComponentsBuilder.fromCurrentRequestUri().build().toUri().toString();
// requestUri = /api/v1/com/my/groupId/an/artifact/v1/an-artifact-v1.jar
For the folder endpoints, I'm not sure if this will work, but you can give it a try
#GetMapping("/**/{artifactId}/{version}")
public ResponseEntity<String> getJar(#PathVariable("artifactId") String artifactId, #PathVariable("version") String version) {
// groupId extracted as before from the requestUri
...
}
Don't know about your java code, but if you are verifying one path at a time, you can just check if the string ends in "/" for a folder and the ones that don't are files
\/{1}$
this regular expression just checks that the string ends with "/" if there is a match, you have a folder, if there is not, you have a file
Well there is no other specific standard in Spring then the way you have used it. However if you can customize URL then I have a special way to differentiate directory and files. That will increase the scalibility and readability of application and will reduce lot of code for you.
Your Code as of now
#ResponseBody
#GetMapping("/{file: .*}")
public String test1(#PathVariable String file) {
return "test1 " + file;
}
#ResponseBody
#GetMapping("{dir: .*[/]{1}$}")
public String test2(#PathVariable String dir) {
return "test2 " + dir;
}
Change above code to as below in your controller class
private final Map<String, String> managedEntities=ImmutableMap.of(
"file","Type_Of_Operation_You_want_For_File",
"directory","Type_Of_Operation_You_want_For_Directory"
);
#GetMapping(path = "/{type:file|directory}")
public String myFileOperationControl(#PathVariable String type){
return "Test"+managedEntities.get(type));
}
And proceed further the way you want to per your business logic. Let me know if you have any questions.
Note: Please simply enhance endpoint per your need.
Spring doesn't allow matching to span multiple path segments. Path segments are delimited values of path on path separator (/). So no regex combination will get you there. Spring 5 although allows the span multiple path segments only at the end of path using ** or {*foobar} to capture in foobar uri template variable for reactive stack but I don't think that will be useful for you.
Your options are limited. I think the best option if possible is to use different delimiter than / and you can use regex.
Other option ( which is messy ) to have catch all (**) endpoint and read the path from the request and determine if it is file or directory path and perform actions.
Try this solution:
#GetMapping("**/{file:.+?\\..+}")
public String processFile(#PathVariable String file, HttpServletRequest request) {
return "test1 " + file;
}
#GetMapping("**/{dirName:\\w+}")
public String processDirectory(#PathVariable String dirName, HttpServletRequest request) {
String dirPath = request.getRequestURI();
return "test2 " + dirPath;
}
Results for URIs from the question:
test2 /testDir/
test2 /testDir/testDir2/
test1 testFile.jar
test1 testFile.jar.sha1
test1 testFile2.pom
test1 testFile2.pom.md5

REST Assured doesn't accept curly brackets

Unable to use query in my Endpoint URL
I have tried using .queryParams() but it does not seem to work . I am getting the following error
java.lang.IllegalArgumentException: Invalid number of path parameters.
Expected 1, was 0.Undefined path parameters are:
cycle-id[12345];test.name[Validate_REST_Assured_Curly_Brackets].
Can someone help me out
almQuery=https://{almurl}/qcbin/rest/domains/{domain}/projects/{project}/test-instances?query={cycle-id[12345];test.name[Validate_REST_Assured_Curly_Brackets]}
Response response = RestAssured.given().relaxedHTTPSValidation()
.contentType("application/xml")
.cookie(cookie) .get(getEntityEndpoint(almQuery)).then().extract().response();
This is how RestAssured implementation works. Whenever your url contains curly braces it will expect path param with for that. For example, if your url contains {project} you should provide a path param with name project.
The only way to avoid it is by manually encoding { and } characters in your url. You could use URLEncoder.encode(), but it will mess your other characters so try simply replacing all { and } with encoded values:
public class App {
public static void main(String[] args) {
String url = "http://www.example.com/path/{project}";
String encoded = encodeUrlBraces(url);
RestAssured.given()
.when()
.get(encoded);
}
private static String encodeUrlBraces(String url) {
return url.replaceAll("\\{", "%7B").replaceAll("}", "%7D");
}
}
Here's an answer for this from Rest Assured founder and contributor https://github.com/rest-assured/rest-assured/issues/682

Rest Assured code not allowing to use println

I am trying to automate twitter API. when tried to print "js.get("text") using
System.out.println(js.get("text")); I am getting error as
"The method println(boolean) is ambiguous for the type PrintStream"
I downloaded jars and passed in Build path as well "scribejava-apis-2.5.3" and "scribejava-core-4.2.0"
Below code is not allowing me use println for ------>js.get("text")
public class Basicfunc {
String Consumerkeys= "**************";
String Consumersecretkeys="*******************";
String Token="*******************";
String Tokensecret="***************************";
#Test
public void getLatestTweet(){
RestAssured.baseURI = "https://api.twitter.com/1.1/statuses";
Response res = given().auth().oauth(Consumerkeys, Consumersecretkeys, Token, Tokensecret).
queryParam("count","1").
when().get("/home_timeline.json").then().extract().response();
String response = res.asString();
System.out.println(response);
JsonPath js = new JsonPath(response);
System.out.println(js.get("text"));
}
}
Use System.out.println(js.getString("text")); instead of System.out.println(js.get("text"));, because get returns any primitive value.
I think your problem is that your twitter response is actually a list.
Try to use System.out.println(js.getList()[0].get("text")); and be aware that you are only using the first [0] entry and ignoring the rest.

Json From .Net Server to android client

I'm trying to call a ApiController from android apllication.
This is the api controller:
[AcceptVerbs("GET", "POST")]
public string Get(string coords)
{
using (var context = new Entities())
{
var records = from poi in context.Pois
where poi.Latitude >= fromLatitude &&
poi.Latitude <= toLatitude &&
poi.Longitude >= fromLongitude &&
poi.Longitude <= toLongitude
select new
{
poiName = poi.Name,
poiLatitude = poi.Latitude,
poiLongitude = poi.Longitude
};
return JsonConvert(records);
}
}
}
private string JsonConvert(object records)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(records,);
}
At the android code, I'm creating json array with new JSON(string).
The problem is java throws an excetpion: the json string is not valid.
When i look at the debuuger, I see that the string have 2 backslash before ",
and java dont know how to parse that.
Where is the problem?
Thank you
Update: Solved. The WebApi returned XML with the json as string. changed the WebApi Not to return XML, then changed it to return object (and removed the JSONConvert) - and it works.
I know this is an old question, but i had a similar problem and found a solution.
In my case i had to pass a complex JSON object (nested) from a .NET Client to a Java Rest API and was using a string parameter which turned out to be an invalid JSON due to the double backslash (I seralized it so it was escaped and then .NET escaped it again before sending).
So, in order to avoid that i used StringContent
MyType obj = new MyType()
{
...
};
string obJSON = JsonConvert.SerializeObject(obj);
StringContent sc = new StringContent(obJSON, Encoding.UTF8,"application/json");
HttpResponseMessage response = client.PostAsync(ruta, sc).Result;
Hope this helps someone!

Categories