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){
....
}
Related
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 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!
I am able to set content type using cxf library but I don't know how to set Authorization header. Whenever I set user name and password then it set Authorization header and encode whole value and add Basic. I don't want to do this. I want to add Authorization header with plain string which ever I provide. Please help me to solve out this problem.
AMPServices services = new AMPServices();
CoreXmlPort coreXmlPort = services.getAMPSoapService();
Client client = ClientProxy.getClient(coreXmlPort);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy=httpConduit.getClient();
String contentType=httpClientPolicy.getContentType();
contentType="application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8";
httpClientPolicy.setContentType(contentType);
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("username");
authorizationPolicy.setPassword("password");
httpConduit.setAuthorization(authorizationPolicy);
It generates following request xml.
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: Basic aXNoaXAgcGIvd3NkZXZlbDowNzZhNjFjYTM5MDcxODAxODVjNWRkMjM2YTdkMzZhNGQ1ODg5OWFj
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I want this type of request
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: username;password
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I was not able to do it. Please help me to solve out this problem.
Thanks,
Awadhendra
I think you are trying to call is a RestFul Service, so that's why the server side always response with a different content type than you expected (json instead of soap/xml). Is your url endpoint based on http protocol? If yes, do you need send additional parameters to this url?
The issue here is that the client you are using to interact with Webservice expecting XML based Soap Messages , while the service is serving JSON as a return media.
Either convert your client to use the JSON format and communicate using that, or alternatively use the XML based endpoint , consult with webservice provider for that.
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/
I want to replicate a working POST request in Java. For testing purpose, lets take message like: 'äöõüäöõüäöõüäöõü'
Working POST request (with encoded message of 'äöõüäöõüäöõüäöõü'):
Header
POST http://www.mysite.com/newreply.php?do=postreply&t=477352 HTTP/1.1
Host: www.warriorforum.com
Connection: keep-alive
Content-Length: 403
Origin: http://www.mysite.com
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko)Chrome/14.0.835.202 Safari/535.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept: */*
Referer: http://www.mysite.com/test-forum/477352-test.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: bblastvisit=1319205053; bblastactivity=0; bbuserid=265374; bbpassword=1125e9ec1ab41f532ab8ec6f77ddaf94; bbsessionhash=91444317c100996990a04d6c5bbd8375;
Body
securitytoken=1319806096-618e5f9012901e2d818bf2c74c2121baa064be57&ajax=1&ajax_lastpost=1319806096&**message=%u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC**&wysiwyg=0&styleid=1&signature=1&fromquickreply=1&s=&do=postreply&t=477352&p=who%20cares&specifiedpost=0&parseurl=1&loggedinuser=265374
As we can see in the request body 'äöõüäöõüäöõüäöõü is encoded as: %u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC
Now i want to replicate it.
Lets Url encode the text with charset utf-8 in Java:
String userText = "äöõüäöõüäöõüäöõü";
String encoded = URLEncoder.encode(userText, "utf-8");
Result: %C3%A4%C3%B6%C3%B5%C3%BC%C3%A4%C3%B6%C3%B5%C3%BC%C3%A4%C3%B6%C3%B5%C3%BC%C3%A4%C3%B6%C3%B5%C3%BC%0A%0A%0A%5BSIZE%3D%221%22%5D%5BI%5D << NOT THE SAME
Lets try ISO-8859-1:
String userText = "äöõüäöõüäöõüäöõü";
String encoded = URLEncoder.encode(userText, "ISO-8859-1");
Result: %E4%F6%F5%FC%E4%F6%F5%FC%E4%F6%F5%FC%E4%F6%F5%FC%0A%0A%0A%5BSIZE%3D%221%22%5D%5BI%5D << NOT THE SAME
Neither of them produce the same encoded string as in the working example, but all of them have the same input. What am I missing here?
%u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC%u00E4%u00F6%u00F5%u00FC
I don't know what the above data is encoded as, but it isn't application/x-www-form-urlencoded; charset=UTF-8 as the request claims. This is not legal data for this MIME type.
It looks like some UTF-16BE-encoded form.
URLEncoder.encode(userText, "utf-8"); would be the correct way to encode the application/x-www-form-urlencoded; charset=UTF-8 values if this was actually what the server was expecting. (ref)