I have kind of a stupid question, but since I can't figure it out I figured I'd post it here to see if anyone can help!
I have some code that makes an HttpPost request to our server. I receive the results perfectly in an XML format. The problem is I want to get the boolean value that is returned, not just a String. So for example, a successful call to the web service returns this xml:
<boolean xmlns="https://myWebService/">false</boolean>
which I can access and read by using this line:
String responseBody = EntityUtils.toString(response.getEntity());
Is there a way to access the data returned (false, in this case) as a boolean, or will I have to manually parse the return String to get the value?
Thanks for your help
will I have to manually parse the return String to get the value?
Yes, but you can simply roll your own method that does the parsing (and etc.) and then returns a boolean.
public boolean asBoolean(Entity e){
return Boolean.parseBoolean(EntityUtils.toString(e));
}
Related
I have an HTTP GET request controller endpoint where I take in a fileName as a query param and pass that on to another service. For this request the param the filename could include any sort of special characters and I would like to keep these values encoded when passing them on. 2 Characters that have been causing issues are spaces (%20) and +(%2B).
How can I keep these characters encoded in the request params.
So far I have tried using the #RequestParam annotation as well as retrieving the params via HttpServletRequest.getParameterValues(String) but both return the decoded values as spaces.
Any help is appreciated thanks!
Yes, these are automatically decoded by the servlet API. You should be able to re-encode them -
encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8);
I found out that I could get the actual value passed in by using the HttpServletRequest.getQueryString() method. Parsing this query string I was able to get the un-decoded version of the fileName being passed in. I hope this helps someone in the future.
I am trying to write code using RestTemplate exchange to query an API that returns song info. The problem is that the data looks like this when data is found but
{"search":[{"song_id":"4R9o2J","song_title":"xxxx", ...}]
but like this if the song is not found
{"search":{"error":"no result"}}
When reading valid data my result object looks like this
Data
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonInclude(JsonInclude.Include.NON_NULL)
public class SongSearch {
List<SongInfo> search;
}
The problem is that when the data is valid, there is no property to contain the array of info... it is the contents of the "search": [{....}] so I can't create a property that will get ignored when it is not found even though the not found message has an error property. In other words, the search property can contain an array OR a single property depending on whether data was found or not.
My exchange call looks like this:
ResponseEntity<SongSearch> res = restTemplate.exchange(url, HttpMethod.GET, entity, SongSearch.class);
I've been able to write code that catches the deserialization exception in the not found case but the exception does not contain the actual error message from the API, which I'd want to return. I am currently able to hack it by making a call again with a different object to capture the error but that seems insane. There MUST BE a better way to do this. Just to be clear, this is not an actual error status returned from the client... the data is just different but it breaks the deserialization.
Anyone have suggestions?
I am getting some JSON values from the server but I don't know if there will be a particular field or not.I need to validate based on the key .
One Type Of Response
Another Type Of Response
In AysncTask we can use "has" function but in Retrofit i am unable to find a solution .
Provide me a solution
Retrofit will parse all attributes that you specified in your model. If some attribute in your JSON does not exist Retrofit will set NULL as the value of that attribute.
Knowing this feature, the only thing that you need to do is something like:
if(myObject.getReviewerDetails() == null)
// do something
Happy code!
You can check key exist or not using jsonObject.has like following way,
JSONObject jsonObject=new JSONObject();
if(jsonObject.has("reviewer_details")){
//do process with data
}
I asked something like this previously, but upon re-reading my original post, it was not easy to understand what I was really asking. I have the following situation. We have (or at least I'm trying to get working) a custom file upload procedure that will take in the file, a set number of 'known' metadata values (and they will always be there), as well as potentially an unknown number of additional metadata values. The service that exists currently uses the Jersey framework (1.16)
I currently have both client and server code that handles dealing with the file upload portion and the known metadata values (server code below)
#POST
#Path("asset/{obfuscatedValue0}/")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public UUID uploadBlob(#PathParam("obfuscatedValue0") Integer obfuscatedValue0,
#FormDataParam("obfuscatedValue1") String obfuscatedValue1,
#FormDataParam("obfuscatedValue2") String obfuscatedValue2,
#FormDataParam("obfuscatedValue3") String obfuscatedValue3,
#FormDataParam("obfuscatedValue4") String obfuscatedValue4,
#FormDataParam("obfuscatedValue5") String obfuscatedValue5,
#FormDataParam("file") InputStream uploadedInputStream) {
.....
}
...and excerpt of client code:
Builder requestBuilder = _storageService
.path("asset")
.path(obfuscatedValue0.toString())
.type(MediaType.MULTIPART_FORM_DATA)
.accept(MediaType.APPLICATION_JSON);
FormDataMultiPart part = new FormDataMultiPart()
.field("file", is, MediaType.TEXT_PLAIN_TYPE) // 'is' is an inputstream from earlier in code.
.field("obfuscatedValue1", obfuscatedValue1)
.field("obfuscatedValue2", obfuscatedValue2)
.field("obfuscatedValue3", obfuscatedValue3)
.field("obfuscatedValue4", obfuscatedValue4)
.field("obfuscatedValue5", obfuscatedValue5);
storedAsset = requestBuilder.post(UUID.class, part);
However, I need to pass a map of additional parameters that will have an unknown number of values/names. From what I've seen, there is no easy way to do this using the FormDataParam annotation like my previous example.
Based upon various internet searches related to Jersey file uploads, I've attempted to convert it to use MultivaluedMap with the content type set to "application/x-www-form-urlencoded" so it resembles this:
#POST
#Path("asset/{value}/")
#Consumes("application/x-www-form-urlencoded")
public UUID uploadBlob(#PathParam(value), MultivaluedMap<String,String> formParams) {
....
}
It's my understanding that MultivaluedMap is intended to obtain a general map of form parameters (and as such, cannot play nicely together in the same method bearing #FormDataParam annotations.) If I can pass all this information from the Client inside some sort of map, I think I can figure out how to handle parsing the map to grab and 'doMagic()' on the data to get what I want done; I don't think I'll have a problem there.
What I AM fairly confused about is how to format the request client-side code when using this second method within the jersey framework. Can anyone provide some guidance for the situation, or some suggestions on how to proceed? I'm considering trying the solution proposed here and developing a custom xml adapter to deal with this situation, and sending xml instead of multipart-form-data but I'm still confused how this would interact with the InputStream value that will need to be passed. It appears the examples with MultivaluedMap that I've seen only deal with String data.
I need help. In my current development one of the requirements says:
The server will return 200-OK as a response(httpresponse).
If the panelist is verified then as a result, the server must also
return the panelist id of this panelist.
The server will place the panelist id inside the body of the 200-OK
response in the following way:
<tdcp>
<cmd>
<ack cmd=”Init”>
<panelistid>3849303</panelistid>
</ack>
</cmd>
Now I am able to put the httpresponse as
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
And I can put
String responseToClient= "<tdcp><cmd><ack cmd=”Init”><panelistid>3849303</panelistid></ack></cmd></tdcp>";
Now what does putting the above xml inside the body of 200-OK response mean and how can it be achieved?
You can write the XML directly to the response as follows:
This example uses a ServletResponse.getWriter(), which is a PrintWriter to write a String to the response.
String responseToClient= "<tdcp><cmd><ack cmd=”Init”><panelistid>3849303</panelistid></ack></cmd></tdcp>";
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
httpServletResponse.getWriter().write(responseToClient);
httpServletResponse.getWriter().flush();
You simply need to get the output stream (or output writer) of the servlet response, and write to that. See ServletResponse.getOutputStream() and ServletResponse.getWriter() for more details.
(Or simply read any servlet tutorial - without the ability to include data in response bodies, servlets would be pretty useless :)
If that's meant to be XML, Word has already spoiled things for you by changing the attribute quote symbol to ” instead of ".
It is worth having a look at JAXP if you want to generate XML using Java. Writing strings with < etc. in them won't scale and you'll run into problems with encodings of non-ASCII characters.