How to send POST request through RestTemplate with custom parameter in header - java

I need to send post request with custom parameter("data" containing path) and set content type as text/plain. I looked through a ton of similar question but none of the solutions posted helped.
The method should list files from this directory.
my code is
public List<FileWrapper> getFileList() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("data", "/public/");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(
map, headers);
String url = "http://192.168.1.51:8080/pi/FilesServlet";
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
String response = restTemplate
.postForObject(url, request, String.class);
List<FileWrapper> list = new ArrayList<>();
for (String part : response.split("\\|")) {
System.out.println("part " + part);
list.add(new FileWrapper(part));
}
return list;
}
Here's working code equivalent written in javascript:
function getFileList(direction){
$("div.file-list").html("<center><progress></progress></center>");
$.ajax({
url: "http://192.168.1.51:8080/pi/FilesServlet",
type: "POST",
data: direction ,
contentType: "text/plain"
})
The parameter is not added as the request returns empty string meaning the path is not valid. The expected response is file_name*file_size|file_name*file_size ...
Thanks in advance.

From the discussion in the comments, it's quite clear that your request object isn't correct. If you are passing a plain string containing folder name, then you don't need a MultiValueMap. Just try sending a string,
String data = "/public/"
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
HttpEntity<String> request = new HttpEntity<String>(
data, headers);
String url = "http://192.168.1.51:8080/pi/FilesServlet";
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
String response = restTemplate
.postForObject(url, request, String.class);

Related

RestTemplate POST with query parameter without request body

I am trying a POST method with RestTemplate. I need my request to have only 1 query parameter, without body (e.g. localhost:8080/predictions/init?date=xxxx).
My current code is the following :
String url = "http://localhost:8080/predictions/init";
String dateToGenerate = "xxxx";
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
Map map = new HashMap<String, String>();
map.put("Content-Type", "application/json");
headers.setAll(map);
Map req_payload = new HashMap();
req_payload.put("date", dateToGenerate);
HttpEntity<?> request = new HttpEntity<>(req_payload, headers);
restTemplateApi.postForEntity(url, request, String.class);
The side of the REST controller I'm trying to call is the following :
#PostMapping
#ResponseStatus(HttpStatus.OK)
public PredictionGenerated initializeOnePrediction(#RequestParam #NotEmpty String date) {
.............................
.............................
}
I'm currently receiving org.springframework.web.client.HttpClientErrorException: 400 null.
Any ideas?
If you have any many query param then set all in Multiple value Map as below.
MultiValueMap<String, String> param= new
LinkedMultiValueMap<String, String>();
param.put("date", datevalue);
Then create Http header add required content.
HttpHeaders headers = new HttpHeaders()
header.setContentType("application/json");
Create the URL as below.
URI url = UriComponentsBuilder.fromHttpUrl(base url)
.queryParams(param)
.build();
HttpEntity<?> request = new HttpEntity<>(req_payload,
headers);
restTemplateApi.postForEntity(url, request, String.class);

How to add body to a SpringBoot RestTemplate Put request that has headers [duplicate]

Please look at this simple code:
final String url = String.format("%s/api/shop", Global.webserviceUrl);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.set("X-TP-DeviceID", Global.deviceID);
HttpEntity entity = new HttpEntity(headers);
HttpEntity<Shop[]> response = restTemplate.exchange(url, HttpMethod.GET, entity, Shop[].class);
shops = response.getBody();
As you can see, above code is intended to GET list of shops from server (in json format) and map response to array of Shop objects.
Now I need to PUT new shop, for example as /api/shop/1. Request entity should have exactly the same format as returned one.
Should I add /1 to my url, create new Shop class object, with all fields filled with my values I want to put and then use exchange with HttpMethod.PUT?
Please, clarify it for me, I'm beginner with Spring. Code example would be appreciated.
[edit]
I'm double confused, because I just noticed also method RestTemplate.put(). So, which one should I use? Exchange or put()?
You could try something like :
final String url = String.format("%s/api/shop/{id}", Global.webserviceUrl);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.set("X-TP-DeviceID", Global.deviceID);
Shop shop= new Shop();
Map<String, String> param = new HashMap<String, String>();
param.put("id","10")
HttpEntity<Shop> requestEntity = new HttpEntity<Shop>(shop, headers);
HttpEntity<Shop[]> response = restTemplate.exchange(url, HttpMethod.PUT, requestEntity, Shop[].class, param);
shops = response.getBody();
the put returns void whereas exchange would get you a response, the best place to check would be documentation https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

RestTemplate with encoded parameters

I need to send an HTTP request to an authentication provider (Auth0). I want to get one specific user by its email address.
The request has to go to:
curl -H "Authorization: Bearer ..." https://.../users?q=email%3A%22mymail%40abc.de%22&search_engine=v2
I tried my luck with RestTemplate (Spring):
public void doSomething() {
...
Map<String, String> requestMap = new HashMap<>();
requestMap.put("q", "email%3A%22mymail%40abc.de%22");
requestMap.put("search_engine", "v2");
RestTemplate restTemplate = getRestTemplateForRequestMap();
HttpHeaders headers = getHeaders();
HttpEntity<Map<String, String>> request = new HttpEntity<>(requestMap, headers);
ResponseEntity<UserInfo[]> response = restTemplate.exchange(URI.create(baseApiUrl + "users"), HttpMethod.GET, request, UserInfo[].class);
...
}
private RestTemplate getRestTemplateForRequestMap() {
RestTemplate restTemplate = new RestTemplate();
List messageConverters = new ArrayList<>();
messageConverters.add(new MappingJackson2HttpMessageConverter());
restTemplate.setMessageConverters(messageConverters);
return restTemplate;
}
Looks like the value of the q parameter needs to be encoded (they call it "Lucene query syntax"). I tried different variations. I even put them "hardcoded" encoded.
However it seems like the q parameter isn't working as the result includes not only the user with the specified email address but all users.
Headers are fine (otherwise I would get no user at all).
You can add the map of your request parameters on on an overloaded method of restTemplate.exchange :
ResponseEntity<UserInfo[]> response = restTemplate.exchange(URI.create(baseApiUrl + "users"), HttpMethod.GET,
request, UserInfo[].class,requestMap);
Works for me:
UriComponentsBuilder builder;
try {
String emailEncoded = URLEncoder.encode("email:" + email, "UTF-8");
builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("include_fields", "true")
.queryParam("search_engine", "v3")
.queryParam("q", emailEncoded);
} catch (UnsupportedEncodingException e) {
.....
}
HttpEntity<?> httpEntity = HttpUtility.getHttpEntity(jwtToken);
ResponseEntity<String> response = restTemplate.exchange(builder.build().toUriString(), HttpMethod.GET, httpEntity, String.class);

Get STRING response from restTemplate.put

I'm having a problem using Spring restTemplate.
For now i'm sending a PUT request for a restful service and that restful service send me back important informations in response.
The question is that restTemplate.put are a void method and not a string so i can't see that response.
Following some answers i've change my method and now i'm using restTemplate.exchange, here are my method:
public String confirmAppointment(String clientMail, String appId)
{
String myJsonString = doLogin();
Response r = new Gson().fromJson(myJsonString, Response.class);
// MultiValueMap<String, String> map;
// map = new LinkedMultiValueMap<String, String>();
// JSONObject json;
// json = new JSONObject();
// json.put("status","1");
// map.add("data",json.toString());
String url = getApiUrl() + "company/" + getCompanyId() + "/appointment/" + appId + "?session_token=" + r.data.session_token;
String jsonp = "{\"data\":[{\"status\":\"1\"}]}";
RestTemplate rest = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
headers.add("Accept", "*/*");
HttpEntity<String> requestEntity = new HttpEntity<String>(jsonp, headers);
ResponseEntity<String> responseEntity =
rest.exchange(url, HttpMethod.PUT, requestEntity, String.class);
return responseEntity.getBody().toString();
}
Using the method above, i receive a 400 Bad Request
I know my parameters, url and so, are just fine, cause i can do a restTemplate.put request like this:
try {
restTemplate.put(getApiUrl() + "company/" + getCompanyId() + "/appointment/" + appId + "?session_token=" + r.data.session_token, map);
} catch(RestClientException j)
{
return j.toString();
}
The problem (like i said before) is that the try/catch above does not return any response but it gives me a 200 response.
So now i ask, what can be wrong?
Here's how you can check the response to a PUT. You have to use template.exchange(...) to have full control / inspection of the request/response.
String url = "http://localhost:9000/identities/{id}";
Long id = 2l;
String requestBody = "{\"status\":\"testStatus2\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(requestBody, headers);
ResponseEntity<String> response = template.exchange(url, HttpMethod.PUT, entity, String.class, id);
// check the response, e.g. Location header, Status, and body
response.getHeaders().getLocation();
response.getStatusCode();
String responseBody = response.getBody();
You can use the Header to send something in brief to your clients. Or else you can use the following approach as well.
restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, ...)
You will be able to get a Response Entity returned through that.
Had the same issue. And almost went nuts over it. Checked it in wireshark: The problem seems to be the escape characters from the request body:
String jsonp = "{\"data\":[{\"status\":\"1\"}]}";
The escape character (backslash) is not resolved. The String is sent with the backslashes, which is obviously not a valid json and therefore no valid request(-body).
I bypassed this by feeding everything in with an Object, that is mapping all the properties.

Java POST application/json [duplicate]

I didn't find any example how to solve my problem, so I want to ask you for help. I can't simply send POST request using RestTemplate object in JSON
Every time I get:
org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
I use RestTemplate in this way:
...
restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
list.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(list);
...
Payment payment= new Payment("Aa4bhs");
Payment res = restTemplate.postForObject("http://localhost:8080/aurest/rest/payment", payment, Payment.class);
What is my fault?
This technique worked for me:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.put(url, entity);
I ran across this problem when attempting to debug a REST endpoint. Here is a basic example using Spring's RestTemplate class to make a POST request that I used. It took me quite a bit of a long time to piece together code from different places to get a working version.
RestTemplate restTemplate = new RestTemplate();
String url = "endpoint url";
String requestJson = "{\"queriedQuestion\":\"Is there pain in your hand?\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);
The particular JSON parser my rest endpoint was using needed double quotes around field names so that's why I've escaped the double quotes in my requestJson String.
I've been using rest template with JSONObjects as follow:
// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);
// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);
// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
.exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK) {
JSONObject userJson = new JSONObject(loginResponse.getBody());
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
// nono... bad credentials
}
As specified here I guess you need to add a messageConverter for MappingJacksonHttpMessageConverter
I'm doing in this way and it works .
HttpHeaders headers = createHttpHeaders(map);
public HttpHeaders createHttpHeaders(Map<String, String> map)
{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
for (Entry<String, String> entry : map.entrySet()) {
headers.add(entry.getKey(),entry.getValue());
}
return headers;
}
// Pass headers here
String requestJson = "{ // Construct your JSON here }";
logger.info("Request JSON ="+requestJson);
HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
logger.info("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
logger.info("Response ="+response.getBody());
Hope this helps
If you are using Spring 3.0, an easy way to avoid the org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type exception, is to include the jackson jar files in your classpath, and use mvc:annotation-driven config element. As specified here.
I was pulling my hair out trying to figure out why the mvc-ajax app worked without any special config for the MappingJacksonHttpMessageConverter. If you read the article I linked above closely:
Underneath the covers, Spring MVC
delegates to a HttpMessageConverter to
perform the serialization. In this
case, Spring MVC invokes a
MappingJacksonHttpMessageConverter
built on the Jackson JSON processor.
This implementation is enabled
automatically when you use the
mvc:annotation-driven configuration
element with Jackson present in your
classpath.
The "415 Unsupported Media Type" error is telling you that the server will not accept your POST request. Your request is absolutely fine, it's the server that's mis-configured.
MappingJacksonHttpMessageConverter will automatically set the request content-type header to application/json, and my guess is that your server is rejecting that. You haven't told us anything about your server setup, though, so I can't really advise you on that.
Why work harder than you have to? postForEntity accepts a simple Map object as input. The following works fine for me while writing tests for a given REST endpoint in Spring. I believe it's the simplest possible way of making a JSON POST request in Spring:
#Test
public void shouldLoginSuccessfully() {
// 'restTemplate' below has been #Autowired prior to this
Map map = new HashMap<String, String>();
map.put("username", "bob123");
map.put("password", "myP#ssw0rd");
ResponseEntity<Void> resp = restTemplate.postForEntity(
"http://localhost:8000/login",
map,
Void.class);
assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
}
I was getting this problem and I'm using Spring's RestTemplate on the client and Spring Web on the server. Both APIs have very poor error reporting, making them extremely difficult to develop with.
After many hours of trying all sorts of experiments I figured out that the issue was being caused by passing in a null reference for the POST body instead of the expected List. I presume that RestTemplate cannot determine the content-type from a null object, but doesn't complain about it. After adding the correct headers, I started getting a different server-side exception in Spring before entering my service method.
The fix was to pass in an empty List from the client instead of null. No headers are required since the default content-type is used for non-null objects.
This code is working for me;
RestTemplate restTemplate = new RestTemplate();
Payment payment = new Payment("Aa4bhs");
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("payment", payment);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(map, headerObject);
Payment res = restTemplate.postForObject(url, httpEntity, Payment.class);
If you dont want to process response
private RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject(serviceURL, request, Void.class);
If you need response to process
String result = restTemplate.postForObject(url, entity, String.class);
I tried as following in spring boot:
ParameterizedTypeReference<Map<String, Object>> typeRef = new ParameterizedTypeReference<Map<String, Object>>() {};
public Map<String, Object> processResponse(String urlendpoint)
{
try{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
//reqobj
JSONObject request = new JSONObject();
request.put("username", name);
//Or Hashmap
Map<String, Object> reqbody = new HashMap<>();
reqbody.put("username",username);
Gson gson = new Gson();//mvn plugin to convert map to String
HttpEntity<String> entity = new HttpEntity<>( gson.toJson(reqbody), headers);
ResponseEntity<Map<String, Object>> response = resttemplate.exchange(urlendpoint, HttpMethod.POST, entity, typeRef);//example of post req with json as request payload
if(Integer.parseInt(response.getStatusCode().toString()) == HttpURLConnection.HTTP_OK)
{
Map<String, Object> responsedetails = response.getBody();
System.out.println(responsedetails);//whole json response as map object
return responsedetails;
}
} catch (Exception e) {
// TODO: handle exception
System.err.println(e);
}
return null;
}
For me error occurred with this setup:
AndroidAnnotations
Spring Android RestTemplate Module
and ...
GsonHttpMessageConverter
Android annotations has some problems with this converted to generate POST request without parameter. Simply parameter new Object() solved it for me.
If you don't want to map the JSON by yourself, you can do it as follows:
RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));
ResponseEntity<String> result = restTemplate.postForEntity(uri, yourObject, String.class);
You can make request as a JSON object
JSONObject request = new JSONObject();
request.put("name","abc");
ResponseEntity<JSONObject> response =restTemplate.postForEntity(append_url,request,JSONObject.class); `enter code here`

Categories