I try to send the shipping status from my database to ecommerce website, but I get:
400 bad request error.
Does anyone have any ideas?
HashMap orderItems = new HashMap<String, String>();
orderItems.put("id","558443685");
ArrayList<HashMap<String,String>> orderItemsArray = new ArrayList<HashMap<String,String>>();
orderItemsArray.add(orderItems);
HashMap contentOrderFulfillment = new HashMap<String, Object>();
contentOrderFulfillment.put("tracking_number", null);
contentOrderFulfillment.put("line_items",orderItemsArray);
HashMap orderFulfillment = new HashMap<String, Object>();
orderFulfillment.put("fulfillment", contentOrderFulfillment);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.add("X-ABC-Access-Token", "9a4d5c56a7edf1ac5bb17aa1c");
headers.add("Content-Type", MediaType.APPLICATION_JSON.toString());
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<String, Object>();
requestBody.add("fulfillment", orderFulfillment);
HttpEntity formEntity = new HttpEntity<MultiValueMap<String, Object>>(requestBody, headers);
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
ResponseEntity<String> responseEntity = restTemplate.exchange("https://mysite.abc.com/admin/orders/406287121/fulfillments.json",HttpMethod.POST, formEntity,String.class);
System.out.println("Response="+responseEntity.getBody());
400 response can be caused from many problems inside your request. Wrong parameters or something like that. Try the request first from command line - with curl or something. When you see it working check if the request from java has the exact same parameters sent.
Have a look in ResponseEntityExceptionHandler (or any descendant) if you extend that handler.
Most of the methods of the handler don't include a message body, so a solution would be for you to extend that class, override the methods handling the exceptions you would like to get an error message for, and provide message body to the handleExceptionInternal(..) method.
See also:
http://www.baeldung.com/2013/01/31/exception-handling-for-rest-with-spring-3-2/
https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
Related
I have been trying to upload an image to Cloudflare images, but no matter what I try it gets rejected with "400 Bad Request: "ERROR 5400: Bad request: Error parsing form fields""
https://api.cloudflare.com/#cloudflare-images-upload-an-image-using-a-single-http-request
I am currently using SpringBoot with Rest Templates, here's an example of what I have tried so far:
public String uploadImage(File file) {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + API_TOKEN);
LinkedMultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
//body.add("\"file\"", new FileSystemResource(file));
body.add("file", new FileSystemResource(file));
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.exchange(URL, HttpMethod.POST, request, String.class);
return response.toString();
}
I have tried using different forms of the file, changing the parameters, using different methods to make the request, ex: restTemplate.exchange vs restTemplate.getForObject, etc... and I have had no luck. If anyone can help me out or point me in the right direction, I would be greatly appreciated!
I am using Spring's RestTemplate to send a POST request to my RestController with request parameters and a request header.
It fails with this error message: POST request for "[myurl]" resulted in 404 (null); invoking error handler.
Note that "[myurl]" is "http://localhost:8080/test"
This is my code:
RestTemplate rest = new RestTemplate();
MultiValueMap<String, Integer> map = new LinkedMultiValueMap<String, Integer>();
map.add("num1", 1);//request parameters
map.add("num2", 2);
HttpHeaders headers = new HttpHeaders();//request header
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<MultiValueMap<String, Integer>> request = new HttpEntity<MultiValueMap<String, Integer>>(map, headers);
Object obj = rest.postForObject("[myurl]", request, Object.class);
logger.log("Returned object: " + obj.toString());
Maybe try doing something like (if you can get away with MultiValueMap):
RestTemplate rest = new RestTemplate();
Map<String, Integer> map = new HashMap<>();
map.put("num1", 1);//request parameters
map.put("num2", 2);
Object obj = rest.postForObject("[myurl]", map, Object.class);
logger.log("Returned object: " + obj.toString());
I'm new to Spring and trying to do a rest request with RestTemplate. The Java code should do the same as below curl command:
curl --data "name=feature&color=#5843AD" --header "PRIVATE-TOKEN: xyz" "https://someserver.com/api/v3/projects/1/labels"
But the server rejects the RestTemplate with a 400 Bad Request
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("PRIVATE-TOKEN", "xyz");
HttpEntity<String> entity = new HttpEntity<String>("name=feature&color=#5843AD", headers);
ResponseEntity<LabelCreationResponse> response = restTemplate.exchange("https://someserver.com/api/v3/projects/1/labels", HttpMethod.POST, entity, LabelCreationResponse.class);
Can somebody tell me what I'm doing wrong?
I think the problem is that when you try to send data to server didn't set the content type header which should be one of the two: "application/json" or "application/x-www-form-urlencoded" . In your case is: "application/x-www-form-urlencoded" based on your sample params (name and color). This header means "what type of data my client sends to server".
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("PRIVATE-TOKEN", "xyz");
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("name","feature");
map.add("color","#5843AD");
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
ResponseEntity<LabelCreationResponse> response =
restTemplate.exchange("https://foo/api/v3/projects/1/labels",
HttpMethod.POST,
entity,
LabelCreationResponse.class);
You need to set the Content-Type to application/json. Content-Type has to be set in the request. Below is the modified code to set the Content-Type
final String uri = "https://someserver.com/api/v3/projects/1/labels";
String input = "US";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("PRIVATE-TOKEN", "xyz");
HttpEntity<String> request = new HttpEntity<String>(input, headers);
ResponseEntity<LabelCreationResponse> response = restTemplate.postForObject(uri, request, LabelCreationResponse.class);
Here, HttpEntity is constructed with your input i.e "US" and with headers.
Let me know if this works, if not then please share the exception.
Cheers!
It may be a Header issue check if the header is a Valid header, are u referring to "BasicAuth" header?
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
headers.add("Accept", MediaType.APPLICATION_JSON.toString()); //Optional in case server sends back JSON data
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<String, String>();
requestBody.add("name", "feature");
requestBody.add("color", "#5843AD");
HttpEntity formEntity = new HttpEntity<MultiValueMap<String, String>>(requestBody, headers);
ResponseEntity<LabelCreationResponse> response =
restTemplate.exchange("https://example.com/api/request", HttpMethod.POST, formEntity, LabelCreationResponse.class);
my issue, the MessageConverters contains other converters may converts then entity to json (like FastJsonHttpMessageConverter). So i added the FormHttpMessageConverter to ahead and it works well.
<T> JuheResult<T> postForm(final String url, final MultiValueMap<String, Object> body) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
return exchange(url, HttpMethod.POST, requestEntity);
}
<T> JuheResult<T> exchange(final String url, final HttpMethod method, final HttpEntity<?> requestEntity) {
ResponseEntity<JuheResult<T>> response = restTemplate.exchange(url, method, requestEntity,
new JuheResultTypeReference<>());
logger.debug("调用结果 {}", response.getBody());
return response.getBody();
}
public JuheSupplierServiceImpl(RestTemplateBuilder restTemplateBuilder) {
Duration connectTimeout = Duration.ofSeconds(5);
Duration readTimeout = Duration.ofSeconds(5);
restTemplate = restTemplateBuilder.setConnectTimeout(connectTimeout).setReadTimeout(readTimeout)
.additionalInterceptors(interceptor()).build();
restTemplate.getMessageConverters().add(0, new FormHttpMessageConverter());
}
fastjson prevent resttemplate converting other mediaTypes other than json
I use Maven + Spring and I want use RestTemplate().postForEntity(url, request, responseType) + Content-Type=application/json
but I have this error:
org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [com.kizeoforms.model.User] and content type [application/json]
java REST client code:
User user = new User();
user.setUser("foo");
user.setPassword("**********");
user.setCompany("xxxxxx");
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Content-Type", "application/json");
HttpEntity<User> request = new HttpEntity<User>(user, headers);
ResponseEntity<Object> response = new RestTemplate().postForEntity("https://www.kizeoforms.com:443/rest/v3/login", request, Object.class);
System.out.println(response.getStatusCode());
I had new MappingJackson2HttpMessageConverter() to restTemplate:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
ResponseEntity<Object> response = restTemplate.postForEntity("https://www.kizeoforms.com:443/rest/v3/login", request, Object.class);
Look into the Restemplate constructor, if there are supported serialized packaged included in your project, the corresponding message converters will be added. So you can add a dependency package, such as com.google.gson.Gson or javax.json.bind.Jsonb, then you needn't handle the message converts explicitly.
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