some strange situation I have and need your help.
For clear understand communication flow (simple client-server communication):
3rd provider send POST callback (application/x-www-form-urlencoded) ---> to API. API take all parameters from POST request (here are issue - no params).
What I see in response payload on 3rd provider (what he did):
<form name="redirectToCaForm" action="http://someURL/api/consentFailed" method="POST" enctype="application/x-www-form-urlencoded">
</form>
<script>
document.redirectToCaForm.submit();
</script>
In API code looks like this to catch request and it params:
#PostMapping(path = "/api/consentFailed",
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<?> postConsentFailedCallback(HttpServletRequest request,
#RequestParam final MultiValueMap<String, String> formParams) {
...
...
}
But not any formParams came. Request working only with written consume. Also I see and know what 3rd provider send, but why API doesn't catch params? Any suggestions will be appreciated.
Related
I am trying to share data from one server(8081) to another(8082) in Spring Boot using ResponseEntity, but I am not able to built the body.
Here is the code which I have written,
Server 1-
#GetMapping("/redirect")
public ResponseEntity<Void> redirectPgServer(#RequestParam("txnId") String txnId,
#RequestParam("amount") String amount) {
// Redirect to server 2
ProductDetails ref=new ProductDetails();
ref.setTxnId("txnId");
ref.setAmount("amount);
HttpHeaders head = new HttpHeaders();
String url = "http://localhost:8082/redirect-server";
System.out.println(url);
head.setLocation(URI.create(url));
return new ResponseEntity<Void>(ref, head, HttpStatus.FOUND);
}
Server2-
#GetMapping(value = "/redirect-server")
public String validateData(#RequestBody ProductDetails ref)
{
//Server 2 receive data
System.out.println(ref.getAmount());
//Does not gives any output since it throws error Request Body Missing, also if I mention
post mapping above it throws error Request method 'GET' not supported]
return "index"; //Using Thymeleaf for displaying html page.
}
I am able to share the data using only header by manipulating the url and using PathVariable but I want to use Post Mapping as I want to hide the parameters in the Url which are visible to User at Browser. Also I have tried using RestTemplate which brings me back to Server 1 and it throws error- Spring rest template cannot convert from text/html utf8.
My suggestion is to annotate both methods with #PostMapping, in both remove just the #RequestBody Annotation. In the first server you should respond with a 307 HTTP Code (which is the temporary redirect) basically this tells to the browser, to retry the call to another endpoint(which is given into the Location header).
Something like this :
Server 1
#PostMapping(value = "/redirect", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity redirect(Product product) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(URI.create("http://localhost:8082/product"));
return new ResponseEntity(httpHeaders, HttpStatus.TEMPORARY_REDIRECT);
}
Server 2
#PostMapping(value = "/product", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void redirect(Product prod) {
System.out.println(prod.getId());
//do your stuff
}
HTML Page
<html>
<body>
<form action="http://localhost:8081/redirect" method="POST">
<input name="id">
<input name="name">
<button type="submit">Send</button>
</form>
</body>
</html>
If you don't use a form, instead you use some kind of async call you MUST specify the url form encoding. Otherwise you will get a 405.
I've tried the code with postman and with a html page it does work correctly. (Tried with Firefox)
If something it's not clear don't esitate to ask.
I have found a similar question where i took inspiration from
A good way to redirect with a POST request?
I have designed a REST based post Service using Spring 3.
The service method consumes parameter as String and responds data as String. The param and response can be json or string
#RequestMapping(value = "/service", method = RequestMethod.POST)
public #ResponseBody String Service(#RequestParam("param") String param) {
Sample POST Request:
http://IP:PORT/test-project/service
param={"name":"John"}
Sample response to above request:
{"age":"31"}
Is there a way to safeguard this request against Cross Site Scripting?
If yes then how can I achieve XSS support once I receive request on param parameter??
If you aren't returning the parameter value (or any manipulation of it) in the response, you don't have an XSS vulnerability.
Not that it means that your service is completely secure, of course.
I have an web application and I'm trying to creat a simple POSt method that will have a value inside the body request:
#RequestMapping(value = "/cachettl", method = RequestMethod.POST)
#CrossOrigin(origins = "http://localhost:3000")
public #ResponseBody String updateTtl(#RequestBody long ttl) {
/////Code
}
My request which I call from some rest client is:
POST
http://localhost:8080/cachettl
Body:
{
"ttl": 5
}
In the response I get 403 error "THE TYPE OF THE RESPONSE BODY IS UNKNOWN
The server did not provide the mandatory "Content-type" header."
Why is that happening? I mention that other GET requests are working perfectly.
Thanks!
Edit:
When I tried it with postman the error message I got is "Invalid CORS request".
Spring application just doesn't know how to parse your message's body.
You should provide "header" for your POST request to tell Spring how to parse it.
"Content-type: application/json" in your case.
You can read more about http methods here: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data
Updated:
Just in case of debug, remove useless annotations to test only POST mechanism. Also, change types of arg and return type. And try to use case-sensitive header.
#RequestMapping(value = "/cachettl", method = RequestMethod.POST)
public void updateTtl(#RequestBody String ttl) {
System.out.println("i'm working");
}
Since the error is about the response type, you should consider adding a produces attribute, i.e :
#RequestMapping(value = "/cachettl", method = RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
Since you are also consuming JSON, adding a consumes attribute won't hurt either :
#RequestMapping(value = "/cachettl", method = RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE, produces=MediaType.APPLICATION_JSON_VALUE)
The error message is slightly misleading. Your server code is not being hit due an authentication error.
Since you say spring-security is not in play then I suspect you're being bounced by a CORS violation maybe due to a request method restriction. The response body generated by this failure (if any at all) is automatic and will not be of the application/json type hence the client failure. I suspect if you hit the endpoint with something that doesn't care for CORS such as curl then it will work.
Does your browser REST client allow you to introspect the CORS preflight requests to see what it's asking for?
I am trying to pass clusterId=1 as parameter from
<a href="http://192.168.11.134:8080/UniconnectConfigurationWeb/nodes?clusterId=1"> and get it into spring mvc controller through #PathParam("clusterId")Integer clusterId. But I'm getting 404 error.
Guide me how to pass parameter through anchor tag and how to hit controller and get the parameter value.
I am sharing my code below,
#RequestMapping(value = "/nodes?clusterId={clusterId}", method = RequestMethod.GET)
public ModelAndView nodes(#RequestParam("clusterId")Integer clusterId,HttpSession session, HttpServletRequest request) {
System.out.println(clusterId);
return dashboard;
}
}
<c:url var="myURL" value="http://192.168.11.134:8080/UniconnectConfigurationWeb/nodes">
<c:param name="clusterId" value="1"/>
</c:url>
Here you are using clusterId as Request Parameter , and passing from client side to server side. but in your server side code you are used ?clusterId={clusterId} in Request Mapping annotation and you are trying to receive that request parameter with #RequestParam Annotation. here #RequestParam is enough for receiving Request Parameter. so, no need to use this ?clusterId={clusterId}`, this is not correct way of writing server side URL.
it may helps you for better understanding #RequestParam vs #PathVariable
My issue:
Having a form in a simple HTML, with action="/myController".
I need to send the form data to my Controller and from there I need to make another POST to an external Controller.
<form method="post" action="/myController">
<textarea name="data"></textarea>
</form>
And my Spring Controller looks something like this:
#RequestMapping(method = RequestMethod.GET, value = "/myController")
#ResponseBody
public String myController(#RequestBody MultiValueMap<String, String[]> formData) {
RestTemplate rest = new RestTemplate();
ResponseEntity<String> response = rest.postForEntity("urlPath", formData, String.class);
String manipulatedResult = manipulateResult(response.getBody());
return manipulatedResult;
}
I need to pass form data, to my controller, it should send form data further to the "urlPath" and recieve a response. I need to manipulate that response and return a result.
My question is, how to send the form data further, without manipulating the request?
Thanks in advance.
Your Response doesn't need to be a String it can be a well formed java object. In this case i do not see any issue returning ResponseEntity object without converting this into String.
#ResponseBody will convert returned java object to JSON/Xml based response to outside world.
you can use ModelAndView class.
Refer the following link: http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/web/portlet/ModelAndView.html