Unable to send request parameter using Spring RestTemplate client to HttpServeletRequest doPost - java

I am using Spring RestTemplate client to do a POST call to another application which handles this request as HTTpServletRequest.
Problem is HTTpServletRequest is expecting a key value pair e.g.
String xmlString = request.getParameter("xml12")
//xmlString should be "`<parent><child></child></parent>`" but coming as null.
Here is the code snippet of both ends -
My app -
String data = "`<parent><child></child></parent>`"
HttpHeaders header = new HttpHeaders()
header.setContentType(MediaType.APPLICATION_XML)
Map<String,String> bodyParamMap = new HashMap<String,String>();
bodyParamMap.put("xml123",data)
String reqBodyData = new ObjectMapper().writeValuesAsString(bodyParamMap)
HttpEntity<String> entity = new HttpEntity<String>(reqBodyData,header)
RestTemplate rt = new RestTemplate()
String response = rt.postForObject("url",entity,String.class)
//Getting response as 500
Other app -
HttpServletRequest request = new HttpServletRequest()
String xmlString = request.getParameter("xml123")
// xmlString is null
I just want to know my mistake and how to pass my data string to post request so that request.getParameter("xml123") receives my data xml as String.

Related

RestTemplate.exchange with JSON

I have two services (one service calls an end point localhost:7000/create to send a json and want expects a json )
Called service is something like this (Data is pojo class) :
#RequestMapping(value="/create",consumes="application/json",produces = "application/json",method = RequestMethod.POST)
#ResponseBody
public Data responseForPayload(#RequestBody String data) {
Data data= new Data();
data.setAccountId("45");
return data;
}
and the calling service restTemplate call is like this (running in :9000):
String ResourceUrl = "http://localhost:7000/create";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
List list= new ArrayList();
list.add(MediaType.APPLICATION_JSON);
HttpEntity httpEntity = new HttpEntity(downstreamPayload, headers);
ResponseEntity<JSONObject> response = restTemplate.exchange(ResourceUrl,
HttpMethod.POST, httpEntity, JSONObject.class);
but i am getting response as {}, when I use string instead of JSON it works fine. I used postman to just to call the 127.0.0.1:7000/create, it worked fine with returning the expected as json
What is my mistake here?
Thanks

Calling RESTlet API from Spring Framework

I have a POST API written in Restlet framework which accepts the data in org.restlet.representation.Representation form, I want to hit the service with some variables and there values from Spring project. How to do that?
Right now I am using the HTTPHeaders to send the data but the API is not accepting the values, all the fields the API is showing as NULL. The code is as follows:
final String uri = "http://localhost:8080/MyServices/adduser";
String userid = "05580a6caa7244a6986ca834403f1a93";
String usertype = "buyer";
String username = "shivam42";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add("userid", userid);
headers.add("usertype", usertype);
headers.add("username", username);
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class);
System.out.println(result);
And the service is like this:
#Post
public String newUser(Representation entity) {
Form form = new Form(entity);
String userid = form.getValues("userid");
String usertype = form.getValues("usertype");
String username = form.getValues("username");
System.out.println(userid);
System.out.println(usertype);
System.out.println(username);
return userid;
}
This is the code generated from curl Maybe someone can help me with this:
curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: 33e6a1c5-c1c9-694f-3d7f-26cbcea61870" -H "Content-Type: application/x-www-form-urlencoded" -d 'userid=05580a6caa7244a6986ca834403f1a93&usertype=buyer&username=shivam42' "http://localhost:8080/MyServices/adduser"
When I am calling the API from POSTMAN it is giving me the correct userid, now how to call it from Spring project? Am I doing something wrong?
#Shivam Thanks for updating the question. With the curl command in place I now see that the data you basically wanted to send is inside the request's body. Therefore the first approach with HttpHeaders won't work. Here's an example of how it could look like for your first approach using the exchange method of Springs RestTemplate:
#Test
public void test() {
RestTemplate restTemplate = new RestTemplate();
final String uri = "http://localhost:8080/adduser";
String userid = "05580a6caa7244a6986ca834403f1a93";
String usertype = "buyer";
String username = "shivam42";
// create request body
JSONObject request = new JSONObject();
request.put("userid", userid);
request.put("usertype", usertype);
request.put("username", username);
// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(request.toString(), headers);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class);
System.out.println(result.getBody());
}
This should also work as expected and return the userid. See also POST request via RestTemplate in JSON for further information.
From the Spring forum I found the solution to this.
Now my code is:
final String uri = "http://localhost:8080/MyServices/adduser";
String userid = "05580a6caa7244a6986ca834403f1a93";
String usertype = "buyer";
String username = "shivam42";
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("userid", userid);
params.add("usertype", usertype);
params.add("username", username);
RestTemplate restTemplate = new RestTemplate();
HttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
HttpMessageConverter stringHttpMessageConverternew = new StringHttpMessageConverter();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(stringHttpMessageConverternew);
messageConverters.add(formHttpMessageConverter);
restTemplate.setMessageConverters(messageConverters);
System.out.println(restTemplate.postForObject(uri, params, String.class));
In my case I am also getting the expected result If I exclude the following code:
HttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
HttpMessageConverter stringHttpMessageConverternew = new StringHttpMessageConverter();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(stringHttpMessageConverternew);
messageConverters.add(formHttpMessageConverter);
restTemplate.setMessageConverters(messageConverters);

spring android resttemplate encoding url

I use Spring android RestTemplate to execute GET request to Youtube API like this:
// build rest template
RestTemplate restTemplate = new RestTemplate();
GsonHttpMessageConverter jsonConverter = new GsonHttpMessageConverter();
FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
final List<HttpMessageConverter<?>> listHttpMessageConverters = restTemplate.getMessageConverters();
listHttpMessageConverters.add(jsonConverter);
listHttpMessageConverters.add(formHttpMessageConverter);
listHttpMessageConverters.add(stringHttpMessageConverter);
restTemplate.setMessageConverters(listHttpMessageConverters);
Uri.Builder uriBuilder = Uri.parse(https://www.googleapis.com/youtube/v3/channels).buildUpon();
uriBuilder.appendQueryParameter("key", API_KEY);
uriBuilder.appendQueryParameter("part", "id,snippet");
uriBuilder.appendQueryParameter("forUsername", channelName);
String url = uriBuilder.build().toString(); // this is right url
// like this: https://www.googleapis.com/youtube/v3/channels?key=MY_KEY&part=id%2Csnippet&forUsername=cnn
MyEntity result = restTemplate.getForObject(url, MyEntity.class);
From debug, I can see RestTemplate execute wrong url and I got 400 bad request error:
03-16 12:06:47.651: W/RestTemplate(24970): GET request for
"https://www.googleapis.com/youtube/v3/channels?key=MY_KEY&part=id%252Csnippet&forUsername=cnn"
resulted in 400 (Bad Request); invoking error handler
I have no idea why RestTemplate try to encode parameter url again, from id%2Csnippet to id%252Csnippet
Is there any way to correct it?
It just so happens that the RestTemplate#getForObject(..) method that expects a String builds a URI from the given String and encodes it before using it. It uses custom Spring classes to do this. (See the source code.)
You can fix this issue by creating a URI object from your String and pass that to the method.
String url = uriBuilder.build().toString(); // this is right url
URI uri = new URI(url);
MyEntity result = restTemplate.getForObject(uri, MyEntity.class);

Trying to use bing translator API with Robospice in Android

I need to implement robospice for doing the networking part in my Translator app. I previously used async task class and it was working fine, but now i want to improve my application with implementing robospice. I'am trying to execute the following code but it doesn't't throw any exception it just never executes....
#Override
public TranslatedText loadDataFromNetwork() throws Exception {
String jsonString = getJsonString();
String headerValue = getHeaderValue(jsonString);
String text = pair.getWordPairs().getWordFrom();
String languageFrom = pair.getLanguagePairs().getLanguageFrom().getCode();
String languageTo = pair.getLanguagePairs().getLangougateTo().getCode();
String uri = String
.format("http://api.microsofttranslator.com/v2/Http.svc/Translate?text=%s&from=%s&to=%s&contentType=text/html",
URLEncoder.encode(text, "UTF-8"),
URLEncoder.encode(languageFrom, "UTF-8"),
URLEncoder.encode(languageTo, "UTF-8"));
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", headerValue);
// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
// Add the Simple XML message converter
getRestTemplate().getMessageConverters().add(new SimpleXmlHttpMessageConverter());
//set the headerValue in the Entity
org.springframework.http.HttpEntity<?> request = new org.springframework.http.HttpEntity<Object>(headerValue);
// Make the HTTP GET request, marshaling the response from XML to an
// EventList
Log.v("request","Making request!");
//This line never finish execuitng, doesen't throw exception or anything in logCat
ResponseEntity<Object> responseEntity = getRestTemplate().exchange(uri, HttpMethod.GET, request, null);
Log.v("request", responseEntity.getBody().toString());
Log.d("Load Data From Network", request.getBody().toString());
return null;
}
The last thing it shows in log cat is Request First!! And nothing after that. It never even gets to The Request Listener onRequestFailure.
Can any 1 tell me what i do wrong ?
This is what look weird to me in your code:
ResponseEntity<Object> and null as 4th parameter of the exchange method are not correct. You need to provide a type which represents the response you get from the server.
The object returned by loadDataFromNetwork() is what you will get in the onRequestSuccess() method. Returning null is not a good idea, in my opinion.
I fixed the problem. So if you need to handle stream you will have to provide the following code
ResponseEntity<byte[]> responseEntity = getRestTemplate().exchange(uri, HttpMethod.GET, request, byte[]);

Calling an RESTFul using Spring-Android

Here is my Strifified json,
{
"Request":{
"Object1":{
"Key1":"Value1"
},
"Object2":{
"Key2":"Value2"
}
},
"Object3":{
"Key3":"Value3"
}
}
I am forming this using Gson. String Stringifiedjson = new Gson().toJson(user);
Here is what i am trying to achive.
RestTemplate rest = new RestTemplate();
String url = "";
String event = rest.getForObject(url, Stringifiedjson);
How would i send to my REST Service and get back my result in onEventHandler or onErrorHandler. I am basically from JavaScript background.
Why does the method getForObject does not accept String, String as params.
Update:
AuthenticateUser user = new AuthenticateUser(credential, Header);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(new MediaType("application","json"));
//HttpEntity<AuthenticateUser> requestEntity = new HttpEntity<AuthenticateUser>(user, requestHeaders);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
String url = "url";
String result = restTemplate.postForObject(url, AuthenticateUser.class, String.class);
Attached is the pastie of what exception i am getting.
http://pastie.org/private/efyfvvbxyxdsvm3lvv7q
About the second question: I just found this example (you could take a look at the entire doc ;) )
2.7.1 Basic Usage Example
The following example shows a query to google for the search term "SpringSource".
String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={query}";
// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
// Add the String message converter
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
// Make the HTTP GET request, marshaling the response to a String
String result = restTemplate.getForObject(url, String.class, "SpringSource");
getForObject
public <T> T getForObject(URI url,
Class<T> responseType)
throws RestClientException
Description copied from interface: RestOperations
Retrieve a representation by doing a GET on the URL . The response (if any) is converted and returned.
Specified by:
getForObject in interface RestOperations
Parameters:
url - the URL
responseType - the type of the return value
Returns:
the converted object
Throws:
RestClientException
The exception in your stacktrace could be related to the same issue of this post. The problem occurs when your app tries to make a connection in the main thread.
10-23 15:46:10.106: E/AndroidRuntime(1038): FATAL EXCEPTION: main
10-23 15:46:10.106: E/AndroidRuntime(1038): android.os.NetworkOnMainThreadException
The NetworkOnMainThreadException is thrown when you execute any network operation in your application main ui thread (see also Keeping Your App Responsive. This is not allowed. You'll have to use a background thread for network operation, see Worker threads on http://developer.android.com/guide/components/processes-and-threads.html

Categories