I am having a problem with passing a cookie while trying to make subsequent requests with AJAX to my Spring MVC controller.
For e.g. I have a /login endpoint to which I pass some JSON via POST method and it sets the cookie. I see the cookie in the firebug:
As you can see it is there. I am creating a cookie like this:
NewCookie cookie = new NewCookie(new Cookie(SECURITY_TICKET, encodedTicket, configKey, null), null, (int) TimeUnit.MINUTES.toSeconds(expireTime), expireTimeDate, false, false)
And setting it to HTTP headers:
httpHeaders.add(HttpHeaders.SET_COOKIE, cookie.toString());
Then these headers are being added to ResponseEntity like this:
ResponseEntity entity = new ResponseEntity<>(this.entity, this.httpHeaders, this.status)
And this response entity is returned. My conroller's methods are all REST based.
So then I am trying to call the other (/search) endpoint after successful login which functionality is expecting the cookie and it obviosly fails because for some reason cookie is not being passed back.
My AJAX calls looks like this:
$(function () {
$.ajax({
url: 'http://localhost:8080/dev-citigroup-citi/login',
type: 'POST',
dataType: 'json',
data: '{ "username": "client1", "password": "*******", "platform": "iOS", "UUID": "321321321", "application": "CitiReach", "applicationVersion": "1.0" }',
success: function (data, status, xhr) {
$.ajax({
url: 'http://localhost:8080/dev-citigroup-citi/search/eventattendee?q=*:*&start=0&rows=1&wt=json&indent=true',
type: 'GET',
xhrFields: { withCredentials:true },
success: function (data, status, xhr) {
console.log(data);
},
error: function (jqXHR) {
console.log(jqXHR);
}
});
},
error: function (jqXHR) {
console.log(jqXHR);
}
});
});
As I mentioned the /login is OK but the other call fails. I am adding xhrFields: { withCredentials:true } which should be including the cookie in the /search request but for some reason it is not.
I also have CORS being set up correctly:
Access-Control-Allow-Origin: http://localhost:63342
Access-Control-Allow-Credentials: true
http://localhost:63342 is the origin where the request comes from, it is configured in the CORS headers.
Any idea what might be wrong here?
I found the solution, so rather than having xhrFields: { withCredentials:true } on the method level, I've put it globaly:
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
And cookie is passed now within the subsequent requests. No idea why it doesn't work on method level, maybe a bug in jquery...
jQuery version I was using: 2.1.3
Maybe this will help someone in future.
Related
I am using Vue.js, axios and Spring.
On the page I have the following axios code
axios({
method: 'post',
url: '/user/info',
params: {
'_csrf' : document.getElementById('csrf_id').value,
'name' : 'job',
'age' : '25',
},
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json'}
});
And on the server I have a receiving method like this
#Controller
#RequestMapping("/user")
public class UserInfo {
#ResponseBody
#PostMapping(value = "/info", consumes = "application/x-www-form-urlencoded", produces = "application/json" + ";charset=utf8")
public String info(#RequestParam(value = "name") String name, #RequestParam(value = "age") String age) {
System.out.println(name);
System.out.println(age);
return "ok";
}
}
Axios makes a request to the server, but the server returns a 415 response.
The request headers are missing the application/x-www-form-urlencoded content type. I suspect the problem lies precisely in this.
Tell me, what am I doing wrong?
HttpMethod Post is a method of writing and transmitting data in the request body.
In your case, you put data through params. If you execute code as you write, data will be sent such as /user/info?_csrf=value&name=job&age=25 and there will be no data in the request body.
To get the response you want, you can modify it as below.
axios({
method: 'post',
url: '/user/info',
data: '_csrf=csrf&name=job&age=25',
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json'}
});
change params keyword to data and write data like querystring.
I am having difficulty understanding how can I return all methods that are allowed on my HTML page or on my embedded jetty-9.4.4.v20170414 server using Spark framework?
Java Spark code:
options("/panel/data/options", (request, response) -> request
.headers("Access-Control-Request-Method"));
AngularJS code:
$scope.options = function(){
$http({
method: 'OPTIONS',
url: 'http://localhost:4567/panel/data/options',
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function succesCallback(response){
alert(response.data)
});
};
This is what I have so far.
First, your Spark java method is modifying the request headers, it should only modify the response headers as your clients are not going to get back the modified request.
options("/panel/data/options", (request, response) -> response
.headers("Access-Control-Request-Method"));
Then in your angular method, as the back end is changing the headers of your response, then you should read those headers, not the data:
$scope.options = function(){
$http({
method: 'OPTIONS',
url: 'http://localhost:4567/panel/data/options',
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function succesCallback(response){
alert(response.headers)
});
};
#CrossOrigin(origins = "http://localhost:3000")
#GetMapping("")
public ResponseEntity<List<ToDoItemViewModel>> loadCategoriesByName(#RequestParam(required = false) String name)
{
List<ToDoItemViewModel> allItemsByCategoryName = toDoItemService.getAllItemsByCategoryName(name);
return new ResponseEntity<>(allItemsByCategoryName, HttpStatus.OK);
}
How can i pass just a primitive type to the controller, here is how my $.ajax looks like
$.ajax({
method: 'GET',
url: "http://localhost:8080/todItems",
contentType: 'application/json',
crossDomain: true,
data: 'Work',
success: (resp) => {
console.log(resp)
},
error: (resp) => {
console.log(resp);
}
})
Now when i debug it, it indeed sends the request to this controller, but the String name is always null for some reason, can you just show me what i have to adjust in my ajax request, it's probably something in the data field.
You are using GET Request with request params(#RequestParam annotation).
#RequestParam means that param in request pass across url, like this;
http://localhost:8080/todItems?name=Work
So, you just need to move data to url params.
If you prefer send data across request body, please do not use GET method, use POST instead. Many web servers are not supporting request body in GET Requests
I'm learning to pass a JSON object through ajax to a Spring Controller.
Found an article, that seems to explain how its done: http://hmkcode.com/spring-mvc-json-json-to-java/
From that point i added a #RequestMapping to the Controller:
#RequestMapping(value = "/get-user-list", method = RequestMethod.POST)
public #ResponseBody String testPost(#RequestBody ResourceNumberJson resourceNumberDtoJson) {
System.out.println(">>>>>>>>>>>>>>>>>>>>>> I AM CALLED");
return "111";
}
Then i'm forming my ajax post:
var json = {
"login" : "login",
"resource_number" : "111",
"identifier" : "1111",
"registrator_number" : "11111111111111"
};
console.log(JSON.stringify(json));
$.ajax({
type : "POST",
url : "/get-user-list",
dataType : "text",
data : JSON.stringify(json),
contentType : 'application/json; charset=utf-8',
mimeType: 'application/json',
success: function(data) {
alert(data.id + " " + data.name);
},
error:function(data,status,er) {
alert("error: "+data+" status: "+status+" er:"+er);
}
});
which is runned from "get-user-list" page.
When i'm trying to run this, i recieve a HTTP 415 error. Spring 4, Jackson 2.4
Cant understand what i'm doing wrong.
HTTP 415 means, that the media type is not supported.
Try changing your #RequestMapping annotation to
#RequestMapping(value = "/get-user-list",
method = RequestMethod.POST,
consumes="application/json")
You should also consider testing your REST-service with a client like RESTClient, Postman or even cURL to make sure it is working correctly before you start implementing the jQuery client.
I'm doing an ajax call to my server, and need to get the values from it. How is this done?
This is the ajax:
$.ajax({
type: "POST",
url: "http://localhost:8080/myapp/etc",
contentType: "application/json; charset=utf-8",
data: {"id": "1", "somekey": "somevalue"},
dataType: "json",
async: "true",
success: function(msg) {
alert("success " + msg);
},
error: function(msg) {
alert("error " + msg.toString());
}
});
I'm working with Restlets so I'm assuming the values would be in the Representation entity. This is the method:
#Post
public Representation doPost(Representation entity) {
String et = java.net.URLDecoder.decode(entity.getText(), "UTF-8");
System.out.println("the entity text " + et);
}
This prints out "id": "1", "somekey": "somevalue". But how do I get the other values? The async, the url, etc?
Restlet will give you access about the elements sent within the request (URL, headers, payload) but not to client-side configuration properties to build the request.
You can have a look at what is sent in the request for your AJAX call using tool like Chome console or Firebug.
The property async isn't sent within the request, so you can't get it from server side. For the URL, you can use this code within a server resource:
Reference reference = getRequest().getResourceRef();
String url = reference.toString();
For more details, have a look at javadocs for the class Reference: http://restlet.com/technical-resources/restlet-framework/javadocs/2.1/jee/api/org/restlet/data/Reference.html. This class allows you to have access to each element within it (host domain, port, path, ...).
Hope it helps you,
Thierry
The async is a client-side directive telling the client not to block while the ajax call is processed. The server doesn't know or care about this.
Getting the URL is possible server side using something like String url = ((HttpServletRequest)request).getRequestURL().toString();
you can do something like this, using the org.restlet.ext.json extension:
#Post
public Representation handle(JsonObject jo) {
System.out.println(jo.getString("id"));
System.out.println(jo.getString("somekey"));
return ...;
}