How to expose header information in API response message? - java

I'm using spring's responseEntity response.
The response I've been using so far is return ResponseEntity.status(200).body(...); method, in this case the return data is in the form [ { ...}, {...} ].
Then, I checked the example, and there was a response header in front of this [ { ...}, {...} ].
HTTP/1.1 200
Content-Type: application/json;
charset=UTF-8 Transfer-Encoding: chunked
Date: Sun, 07 Oct 2018 11:53:46 GMT
[{"id":1,"username":"Jane"},{"id":2,"username":"John"}]
like this
Instead of checking the header separately, I want to check it together in the response message like this.
Did I misunderstand that the header message was arbitrarily moved?
Or is it possible?

Related

CORS response headers not shown when using #CrossOrigin

I have created a basic GET endpoint, and attempted to allow CORS. However, the expected headers aren't returned in the response body, and I couldn't find what I'm doing wrong here.
GET method in my REST controller:
#CrossOrigin(
allowCredentials = "true",
origins = "*",
allowedHeaders = {
"Access-Control-Allow-Origin",
"Access-Control-Allow-Headers",
"Access-Control-Max-Age",
"Access-Control-Allow-Methods",
"Content-Type"})
public String test() {
return "test";
}
When I send a request here, the response headers are as follows:
Content-Length: 4
Content-Type: text/html;charset=UTF-8
Date: Mon, 13 May 2019 19:33:11 GMT
I'm hoping to add the headers to this response, i.e.:
Content-Length: 4
Content-Type: text/html;charset=UTF-8
Date: Mon, 13 May 2019 19:33:11 GMT
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Max-Age, Access-Control-Allow-Methods, Content-Type
Access-Control-Allow-Origin: *
Any help would be greatly appreciated.
Ahh, I see - these headers are only added for cross-origin requests. When I set the origin in the request headers, the response headers are added as expected.

Spring rest endpoint not returning body

I am very confused about the behavior of one of my rest endpoint int my Spring application
I have a simple controller:
#RestController
public class MyController {
#GetMapping("/test")
public String test(Principal principal) {
System.out.println("HELOOOO");
return "hello";
}
}
And I am sending requests to this endpoint. The request is accepted and returns 200 OK but the body is missing. I see the printline and I see the request being successfully processed in my browser console but there is no body.
I have other endpoints in my application (some even in the same controller class) which work fine so I am confused what might be the reason for this particular one.
EDIT: this is what I am seeing in the web console:
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 22 Apr 2019 08:37:46 GMT
Failed to load response data
#ResponseBody annotation does nothing.
EDIT2: Thank you all for your suggestion - especially the one about trying the endpoint with cUrl. The exception was not in Spring but in my client handling the response where I was handling it incorrectly.
You can return a ResponseEntity as following:
#GetMapping("/test")
public ResponseEntity test(Principal principal) {
System.out.println("HELOOOO");
return new ResponseEntity<>("hello", HttpStatus.OK);
}
This worked fine for me.
Response status is an 200, but response ultimately comes with an error message "Failed to load response data".
This could only be due to failure to serialise the data you returned to a valid JSON.
I'm not a Spring expert, but perhaps if you returned "\"hello\"" it should be fine.

Spring Boot: How to resolve Content-Type when incorrectly received from server

I have the following class in Java. I'm expecting it to issue a GET request to the url, get back a JSON payload, and transform that payload to List<LocationData>.
package ...
import ...
#Repository
public class ProxiedLocationRepo {
public List<LocationData> findAll() throws Exception {
RestTemplate restTemplate = new RestTemplate();
String url = UriComponentsBuilder
.fromUriString("https://my-host/path")
.queryParams("some", "queryParams")
.toUriString();
ResponseEntity<List<LocationData>> res = restTemplate.exchange(
url,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<LocationData>>(){});
if (res.getStatusCode() == HttpStatus.ACCEPTED) {
return res.getBody();
} else {
throw new ResponseStatusException(res.getStatusCode(), "Did not receive a 200 response from Server.");
}
}
}
However, I'm getting back this error:
org.springframework.http.InvalidMediaTypeException: Invalid mime type "charset=UTF-8": does not contain '/'
Which is expected, because if I do the same request from curl, and check the headers I get this (notice Content-Type line):
$ curl -sfi 'https://my-host/path?some=queryParams'
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 06 Mar 2019 13:58:58 GMT
Content-Type: charset=UTF-8
Content-Length: 1821
Connection: keep-alive
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
... # perfectly formatted JSON payload here
I know that the Content-Type returned from this server is going to be application/json, but it is not providing it to me.
Is there anyway to inform RestTemplate#exchange of what the Content-Type of the response will be? If not, is there any other methodology I could use to resolve this issue besides getting the owners of the server to set the Content-Type correctly?
EDIT:
I have also tried adding the "Accept" header but got the same results:
$ curl -sfi 'https://my-host/path?some=queryParams' \
-H 'Accept: application/json'
Unfortunately I don't think there's any way to fix this while leveraging the Spring framework. Even if you were to create a custom JsonbHttpMessageConverter that accepts a MIME type of ANY, Spring would still fail to parse the incorrect Content-Type received from the request (because it can't find "/" in the Content-Type string).
So the resolution here was to do use java.net.HttpURLConnection to do the networking instead, and then use com.fasterxml.jackson.databind.ObjectMapper to map from the JSON to a POJO.
It works, but at the cost of no longer being able to leverage any of Spring's HTTP handling, which is likely much much more robust than anything I can implement alone.

OneDrive API download in parts

I am currently trying to develop a Java based app to access OneDrive.
Today i tried to implement the download as described here: https://dev.onedrive.com/items/download.htm
I wanted to use the range parameter, to offer the user the capability to pause large downloads. But no matter how i send the parameter be at within the HTTP-Request header or in the URL as a GET-Parameter it will always send me the complete file.
Things i tried so far:
https:/ /api.onedrive.com/v1.0/drive/items/***/content?range=0-8388607
(OAuth via HTTP header)
https:/ /api.onedrive.com/v1.0/drive/items/***/content:
Header: Authorization: ***
range: 0-8388607
https:/ /api.onedrive.com/v1.0/drive/items/***/content:
Header: Authorization: ***
range: bytes=0-8388607
I also tried Content-Range and various variations on lower and upper case without success. Any reason why this dose not work?
PS.:
The links a broken because i am using a new account that only allows 2 links per post, I am aware that ther is a space between the two // in my post ;)
Requesting the range of the file is supported. You might want to use fiddler or some other tool to see if the original headers are being passed after the 302 redirect is performed. Below are the HTTP requests and responses when I provide the range header which is being passed on after the 302 redirect occurs. You'll notice that a HTTP 206 partial content response is returned. Additionally, to resume a download, you can use "Range: bytes=1025-" or whatever the last byte received was. I hope that helps.
GET https://api.onedrive.com/v1.0/drive/items/item-id/content HTTP/1.1
Authorization: Bearer
Range: bytes=0-1024
Host: api.onedrive.com
HTTP/1.1 302 Found
Content-Length: 0
Location: https://kplnyq.dm2302.livefilestore.com/edited_location
Other headers removed
GET https://kplnyq.dm2302.livefilestore.com/edited_location
Range: bytes=0-1024
Host: kplnyq.dm2302.livefilestore.com
HTTP/1.1 206 Partial Content
Cache-Control: public
Content-Length: 1025
Content-Type: audio/mpeg
Content-Location: https://kplnyq.dm2302.livefilestore.com/edited_location
Content-Range: bytes 0-1024/4842585
Expires: Tue, 11 Aug 2015 21:34:52 GMT
Last-Modified: Mon, 12 Dec 2011 21:33:41 GMT
Accept-Ranges: bytes
Server: Microsoft-HTTPAPI/2.0
Other headers removed

Testing of Raw HTTP post in java, 400 Bad Request

I have developed a raw http post in java. I am trying to post a file to the post request dump website http://www.posttestserver.com/. But it shows and error
400 Bad Request. Pleas let me know what need to be done to avoid this error.
In this code , output => Stream to write on server.
filename -> path on server, here filename is initated to post.php
output.println("POST"+" "+filename+" HTTP/1.1\r");
//output.println("Content-Length: "+data.length());
output.println("Content-Type: multipart/form-data, boundary=AaB03x\r");
output.println("Content-length: 100\r");
//As http1.1 is by default keep-alive , close the connection explicitly
output.println("Connection: Close");
// blank line
output.println();
output.println("--AaB03x");
output.print(
"--AaB03x Content-Disposition: form-data; name=\"fileID\"; filename=\"temp.txt\" Content-Type: text/plain "
+"/nHello How are you?"
+ "/n--AaB03x--");
output.flush();
Error is
HTTP/1.1 400 Bad Request
Date: Wed, 18 Mar 2015 02:22:00 GMT
Server: Apache
Vary: Accept-Encoding
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1
400 Bad Request
Bad Request
Your browser sent a request that this server could not understand.
This might be the issue of Content type. Server is expecting a request having header of content type text/HTML but your request content type is multipart/form data.

Categories