Not able to receive Set-Cookie field using RestTemplate - java

I am trying two ways to POST on a url and everything is working fine except in one field.
If i am using HttpConnection i am receiving Set-Cookie field as output.
JSONObject json = new JSONObject();
json.put("username", "1010101010");
json.put("password", "11two33");
String loginContent = json.toString();
int timeOut = 100000;
String authLoginUrl = "http://localhost:8080/api/login";
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json");
HttpExternalService httpService = new HttpExternalService();
HttpExResponseDetails exResponse = httpService.sendRequest(authLoginUrl, loginContent, HttpMethod.POST, timeOut,
headers, null, null, true, true, true, false, null);
Map<String, List<String>> rsHeaders = exResponse.getResponseHeaderMap();
for(Entry<String, List<String>> e: rsHeaders.entrySet()){
System.out.println("Key: "+e.getKey());
List<String> valueList = e.getValue();
for(String str: valueList){
System.out.println("Value: "+str);
}
}
That is one field that is coming in the output:
OUTPUT:
Key: Transfer-Encoding
Value: chunked
Key: null
Value: HTTP/1.1 200 OK
Key: Server
Value: Jetty(9.2.16.v20160414)
Key: X-Content-Type-Options
Value: nosniff
Key: Pragma
Value: no-cache
Key: X-Application-Context
Value: gateway:8080
Key: Date
Value: Wed, 13 Jul 2016 14:08:55 GMT
Key: Via
Value: 1.1 d.eze.cc
Key: X-Frame-Options
Value: DENY
Key: Cache-Control
Value: no-cache, no-store, max-age=0, must-revalidate
Key: Vary
Value: Accept-Encoding
Key: Set-Cookie
Value: jsessionid=c5bcc245-e18e-4320-8ac2-08b3e51dcae7;Path=/api/;HttpOnly
Key: Expires
Value: Thu, 01 Jan 1970 00:00:00 GMT
Key: X-XSS-Protection
Value: 1; mode=block
Key: Content-Type
Value: application/json; charset=UTF-8
But if i am using RestTemplate for hitting the same url i am not receiving any Set-Cookie field which is a strange behaviour.
Map<String, String> json = new HashMap<String, String>();
json.put("username", "1010101010");
json.put("password", "11two33");
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json");
ResponseEntity<ApiOutput> out = WebServiceCaller.postServiceCall(url, ApiOutput.class, json, null);
// HttpExResponseDetails exResponse =
// httpService.sendRequest(authLoginUrl, loginContent, HttpMethod.POST,
// timeOut,
// getHeaders(), null, null, true, false, false, false, null);
System.out.println("Status code: " + out.getStatusCode());
MultiValueMap<String, String> rsHeaders = out.getHeaders();
for (Entry<String, List<String>> e : rsHeaders.entrySet()) {
System.out.println("Key: " + e.getKey());
List<String> valueList = e.getValue();
for (String str : valueList) {
System.out.println("Value: " + str);
}
}
Response:
Status code: 200
Key: Date
Value: Wed, 13 Jul 2016 14:06:43 GMT
Key: Server
Value: Jetty(9.2.16.v20160414)
Key: X-Application-Context
Value: gateway:8080
Key: X-Content-Type-Options
Value: nosniff
Key: X-XSS-Protection
Value: 1; mode=block
Key: Cache-Control
Value: no-cache, no-store, max-age=0, must-revalidate
Key: Pragma
Value: no-cache
Key: Expires
Value: 0
Key: X-Frame-Options
Value: DENY
Key: Content-Type
Value: application/json; charset=UTF-8
Key: Via
Value: 1.1 localhost:8080
Key: Vary
Value: Accept-Encoding
Key: Transfer-Encoding
Value: chunked
The RestTemplate code that i am using to get this:
public static <T> ResponseEntity<T> postServiceCall(String url, Class<T> responseType,
Object postBody,MultiValueMap<String, String> headers) {
HttpEntity<Object> request = new HttpEntity<Object>(postBody, headers);
ResponseEntity<T> response=restTemplate.exchange(url, HttpMethod.POST, request,responseType);
return response;
}

I am not sure what's WebServiceCaller does, however RestTemplate#exchange should return all the headers.

Related

#RequestMapping handling of special characters

I have a REST API
#RequestMapping(value = "/Save", method = RequestMethod.POST,
consumes = {"application/json;charset=ISO-8859-1" },
produces = {"application/json;charset=ISO-8859-1" })
public SaveResponse save(#RequestBody SaveRequest request) {
//some codes
}
}
My request contains the following lines
{
:
:
"mailingAddress": {
"addressLine1": "Carrera 36E N°",
"addressLine2": "Medellín, Antioquia",
"country": "COL"
}
:
And I received a 400 Bad Request
HTTP/1.1 400 Bad Request
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Date: Wed, 16 Jun 2021 12:26:37 GMT
Pragma: no-cache
Content-Length: 0
Expires: 0
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-RBT-Optimized-By: CANA014IJT (RiOS 6.1.1a #11) SC
And when I removed the characters "°" and "í" from the request, then the request can go through with no error. What is my problem?
Thank you.
You can try changing the character set from ISO-8859-1 to UTF-8, as the former does not support as wide an array of character mappings (What is the difference between UTF-8 and ISO-8859-1?).

Apache Jmeter : Post an object not working with ModelAttribute

I am working on stress testing our webapplication written in Spring-MVC.
I would like to send an object Person to the application. I have added a system out to get the email, but whenever I am sending the object, it is null. What am I doing wrong?
Server code :
#RequestMapping(value = "/person/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("person") Person person, BindingResult bindingResult) {
try {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
System.out.println("String is "+json);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("Person add called"+person.getUsername());
person.setUsername(this.stripHTML(person.getUsername()));
int personId = this.personService.addPerson(person);
if (!(personId == 0)) {
Person person1 = this.personService.getPersonById(personId);
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
Authentication authentication = new UsernamePasswordAuthenticationToken(person1, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
return "redirect:/canvaslisting";
} else {
return "redirect:/";
}
}
Object sent in body data :
{"person":{"id":0,"username":"testemail#gmail.com","firstName":"test","cleanCacheFlag":false,"googleDrive":false,"dropbox":false,"evernoteConsumed":false,"statusChangeTimeStamp":null,"useCalendar":false,"newsletterFlag":false,"tourSteps":null,"profession":null,"notiz":null,"telePhone":null,"lastVisitedBoards":null,"leftGroup":null,"optionalEmail":null,"facebookLink":null,"xingLink":null,"linkedinLink":null,"lastOnlineTimestamp":null,"userRole":null,"homePage":null,"excelImportQuota":0,"toEmail":null,"code":null,"authorities":null,"role":null,"newpassword":null,"token":null,"profilePhotoString":null,"accountNonExpired":true,"credentialsNonExpired":true,"accountNonLocked":true,"active":true,"enabled":false}
}
Output :
Person add callednull
Screenshot :
Sample result
Thread Name: Thread Group 2-5
Sample Start: 2017-06-29 15:17:11 IST
Load time: 6
Connect Time: 0
Latency: 6
Size in bytes: 237
Sent bytes:0
Headers size in bytes: 205
Body size in bytes: 32
Sample Count: 1
Error Count: 1
Data type ("text"|"bin"|""): text
Response code: 415
Response message: Unsupported Media Type
Response headers:
HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Language: en
Content-Length: 1048
Date: Thu, 29 Jun 2017 09:47:11 GMT
Connection: close
HTTPSampleResult fields:
ContentType: text/html;charset=utf-8
DataEncoding: utf-8
Request:
POST http://127.0.0.1:8080/person/add/
POST data:
{"person":{"id":0,"username":"testemail#gmail.com","firstName":"test","cleanCacheFlag":false,"googleDrive":false,"dropbox":false,"evernoteConsumed":false,"statusChangeTimeStamp":null,"useCalendar":false,"newsletterFlag":false,"tourSteps":null,"profession":null,"notiz":null,"telePhone":null,"lastVisitedBoards":null,"leftGroup":null,"optionalEmail":null,"facebookLink":null,"xingLink":null,"linkedinLink":null,"lastOnlineTimestamp":null,"userRole":null,"homePage":null,"excelImportQuota":0,"toEmail":null,"code":null,"authorities":null,"role":null,"newpassword":null,"token":null,"profilePhotoString":null,"accountNonExpired":true,"credentialsNonExpired":true,"accountNonLocked":true,"active":true,"enabled":false}
}
[no cookies]
Request Headers:
Connection: close
Content-Length: 717
Content-Type: application/x-www-form-urlencoded
Change header Content-Type in HTTP Header Manager from:
Content-Type: application/x-www-form-urlencoded
To:
Content-Type: application/json
Shouldn't you just have an #RequestBody annotation on person ?
public String addPerson(#RequestBody Person person);
Well, there is a typo or copy-paste issue in your JMeter request
Also your JMeter configuration might be missing HTTP Header Manager configured to send Content-Type header with the value of application/json

Angular2 - unable to get Set-Cookie from auth. response (jaas, wf)

Iam trying to authenticate from Angular2.1.0 to JAAS form-based j2ee app on WildFly 8.2
let j_username = 'sb2';
let j_password = 'sb222';
let url: string = 'http://127.0.0.1:8888/prototype-rest/j_security_check';
let body = 'j_username=' + j_username + '&j_password=' + j_password;
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
})
;
//let options = new RequestOptions({headers: headers, withCredentials : true});
let options = new RequestOptions({headers: headers});
this.http.post(url, body, options)
.subscribe(
(res: Response) => {
console.log('res = ' + res);
console.log(res.headers.keys());
var headers = res.headers;
var setCookieHeader = headers.get('Set-Cookie');
console.log('setCookieHeader = ' + setCookieHeader);
},
err => {
console.log('err = ' + err);
}
)
;
response from wildfly
HTTP/1.1 200 OK
Expires: 0
Cache-Control: no-cache, no-store, must-revalidate
X-Powered-By: Undertow/1
Set-Cookie: JSESSIONID=iyD6Yz_Tj7xsIM1zRDHaR2bh.sk-za-04702; path=/prototype-rest
Access-Control-Allow-Headers: accept, authorization, content-type, x-requested-with
Server: WildFly/8
Pragma: no-cache
Access-Control-Expose-Headers: Set-Cookie
Date: Thu, 03 Nov 2016 14:01:41 GMT
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Length: 0
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Max-Age: 3600
My problem is that I am not able to read Set-Cookie, if I use withCredentials : true (I am not sure if I should), response fails ... I'd like to add JSESSIONID to request, where I register websocket ...

HttpUrlConnection setting Range in Android is ignored

I'm trying get a 206 response from my server using Android.
Here's the code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL("http://aviddapp.com/10mb.file");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("Range", "bytes=1-2");
urlConnection.connect();
System.out.println("Response Code: " + urlConnection.getResponseCode());
System.out.println("Content-Length: " + urlConnection.getContentLength());
Map<String, List<String>> map = urlConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() +
" ,Value : " + entry.getValue());
}
InputStream inputStream = urlConnection.getInputStream();
long size = 0;
while(inputStream.read() != -1 )
size++;
System.out.println("Downloaded Size: " + size);
}catch(MalformedURLException mue) {
mue.printStackTrace();
}catch(IOException ioe) {
ioe.printStackTrace();
}
return null;
}
}.execute();
}
Here's the output:
I/System.out: Respnse Code: 200
I/System.out: Content-Length: -1
I/System.out: Key : null ,Value : [HTTP/1.1 200 OK]
I/System.out: Key : Accept-Ranges ,Value : [bytes]
I/System.out: Key : Cache-Control ,Value : [max-age=604800, public]
I/System.out: Key : Connection ,Value : [Keep-Alive]
I/System.out: Key : Date ,Value : [Tue, 04 Oct 2016 07:45:22 GMT]
I/System.out: Key : ETag ,Value : ["a00000-53e051f279680-gzip"]
I/System.out: Key : Expires ,Value : [Tue, 11 Oct 2016 07:45:22 GMT]
I/System.out: Key : Keep-Alive ,Value : [timeout=5, max=100]
I/System.out: Key : Last-Modified ,Value : [Tue, 04 Oct 2016 07:36:42 GMT]
I/System.out: Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4]
I/System.out: Key : Transfer-Encoding ,Value : [chunked]
I/System.out: Key : Vary ,Value : [Accept-Encoding,User-Agent]
I/System.out: Key : X-Android-Received-Millis ,Value : [1475567127403]
I/System.out: Key : X-Android-Response-Source ,Value : [NETWORK 200]
I/System.out: Key : X-Android-Sent-Millis ,Value : [1475567127183]
I/System.out: Downloaded Size: 10485760
Now I'm doing the same thing is pure java.
public static void main(String... args) {
try {
URL url = new URL("http://aviddapp.com/10mb.file");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("Range", "bytes=1-2");
urlConnection.connect();
System.out.println("Respnse Code: " + urlConnection.getResponseCode());
System.out.println("Content-Length: " + urlConnection.getContentLength());
Map<String, List<String>> map = urlConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() +
" ,Value : " + entry.getValue());
}
InputStream inputStream = urlConnection.getInputStream();
long size = 0;
while(inputStream.read() != -1 )
size++;
System.out.println("Downloaded Size: " + size);
}catch(MalformedURLException mue) {
mue.printStackTrace();
}catch(IOException ioe) {
ioe.printStackTrace();
}
}
Here's the output
Respnse Code: 206
Content-Length: 2
Key : Keep-Alive ,Value : [timeout=5, max=100]
Key : null ,Value : [HTTP/1.1 206 Partial Content]
Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4]
Key : Content-Range ,Value : [bytes 1-2/10485760]
Key : Connection ,Value : [Keep-Alive]
Key : Last-Modified ,Value : [Tue, 04 Oct 2016 07:36:42 GMT]
Key : Date ,Value : [Tue, 04 Oct 2016 07:42:17 GMT]
Key : Accept-Ranges ,Value : [bytes]
Key : Cache-Control ,Value : [max-age=604800, public]
Key : ETag ,Value : ["a00000-53e051f279680"]
Key : Vary ,Value : [Accept-Encoding,User-Agent]
Key : Expires ,Value : [Tue, 11 Oct 2016 07:42:17 GMT]
Key : Content-Length ,Value : [2]
Downloaded Size: 2
As you can see I'm getting diffrent response codes in both cases. It seems like Android is not passing Range to the server maybe? What's happening here?
PS: I'm getting a 206 if the file size is 1mb.
I am relatively certain the error is not in the Android code.
It looks like the server might be delivering spurious results.
You can check with a third party tool (such as Postman) to determine the headers that web service is delivering.
My results using Postman. As you can see, it is delivering HTTP 200 (not 206). It is also not wending a capped Content-Length. If the server is yours, perhaps check that it is configured correctly. Also check your code with other servers.
Hi Can u try this piece of code, it seems i am getting HTTP 206 here.
new Thread() {
#Override
public void run() {
try {
URL url = new URL("http://aviddapp.com/10mb.file");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// urlConnection.setRequestMethod("HEAD");
urlConnection.setRequestProperty("Accept-Encoding", "");
urlConnection.setRequestProperty("Range", "bytes=1-2");
urlConnection.connect();
System.out.println("Response Code: " + urlConnection.getResponseCode());
System.out.println("Content-Length: " + urlConnection.getContentLength());
Map<String, List<String>> map = urlConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() +
" ,Value : " + entry.getValue());
}
InputStream inputStream = urlConnection.getInputStream();
long size = 0;
while (inputStream.read() != -1)
size++;
System.out.println("Downloaded Size: " + size);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}.start();
You just have to add this in async task.
Check this result commenting on/off this line.
urlConnection.setRequestProperty("Accept-Encoding", "");
I am not sure if this is related to Content-Length being cleared by android implementation by default. Look at the below snippet from the source code where it says it does gzip compression by default.
https://android.googlesource.com/platform/libcore/+/2e317a02b5a8f9b319488ab9311521e8b4f87a0a/luni/src/main/java/java/net/HttpURLConnection.java
By default, this implementation of HttpURLConnection
requests that servers use gzip compression and it automatically
decompresses the data for callers of getInputStream(). The
Content-Encoding and Content-Length response headers are cleared in
this case.
Can you try disabling the default caching using below code to check if that works?
urlConnection.setRequestProperty("Accept-Encoding", "identity");
PS: Sorry for bad formattings. Using the mobile version of SO.
Have you tried like that:
urlConnection.setRequestProperty("Range", "bytes=1000-");

Can't get Set-Cookie header from http response

I am developing a small web content scraper . Part of the code is to send a http request and get the cookie from the response header, so it can be set in the subsequent request.
The code to get the cookies is like this:
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
request.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
request.setHeader("Accept-Encoding","gzip,deflate,sdch");
if(cookie!=null)
{
request.setHeader("Cookie", cookie);
}
request.setHeader("Accept-Language","en-US,en;q=0.8,zh-CN;q=0.6");
request.setHeader("Cache-Control", "max-age=0");
request.setHeader("Connetion", "keep-alive");
request.setHeader("Host", "www.booking.com");
request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/32.0.1700.76 Safari/537.36");
try {
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println(statusCode);
//get all headers
Header[] headers = response.getAllHeaders();
for (Header header : headers) {
System.out.println("Key : " + header.getName()
+ " ,Value : " + header.getValue());
}
System.out.println("----------------------------------------------------------");
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The url I used to test is http://www.booking.com/hotel/il/herods-hotels-spa.html#tab-reviews
The result printed is like this:
200
Key : Server ,Value : nginx
Key : Date ,Value : Mon, 03 Feb 2014 05:15:41 GMT
Key : Content-Type ,Value : text/html; charset=UTF-8
Key : Connection ,Value : keep-alive
Key : Cache-Control ,Value : private
Key : Vary ,Value : User-Agent, Accept-Encoding
Key : Set-Cookie ,Value : bkng=11UmFuZG9tSVYkc2RlIyh9YdMHS7ByVcpJ6zdHwCKMHsY37i1DyVPCutMoSY%2F9OR7ixF74JFUj1%2BJ3pF8ntbVX55kLQJvNnfE6Qco2NDwnHPzomws7z40vIxLRgwBTWU9CTbAN3zZqJGksaPN3GqHpSWJ%2BMIKlI5hQN6ZcJnKsU3rR9KXmRVS4plyPQf4gqmsjR131%2BtuuBiULzmDsKzejJZg%2BFgWWUOWS71bCxUGvJbeBBo1HRmUVmigKDEyHylYplnhKkriMof25dYccWyLQoBjIyUL4QZWr58O5D7fKPHDYWSY9y7k%2Bxfk7irIsyKdu%2B0owjpGp2%2BncNdphtqPZqdpeCyky1ReSjWVQ4QuZemceNGmfZGwxm%2BQxu0%2BkBEsJA5zY%2BoqulR8MJIBKZpFqsuvbeDZ9r5UJzl5c%2Fqk7Vw5YU1I%2FQunbw7PHra7IaGp6%2BmHnH2%2BeyiMDhAjWL769ebuwG2DhrgfB6eI0AGZE%2F6T0uA4j7bxA%2FwUdhog6yOu%2FSeTkPl%2FTAiIetVyKLfT1949ggWKfk1kGzmjnowOlZzPbxr1L%2FAifBjInWZ6DreY1Mr2A3%2BfjFYaHJYnS8VpB%2BZappBpGXBUVfHe%2FQ7lbDwNd6TCCzigpsb17LtvFYsb3JiZ%2BQFF82ILNwWFKz6B1xxEEbCRVoq8N%2FcXXPStyGSwApHZz%2Bew6LNI7Hkd2rjB1w3HenUXprZWR3XiWIWYyhMAbkaFbiQV2LThkl2Dkl%2FA%3D; domain=.booking.com; path=/; expires=Sat, 02-Feb-2019 05:15:41 GMT; HTTPOnly
Key : X-Recruiting ,Value : Like HTTP headers? Come write ours: booking.com/jobs
However when I uploaded this small program to my server, and ran it, the result became:
200
Key : Server ,Value : nginx
Key : Date ,Value : Mon, 03 Feb 2014 05:14:14 GMT
Key : Content-Type ,Value : text/html; charset=UTF-8
Key : Connection ,Value : keep-alive
Key : Cache-Control ,Value : private
Key : Vary ,Value : User-Agent, Accept-Encoding
Key : X-Recruiting ,Value : Like HTTP headers? Come write ours: booking.com/jobs
The Set-Cookie header disappeared and my subsequent requests to other content pages within the same site(which are supposed to be loaded by a javascript in the first page I requested) all returned 400 error which I guess is because the cookie missing.
I can't figure out why, and the differences between my pc and the server that I know are:
My pc is running Windows 7 and actually has a Chrome browser, while the server is running Linux and doesn't have any actual browser.
The ip addresses are different.
Other than these, I can't think of any yet.
Any suggestion or advice to solve this problem will be appreciated. Thank you.
set-cookie is a forbidden response header name, you can't read it using browser-side JavaScript
developer.mozilla.org
Browsers block frontend JavaScript code from accessing the Set Cookie header, as required by the Fetch spec, which defines Set-Cookie as a forbidden response-header name that must be filtered out from any response exposed to frontend code.

Categories