I have a jquery script that sends data to my spring controller using PUT type. But controller never gets hit. If i change PUT to POST everything works as expected, but i need to use exactly PUT. Could you please review my code and tell me what i am doing wrong?
jQuery
var values = $("form").serialize();
$.ajax({
type: "PUT",
url: "/user/" + elogin.val(),
async: false,
data: values,
success: function(resp) {\\doStuff}
})
Controller
#Controller
#RequestMapping(value = "/user")
public class RestController {
#RequestMapping(value = "/{userLogin}", method = RequestMethod.PUT)
#ResponseBody
public boolean updateUser(#PathVariable String userLogin,
#RequestParam("epassword") String password,
...)
throws ParseException {
if (...) {
return false;
}
\\doStuff
return true;
}
}
FireBug error message
400 Bad Request
Response Headers
Connection close
Content-Length 1072
Content-Type text/html;charset=utf-8
Date Tue, 03 Sep 2013 10:21:28 GMT
Server Apache-Coyote/1.1
Request Headers
Accept */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Content-Length 168
Content-Type application/x-www-form-urlencoded; charset=UTF-8
Cookie JSESSIONID=5A510B1FB82DA6F3DD9E9FA8D67A8295
Host localhost:8085
Referer http://localhost:8085/welcome
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0
X-Requested-With XMLHttpRequest
Error
HTTP Status 400 - Required String parameter 'epassword' is not present
type Status report
message Required String parameter 'epassword' is not present
description The request sent by the client was syntactically incorrect.
Solved by adding to web.xml
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Hi I dont know am correct or not but I think we cannot use PUT for jquery ajax
type (default: 'GET')
Type: String
The type of request to make ("POST" or "GET"), default is "GET". Note: Other HTTP request methods, such as PUT and DELETE, can also be used here, but they are not supported by all browsers.
check this
http://api.jquery.com/jQuery.ajax/
Related
My React code as down below
and it always turn to text/plain;charset=UTF-8
I found that cors support just
application/x-www-form-urlencoded
multipart/form-data
text/plain
but I want to send the json to Http req. how I can fix it?
The problem is that you're setting the wrong HTTP header to accept JSON as a response. The header you should set is Accept:
axios.get('my/url', {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
}
})
I m trying to write a unitTest for an endpoint.
This endpoint should take a json object as follow
#PostMapping(value = "/test")
public String endPoint(#RequestBody String obj) {
try {
JSONObject inputJsonObject = new JSONObject(individualJson);
} catch (JSONException | IOException e) {
throw new MyException("JSONObject not valid");
}
......
}
in my unit test I m trying to send an empty string and I m expecting to have a JSONException
mvc.perform(post(url)
.contentType(MediaType.APPLICATION_JSON)
.content(""))
.andReturn().getResponse();
however this my post is not hiting my endpoint... it is like it is not able to evaluate an empty String as a String : "" is not hitting the endpoint however
" " (with a space) is hitting the endpoint ...
Here is the exception returned by the call :
org.springframework.http.converter.HttpMessageNotReadableException:
Required request body is missing: public
com.ba.mypackage.MyController.endPoint(java.lang.String)
How may I access the endpoint by passing an empty string "" ?
You can't, since sending an empty string as body is the same thing as not sending a body in this context, and not sending a body is disallowed by #RequestBody annotation, since default value for its required attribute is true.
Sending an empty string as body is the same thing as not sending a body because in HTTP, a POST request has a header section and body section separated by CRLF, and separating CRLF is required both when having a body and not having it. This is how it is defined in HTTP specification, see https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html for details:
5 Request
A request message from a client to a server includes, within the first line of that message, the method to be applied to the resource, the identifier of the resource, and the protocol version in use.
Request = Request-Line ; Section 5.1
*(( general-header ; Section 4.5
| request-header ; Section 5.3
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 4.3
A header section you provide, and body is something you want to have as empty string. However, you need to anyway have CRLF in place, so request would look something like this:
POST /url HTTP/1.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, application/javascript, text/javascript
Content-Length: 0
Host: localhost:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_112)
Accept-Encoding: gzip,deflate
or, to put [CRLF] on where that character is,
POST /url HTTP/1.1[CRLF]
Content-Type: application/json; charset=UTF-8[CRLF]
Accept: application/json, application/javascript, text/javascript[CRLF]
Content-Length: 0[CRLF]
Host: localhost:8888[CRLF]
Connection: Keep-Alive[CRLF]
User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_112)[CRLF]
Accept-Encoding: gzip,deflate[CRLF]
[CRLF]
Since the content-length is zero and the CRLF separator needs to always be there, how would you tell a difference between empty string sent as body and no body sent at all? The thing is you can't, in this context it's the same thing, so what you ask can't be done.
Because empty string is not a valid String and treated similar to Null.
However if you just want to hit the controller and not interested in the empty strings value inside of controller, just mark the parameter as optional.
public String endPoint(#RequestBody(required = false) String obj) {
I am using a spring boot restcontroller that has a method with requestmapping of GET and it takes a string parameter. Parameter has to be mapped from the URL PathVariable such /method/{param}.
#ResponseStatus(HttpStatus.OK)
RequestMapping(value = "/method/{param}", method =
RequestMethod.GET)
public ResponseEntity findByName(#PathVariable String param){
logger.info(param);// this log has " before and after the string
String p = StringEscapeUtils.unescapeHtml4(param);
logger.info(p);
...
}
HTTP Request
GET /SampleDataService/method/vanilla HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
I do get the value param but it has the html escaped quotation marks appended to it.
For eg, if I call /method/vanilla I get "vanilla"
Right now I am using StringEscapeUtils.unescapeHtml4(param) and then replacing the quotes with empty string.
But I want to know if there is some spring boot configuration that can prevent extra quotes in string PathVariables.
In url having multiple parameters
#RequestMapping(value="/method/{param:.+}", method=RequestMethod.GET)
public ResponseEntity findByName(#PathVariable("param")String param){
....
}
I want to use HttpOnly cookies and I set it in Java as follows:
...
Cookie accessTokenCookie = new Cookie("token", userToken);
accessTokenCookie.setHttpOnly(true);
accessTokenCookie.setSecure(true);
accessTokenCookie.setPath("/");
response.addCookie(accessTokenCookie);
Cookie refreshTokenCookie = new Cookie("refreshToken", refreshToken);
refreshTokenCookie.setHttpOnly(true);
refreshTokenCookie.setSecure(true);
refreshTokenCookie.setPath("/");
response.addCookie(refreshTokenCookie);
...
I got the client side the response with the cookies, but when I send the next request I do not have the cookies on the request. Maybe I miss something, but as I understood, these HttpOnly cookies has to be sent by the browser back on every request (JavaScript does not have access to those cookies) coming to the defined path.
I have the following Request Headers:
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8,hu;q=0.6,ro;q=0.4,fr;q=0.2,de;q=0.2
Authorization:Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Connection:keep-alive
Content-Length:35
content-type:text/plain
Host:localhost:8080
Origin:http://localhost:4200
Referer:http://localhost:4200/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36
X-Requested-With:XMLHttpRequest
and the following response headers:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:4200
Access-Control-Expose-Headers:Access-Control-Allow-Origin, Content-Type, Date, Link, Server, X-Application-Context, X-Total-Count
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:482
Content-Type:application/json;charset=ISO-8859-1
Date:Fri, 03 Feb 2017 13:11:29 GMT
Expires:0
Pragma:no-cache
Set-Cookie:token=eyJhbGciO;Max-Age=10000;path=/;Secure;HttpOnly
Set-Cookie:refreshToken=eyJhb8w;Max-Age=10000;path=/;Secure;HttpOnly
Vary:Origin
Also in the client side I use withCredentials: true in Angular2 and X-Requested-With:XMLHttpRequest as request header.
And it is Cross Domain.
Yes you are correct having the cookie your browser should send the cookie automatically while it is not expired and the httpOnly flag means it cannot be accessed or manipulated via JavaScript.
However
You need to ensure that the cookie you are sending is not cross domain, if you require it cross domain you will need to handle it differently.
I have to do a form submit through angularjs and java layer has to process the request.
Sample Request:
Request Header:
PUT /student/form HTTP/1.1
Host: mydomain
Connection: keep-alive
Content-Length: 154
Origin: mydomain
Accept-Language: en
Content-Type: application/x-www-form-urlencoded
Accept: application/json, text/plain, */*
X-Requested-With: XMLHttpRequest
Form Data:
------WebKitFormBoundaryJ8UG5IFHivltab5e
Content-Disposition: form-data; name="formData"
[object Object]
------WebKitFormBoundaryJ8UG5IFHivltab5e--
In Java,
#org.springframework.stereotype.Service
#Path("/student")
public class FormSubmitService {
#PUT
#Path("/form")
#Consumes({MediaType.MULTIPART_FORM_DATA})
public void saveForm(#Context HttpServletRequest request,
#RequestBody FormDomainRequest formDomainRequest) {
LOG.debug("requets from browser");
}
}
But i could not get the form data in request to map to my pojo class "FormDomainRequest"
Please let me know there is there any wrong in my service layer!