Spring 3.2 forward request with new object - spring

I'm trying to forward a request from one controller to another controller and set a object in request so that the forwarded controller can use it in #RequestBody.
Following is the exact scenario:
Twilio calls a controller method with data sent by client as following:
#RequestMapping(value = "/sms", method = RequestMethod.POST)
public String receiveSms(#RequestParam("Twiml") String twiml,
HttpServletRequest request,
HttpServletResponse response) {
//TODO - Create new instance of Activity and populate it with data sent from client
return "forward:/activity/new";
}
Now, I want to forward this request to ActivityController which already handles the request from web/rest clients.
ActivityController.java has a method with following signature:
#RequestMapping(value = "/activity/new", method = RequestMethod.POST)
public ResponseEntity<Activity> updateLocation(
#RequestBody Activity activity) {
}
Is it possible? If yes, how?
Thanks,

Create the object and add it to the request as an attribute in the first controller,
request.setAttribute("object",new OwnObject()),
return "forward:/activity/new";
In the updateLocation Method retrieve that object from the request
#RequestMapping(value = "/activity/new", method = RequestMethod.POST)
public ResponseEntity<Activity> updateLocation(
#RequestBody Activity activity, HttpServletRequest request) {
OwnObject o = (OwnObject) request.getAttribute("object");
}

Related

How to send JSON response from controller?

I want to pass a boolean value from my controller to javascript using json but couldnot find a way as I am new to spring mvc.
While using servlet we wrote:
response.getWriter().println(somevalue)
and the somevalue can be received using ajax.
Here my controller method is:
#RequestMapping(value = REGISTERACTION , method = RequestMethod.POST)
#ResponseBody
public boolean RegisterUser(#ModelAttribute("register") Register register,HttpServletRequest request, HttpServletResponse response)
{
boolean Registrationsuccess = userService.RegisterUser(register);
return Registrationsuccess;
}
So, here the boolean variable is Registrationsuccess which I want to send to js file and receive it using ajax.
And in my javascipt function which is called using onsubmit event-->
function AccountExists()
{
$.ajax({
type: 'POST',
url: 'registerProcess',
success: function(data){
let detail = JSON.parse(data);
if( data == true)
alert("Success");
else
alert("Not ");
}
});
}
Getting error --
The target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request, and the server is unwilling to supply a default representation.
You need to use ResponseEntity and #RestController for JSON Response.
Note : #RestController includes both annotations #Controller and #ResponseBody.
Try with this :
#RestController
#RequestMapping("controller")
public class Controller {
#PostMapping("REGISTERACTION")
public ResponseEntity<Boolean> RegisterUser(#ModelAttribute("register") Register register)
{
Boolean registrationSuccess = userService.RegisterUser(register);
return new ResponseEntity<Boolean>(registrationSuccess , HttpStatus.OK);
}
}
Try to use #ResponseBody annotation in your controller's method. And change the return type of the method to Boolean, then return Registrationsuccess instead of ModelAndView.
You can achieve this using 2 approach
Approach 1: Set model attribute and using expression language you can find on jsp
model.addAttribute("test",true);
in Jsp page
${test}
Approach 2: If you are sending ajax request instead of ModelAndView create a object
set any attribute boolean and return object from method #ResponseBody annotation you will get json in Ajax Response
#RequestMapping(value = REGISTERACTION , method = RequestMethod.POST)
public #ResponseBody MyCustomObject RegisterUser(#ModelAttribute("register") Register register,HttpServletRequest request, HttpServletResponse response)
{
boolean Registrationsuccess = userService.RegisterUser(register);
MyCustomObject cusobj=new MyCustomObject();
cusobj.setStatus(true);
return cusobj;
}
Whatever code you have written it will not return json(It is basically form submission approach) so you have to go with first approach.

Spring MVC - Stop redirect in Controller function

I have a Spring MVC Controller and a PUT mapping that consumes JSON. I receive the JSON and everything just fine, the problem is whenever I fire off the JSON the mapper wants to redirect to the URL, giving me error 500 because the server can't find any template for the URL. How can I stop Spring MVC from trying to redirect to the URL and just receive the JSON?
My relevant Controller code :
#RequestMapping(value = "admin/users/VMs", method = RequestMethod.PUT, consumes = "application/json")
public void removeVM(#RequestBody ManageVMRequest packet, Authentication authentication) {
System.out.println(packet.getVm());
System.out.println(packet.getUser_id());
}
You can try to return ResponseEntity<Void>
#RequestMapping(value = "admin/users/VMs", method = RequestMethod.PUT, consumes = "application/json")
public #ResponseBody ResponseEntity<Void> removeVM(#RequestBody ManageVMRequest packet, Authentication authentication) {
System.out.println(packet.getVm());
System.out.println(packet.getUser_id());
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
}

Redirect POST request with additional form data in Spring

I am developing a container app for my Angular frontend in Spring. I have a mock payment gateway, which I am submitting a Angular form using POST method.
#RequestMapping(path = "/pay", method = RequestMethod.POST)
public String handleMockPayment(HttpServletRequest request, HttpServletResponse response) {
// APPEND MOCK PAYMENT STATUS CODE HERE (ResponseCode)
// something like,
// response.setParameter("ResponseCode", "1");
request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT); // to allow redirecting POST requests
return "redirect:/confirm";
}
In this mock controller, I need to append an additional data field to the original data received (which is the form submitted from Angular app). This data field is the mock payment success/failure code. This controller will then redirect to another controller, which is the real controller I am going to use to handle callback request from the payment server.
#RequestMapping(path = "/confirm", method = RequestMethod.POST)
public String paymentVerification(HttpServletRequest request, HttpServletResponse response) {
String orderId = request.getParameter("OrderID");
String responseCode = request.getParameter("ResponseCode"); // this is null
// do some stuff with orderId and responseCode
// ...
return "redirect:/booking";
}
The orderId is available as it was set from the initial form submission. But all the methods I tried (using Model, FlashParams, ... ), did not work (responseCode was null all the time).
How can I append this new parameter here?
Any alternative method to mock payment gateway is also appreciated. My goal is to either append a response code to the existing form data, or create a new form within the mock controller (handleMockPayment) with necessary mock attributes. Thanks in advance.
you can use RedirectView to achieve this.
#RequestMapping(value = "test/{id}")
public RedirectView handleMockPayment (HttpServletRequest request, HttpServletResponse response) {
...
RedirectView rv = new RedirectView();
rv.setContextRelative(true);
rv.setUrl("/confirm/{responseCode}");
return rv;
}
you can access same in /confirm using path variable.

spring rest app, can't get data from PUT

I have two methods in controller, this is handler request from client. I can't get request body of PUT. For send request i use Advanced Rest Client in Chrome.
#RequestMapping(value = "/addPupil", method = RequestMethod.POST)
public void addPupil(Pupil pupil){
System.out.println(pupil.toString());
}
Result in Advanced Rest Client:
Status 200 OK Response does not contain any data.
stdout:
Pupil{address='is address', level='is level', group='is group', last='is last', name='is name'}
But problem with this method, i can't get pupil object!
#RequestMapping(value = "/changePupil/{id}", method = RequestMethod.PUT)
public void changePupil(#PathVariable("id") Long id, Pupil pupil){
System.out.println("id: "+id);
System.out.println(pupil.toString());
}
Result in Advanced Rest Client:
Status 200 OK Response does not contain any data.
stdout:
id: 2
Pupil{address='null', level='null', group='null', last='null', name='null'}
you should use #RequestBody
#RequestMapping(value = "/changePupil/{id}", method = RequestMethod.PUT)
public void changePupil(#PathVariable("id") Long id,#RequestBody Pupil pupil){
System.out.println("id: "+id);
System.out.println(pupil.toString());
}
Take an advantage of #RestController on your controller class instead of #Controller and specify the MediaType that your rest method consuming and you may have to register appropriate HttpMessageConverter too.
Ref: How to configure MappingJacksonHttpMessageConverter while using spring annotation-based configuration?

How to get the HTTP Request body content in a Spring Boot Filter?

I want to get the raw content that is posted towards a RestController. I need it to do some processing on the raw input.
How can I get the raw body content without interfering with the Filter Chain?
Here is a sample of controllerAdvice where you can access RequestBody and RequestHeader as you do in your controller. The Model attribute method is basically to add model attributes which are used across all pages or controller flow. It gets invoked before the controller methods kick in. It provides cleaner way of accessing the RESTful features rather than convoluted way.
#ControllerAdvice(annotations = RestController.class)
public class ControllerAdvisor {
#ModelAttribute
public void addAttributes(HttpServletRequest request, HttpServletResponse response,Model model, #RequestBody String requestString, #RequestHeader(value = "User-Agent") String userAgent) {
// do whatever you want to do on the request body and header.
// with request object you can get the request method and request path etc.
System.out.println("requestString" + requestString);
System.out.println("userAgent" + userAgent);
model.addAttribute("attr1", "value1");
model.addAttribute("attr2", "value2");
}
}
I use #ModelAttribute method to set value from #RequestBody.
#ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler
{
public CustomRestExceptionHandler() {
super();
}
private Object request;
#ModelAttribute
public void setRequest(#RequestBody Object request) {
this.request = request;
}
#Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
logger.info(this.request)
}
}

Resources