Build Response Entity without sending it - java

I have the following situation: In my spring application I make a request to another web service. This web service sends me a ResponseEntity back. Now I have modified the ResponseEntity this worked perfectly, except that I cannot build a new ResponseEntity, I don't know why. Can someone tell me how to build a new ResponseEntity?
Thats my code:
JsonNode modifiedBody = //body
HttpHeaders modifiedHeader = //header
HttpEntity<Object> newResponse = new HttpEntity<>(modifiedBody, modifiedHeader);
//until this point everything works perfect now I want to create a new ResponseEntity without calling a webservice
ResponseEntity<Object> entity = //MAKE NEW RESPONSE ENTITY
Can someone please tell me how to make a new response entity without sending it?
Thanks in advance.
Edit:
Disappearing value:
If I look in the debugger I find the value. But in the next step its gone.

As simple as that:
ResponseEntity<Object> entity = ResponseEntity
.status(200) // status
.headers(...)
.body(...); // maybe some body
Please note that you cannot pass HttpEntity there, so you must set headers and body through these static methods as well.

Related

In Web Client, returning ResponseEntity containing both Body and Http Status Code(both success and failure) JAVA spring boot

I am writing an blocking web client. I want to return both body(class) and http status code in ResponseEntity object to be used in some method. Can you please help with this. I am new to Java and already tried approaches many mentioned on internet.
You can use ResponseEntity class!
For e.g. Assume you want to return your Model/Pojo as below
Model class -> MyResponse (Has fields, getter/setters,toString etc) you want to respond along with HTTP code
Code snippet
#GetMapping("/getresponse) //Or any mapping
public ResponseEntity getResponse()
{
MyResponse response=new MyResponse();
return new ResponseEntity>(response,HttpStatus.OK);
}

Calling multiple external APIs in Spring Boot

I am working on a project but it requires me to call multiple external APIs. I basically have to call an API to get a player id by giving a name. Then use that player id to get a list of match ids. Then make calls for each match id to get details on each match. its alot and doesnt seem optimal but its the only way to do it. I was going to use rest template to make a call to the following
https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/HDzjdaStxhHcceGGd8qJcc4Vw45FOlOQ1PNXKQ0h9_iqfwHP3oI0spl1bLUOw_7_J49vzaIKylv5Vg/ids?start=0&count=20
I have to pass in headers as well such as
riot token : token
"Origin": "https://developer.riotgames.com"
I was wondering how I can do this in Java Spring boot. I saw RestTemplate would be used but I couldnt figure out how to include the headers. Any guidance would be appreciated.
You can call RestTemplate.exchange() using either the method signature with RequestEntity or with HttpEntity.
// Using RequestEntity
RequestEntity<?> request= RequestEntity.get(url).header(headerName, headerValue).build();
ResponseEntity<String> response = restTemplate.exchange(request, String.class);
// Using HttpEntity
HttpHeaders headers = new HttpHeaders();
headers.set(headerName, headerValue);
HttpEntity httpEntity = new HttpEntity(/* this is nullable */ requestBody, headers);
ResponseEntity,String> response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
Would also recommend reading through the following:
https://howtodoinjava.com/spring-boot2/resttemplate/spring-restful-client-resttemplate-example/
https://www.baeldung.com/rest-template
How to set an "Accept:" header on Spring RestTemplate request?

Passing Request Body to Spring Rest Template without using LinkedMultiValueMap

I'm using the Spring Rest Template to make an Http PUT request and up until now I have been passing the request body using the following:
MultiValueMap<String, Object> body = new LinkedMultiValueMap<String, Object>();
body.add("account", testAccount);
HttpEntity<?> requestEntity = new HttpEntity<Object>(body, headers);
ResponseEntity<String> responseEntity;
try {
responseEntity = rest.exchange(uri, HttpMethod.PUT, requestEntity, String.class);
}
catch (HttpStatusCodeException e) {
log.error("Http PUT failed with response: " + e.getStatusText());
return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
}
return responseEntity;
The request body that gets sent to my target API appears as:
{"account":[{"account_id":"495"}]}
This works, but my target API is not expecting the account object to have an array as a value and is currently giving me a 500 Internal Server Error, so, my question is, how can I get the value of the 'account' property to be an object rather than an array? For example I would like the request body to appear as:
{"account":{"account_id":"495"}}
Is there another type of Map which can be used which does not accept multiple values?
I would still like to use the exchange method if possible.
Any on help on this would be grand! Many thanks
The answer was actually simply using a regular HashMap instead of the MultiValueMap. As seen here the MultiValueMapcase is used when you want to add an array to a single key in the request body.
Thanks for all the help.

Testing MockRestServiceServer spring-test with multipart request

Recently I've started to use Spring's MockRestServiceServer to verify my RestTemplate based requests in tests.
When its used for simple get/post request - all good, however, I couldn't figure out how to use it with POST multipart request:
For example, my working code that I would like to test looks like this:
public ResponseEntity<String> doSomething(String someParam, MultipartFile
file, HttpHeaders headers) { //I add headers from request
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("file", new ByteArrayResource(file.getBytes()) {
#Override
public String getFilename() {
return file.getOriginalFilename();
}
});
map.add("someParam", someParam);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new
HttpEntity<>(map, headers);
return this.restTemplate.exchange(
getDestinationURI(),
HttpMethod.POST,
requestEntity,
String.class);
}
So my question is How I can specify my expectations with org.springframework.test.web.client.MockRestServiceServer? Please notice, that I don't want to just mock the "exchange" method with mockito or something, but prefer to use MockRestServiceServer
I'm using spring-test-4.3.8.RELEASE version
A code snippet would be really appreciated :)
Thanks a lot in advance
Update:
As per James's request I'm adding non-working test snippet (Spock test):
MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build()
server.expect(once(), requestTo(getURI()))
.andExpect(method(HttpMethod.POST))
.andExpect(header(HttpHeaders.CONTENT_TYPE, startsWith("multipart/form-data;boundary=")))
.andExpect(content().formData(["someParam" : "SampleSomeParamValue", "file" : ???????] as MultiValueMap))
.andRespond(withSuccess("sample response", MediaType.APPLICATION_JSON))
multipartFile.getBytes() >> "samplefile".getBytes()
multipartFile.getOriginalFilename() >> "sample.txt"
I get exception while asserting the request content. The form data is different, because an actual form data is created internally with Content-Disposition, Content-Type, Content-Length per parameter and I don't know how to specify these expected values
Multipart request expectations have been added to MockRestServiceServer in Spring 5.3 - see:
pull request
final version
You can use
content().multipartData(MultiValueMap<String, ?> expectedMap)
Parse the body as multipart data and assert it contains exactly the values from the given MultiValueMap. Values may be of type:
String - form field
Resource - content from a file
byte[] - other raw content
content().multipartDataContains(Map<String,?> expectedMap)
Variant of multipartData(MultiValueMap) that does the same but only for a subset of the actual values.
I think this depends on how deeply you want to test the form data. One way, which is not 100% complete, but is a "good enough" for unit testing (usually) is to do something like:
server.expect(once(), requestTo(getURI()))
.andExpect(method(HttpMethod.POST))
.andExpect(content().string(StringContains.containsString('paramname=Value') ))....
This is ugly and incomplete, but is sometimes useful. Of course, you can also work to make the form setup it's own method and then use mocks to try to verify that the expected parameters are all in place.

Spring RestTemplate post response

I'm not familiar with Spring RestTemplate.
But for this project I have to use Spring RestTemplate to send a POST call to consume a rest api.
I'm using this code:
String restCall = restTemplate.postForObject(url+restParm, null, String.class);
This is working fine.
I would like to retriveve the HTTP status code (E.g: 200 OK.). How could I do that ?
Thanks.
You use the postForEntity method as follows...
ResponseEntity<String> response = restTemplate.postForEntity(url+restParm, null, String.class);
HttpStatus status = response.getStatusCode();
String restCall = response.getBody();
It will be pretty weird if RestTemplate couldn't get the response,as others have suggested. It is simply not true.
You just use the postForEntity method which returns a
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/http/ResponseEntity.html
And as the documentation suggests, the response entity has the status.

Categories

Resources