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
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 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
I'm working on a Spring MVC application and have a client that I have no control over. This client is POSTing JSON data but transmitting a application/x-www-form-urlencoded header. Spring naturally trusts this header and tries to receive the data but can't because its JSON. Has anyone had experience overriding the header that Spring receives or just specifying exactly what type of data is coming, regardless of the headers?
You can do two things;
Change the client to send the Content-Type:
application/json header
Write a Servlet Filter or Spring Interceptor which is on top of the Spring Controller and checks for the header Content-Type. If it is not application/json then it changes it to application/json.
Why don't you write a separate controller to handle application/x-www-form-urlencoded requests. If the request is a valid JSON, then you can parse it and forward it to to appropriate service.
This way you can also handle a case in future where you get request of same type which is not a valid JSON.
#RequestMapping(value = "/handleURLEncoded", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public #ResponseBody Object handleURLEncoded(HttpEntity<String> httpEntity) {
String json = httpEntity.getBody();
//now you have your request as a String
//you can manipulate it in any way
if(isJSONValid(json)) {
JSONObject jsonObj = new JSONObject(json);
//forward request or call service directly from here
//...
}
//other cases where it's not a valid JSON
}
Note: isJSONValid() method copied from this answer
Simply, I'm trying to parse a List of composite objects passed from Spring controller via ModelAndView object as the following
Spring part
ModelAndView view = new ModelAndView("my view");
List<ActionHistory> histories = myService.getListData();
view.addObject("histories", histories);
return view;
In Jquery i tried couple of alternatives, first used the below line to construct JSON from List:
var list = JSON.stringify('${histories}');
console.log(histories);
the console is returning
"[com.companyname.projectname.domains.ActionHistory#48126327]"
TypeError: invalid 'in' operand a
I also tried from jquery-json by including "jquery.json.min.js" as a suggestion from this topic discussed but getting the same error above Serializing to JSON in jQuery
var histories = $.toJSON('${histories}');
console.log(histories);
Check you contentType in ajax function it should be.
contentType: "application/json"
Also your Spring controller which is handling this mvc call should configure be configired with
produces=MediaType.APPLICATION_JSON_VALUE
e.g. something like
#RequestMapping(value ="/getList", method= RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
I use Spring MVC, I have controller with a method:
#RequestMapping(value = "/listReader", method = RequestMethod.POST)
public #ResponseBody
List<Reader> getListReader(ModelMap model) {
return libraryService.getAllReaders();
}
But I do not know:
How can use list (that I get from method getListReader by #ResponseBody) in JSP?
How can I get list in JSP?
How do to display a list in JSP-page?
How do to get the list from #ResponseBody in JSP?
Give an example, please.
You can't. #ResponseBody is basically telling Spring: take the object I (method) return and use any serializer you have that supports it and write it directly to the body of the HTTP response. There's no JSP involved here.
Instead you should add the list to the model and return the String view name of your JSP.
#RequestMapping(value = "/listReader", method = RequestMethod.POST)
public String getListReader(ModelMap model) {
model.addAttribute("someKey", libraryService.getAllReaders());
return "my-jsp";
}
then you can use EL in the JSP to retrieve it
<h3>${someKey}</h3>
Use JSTL to iterate over it.
#RequestMapping(value = "/listReader", method = RequestMethod.POST)
That defines an Endpoint.
I would suggest using RequestMethod.GET than RequestMethod.POST, since you want something from the server not POSTING something to the server.
On the other Hand, if you want to use that information on a JSP, there are two ways:
1) Some view could consume that information via a http-GET-Request like $.get in jQuery or ajax. After you got the data, you can insert it in your HTML
2) Instead of using ajax you could display it directly on the page.
Then, you have to put your List into a Model, which you can acces on your JSP with Expression Language. Then you have to remove the #ResponseBody and return an according view instead.