Spring MVC Flash Attributes - java

How do I enhance the Controller below to utilize Spring MVC's Flash Attributes? The use case is a copy function.
POST/REQUEST/GET implementation:
client clicks "copy" button in the UI
server sets the response "Location" header
client redirects to "path/to/page?copy"
server provides ModelAndView
client (jQuery success function) sets window.location
FooController redirect method:
#RequestMapping(value = "{fooId}", method = POST, params = { "copy" })
#Transactional
#ResponseStatus(CREATED)
public void getCopyfoo(#PathVariable String fooId,
HttpServletResponse response, RedirectAttributes redirectAttrs) {
response.setHeader("Location", uriPath);
//no worky?!:
redirectAttrs.addFlashAttribute("barKey", "barValue");
}
FooController get method:
#RequestMapping(value = "{fooId}", method = GET)
#Transactional(readOnly = true)
public ModelAndView findFooById(#PathVariable String fooId,
HttpServletRequest request){
Map<String, ?> map = RequestContextUtils.getInputFlashMap(request);
// map is empty...
return modelAndViewFromHelperMethod();
}

I'm affraid that RedirectAttributes work only with RedirectView,
so Your controller should return for example:
1. String: "redirect:/[uriPath]"
2. new RedirectView([uriPath])
If you realy need to handle server response with JS, then maybe handling HTTP status 302 would help.

Related

How to retrieve value of parameters annotated by #RequestBody from a HttpServeletRequest object?

in a springcloud project
if a backend microservice has the following:
#RequestMapping("/test")
pubilc void test(#RequestBody MyPram myParam){
...
}
how can I retrive the "myParam" value in a zuul filter?
in other words, since I can have the following code segment in a zuul filter
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
how can I retrive the "myParam" value from a request?
i don't know in Spring Cloud but tried in springMVC (spring version 3) we can get the Request body HttpServeletRequest object or method.
#RequestMapping(value="/employee/{id}")
public #ResponseBody String demo(HttpServletRequest request, #PathVariable("id") Integer id) {
if (request.getMethod().equalsIgnoreCase("POST")) {
return "POST MEhod";
} else if (request.getMethod().equalsIgnoreCase("GET")) {
return "GET Method";
}
}
Its not exact what you are looking but it will give you hint to solve your problem

on submitting request control is always picking up GET method and not POST

I am trying this using spring3 hibernate3 and tiles2.
#RequestMapping(value = "/capturedetails", method = RequestMethod.GET)
public String getcapturedetails(Model model, HttpSession session,
HttpServletRequest request) {
Customer customer=new Customer();
model.addAttribute("customer", customer);
return "capturedetails";
}
#RequestMapping(value = "/capturedetails", method = RequestMethod.POST)
public String addcustomer(
#ModelAttribute("Customer") Customer customer, Model model,
HttpSession session, HttpServletRequest request) {
custBarcodeService.saveCustomer(customer);
model.addAttribute("customer ", new Customer());
return "capturedetails";
}
Upon submitting request control it always picking up GET method and not POST...
How can I fix this?
I had faced similar issue in the past. In my case I was trying to make a POST request from postman with a json body to an endpoint which was receiving the data in x-www-form-urlencoded format on the controller side.
Note that if you are using #ModelAttribute in your post controller method, it receives the data in x-www-form-urlencoded format. If this case, then possible solutions would be
make the post request method receive json data by using #RequestBody:
#RequestMapping(value = "/capturedetails", method = RequestMethod.POST)
public String addcustomer(#RequestBody Customer customer, Model model,
HttpSession session, HttpServletRequest request) {
custBarcodeService.saveCustomer(customer);
model.addAttribute("customer ", new Customer());
return "capturedetails";
}
Send data in x-www-form-urlencode format from rest client
I think you might have multiple form-element open...Check your tiles layout files and remove the multiple form elements and then try to post.
Because the same solution solved my problem as well.

Spring MVC and redirect on POST sends destination file on URL

I have a very weird problem in my Spring MVC application. I am writing a login form and POSTing the data via AJAX into a Spring MVC controller that looks like this:
#Controller
public class LoginResourceController {
private static final Logger log = Logger.getLogger (LoginResourceController.class.getName());
#RequestMapping (value="/login", method = RequestMethod.POST)
public String checkAccount (HttpServletRequest httpRequest, HttpServletResponse httpResponse,
#RequestHeader (value = "User-Agent") String retrievedUserAgent,
#RequestParam("username") String username,
#RequestParam("password") String password,
#RequestParam("rememberMe") String rememberMe)
{
//Check username and password in DB, and then if OK,
return "redirect:/login/redirectToMain";
}
#RequestMapping (value = "/login/redirectToMainpage", method = RequestMethod.GET)
public String redirectControllerToMainPage (HttpServletRequest httpRequest, HttpServletResponse httpResponse)
{
return "mainPage";
}
Now, the problem is, I have the client (browser) upon redirect requesting a URL that contains the entire contents of mainPage.jsp in the URL. So it looks like:
https://localhost:8443/<!DOCTYPE html><html><head><meta charset=utf-8 /><title>Page that the subscriber sees after login</title>....
I am quite confounded by this error. Is this some servlet setting in WEB-INF/web.xml or mvc-dispatcher-servlet.xml that I need to change? I am using Spring 3.0.5.
BTW, my redirect works flawlessly for GET method controllers in the same Spring MVC application. (e.g., when I re-load the main page of my application, the redirect to the logged in mainPage.jsp above works flawlessly). Moreover, other GET methods on other jsps work correctly too (example, redirect to /login page via login.jsp via a GET of https://localhost:8443/.
I have checked the following and they didn't help: 1 2.
Try not to put the redirect in the return of the controller. This seems to either cause the full page to be rendered as the ajax response, or a redirect header is filled in with an url with the full contents of the page as a string in the response body.
As a first approach, try to make the request a normal HTTP request instead of ajax, and it should just work.
Alternativelly try to make the return body empty, and return an HTTP status code to the client. Either 200 OKif the account is OK or 401 Unauthorized:
#RequestMapping (value="/login", method = RequestMethod.POST)
public ResponseEntity checkAccount (HttpServletRequest httpRequest, HttpServletResponse httpResponse,
#RequestHeader (value = "User-Agent") String retrievedUserAgent,
#RequestParam("username") String username,
#RequestParam("password") String password,
#RequestParam("rememberMe") String rememberMe)
{
//Check username and password in DB
....
HttpStatus returnCode = null;
if(usernameAndPasswordOK) {
returnCode = HttpStatus.OK;
}
else {
returnCode = HttpStatus.UNAUTHORIZED;
}
return new ResponseEntity(returnCode);
}
And then on the client redirect with Javascript accordingly.
This was a little tricky for me to figure out, and being a web development noob doesn't help here. Anyway, #jhadesdev's answer above pointed me to the issue.
On my client, I do this:
$("#loginForm").submit(function(evt)
{
evt.preventDefault();
if (loginFormInputIsValid ())
{
$.ajax ({
type: "POST",
url: "/login",
data: $(this).serialize(),
success: function (response)
{
window.location = response;
}
});
}
}
which was the issue--you see, setting the window.location=response; caused the client (browser) to request the server for the funky URL above. I have to change my client call (this is where #jhadesdev's response helped) to make sure I don't do something so wrong.
Thanks for your time, #jhadesdev.

When the validator finds form errors, the form page is redisplayed at the POST url

An item is displayed at this URL:
/item/10101
using this Controller method:
#RequestMapping(value = "/item/{itemId}", method = RequestMethod.GET)
public final String item(HttpServletRequest request, ModelMap model,
#PathVariable long itemId)
{
model = this.fillModel(itemId);
return "item";
}
The page contains a form that submits to the following method in the same controller:
#RequestMapping(value = "/process_form", method = RequestMethod.POST)
public final String processForm(HttpServletRequest request,
#ModelAttribute("foo") FooModel fooModel,
BindingResult bindResult,
ModelMap model)
{
FooModelValidator validator = new FooModelValidator();
validator.validate(FooModel, bindResult);
if (bindResult.hasErrors())
{
model = this.fillModel(fooModel.getItemId());
return "item";
}
return "account";
}
If the validator finds errors in the form, it redisplays the item but instead of displaying it at the original url:
/item/10101
it displays it at its own url:
/process_form
Is it possible to redisplay the form at the original URL?
/item/10101
(I've tried getting the referrer and redirecting to it in processForm but then all of the model contents end up displayed as URL name/value pairs:)
#RequestMapping(value = "/process_form", method = RequestMethod.POST)
public final String processForm(HttpServletRequest request,
#ModelAttribute("foo") FooModel fooModel,
BindingResult bindResult,
ModelMap model)
{
String referrer = request.getHeader("referer");
FooModelValidator validator = new FooModelValidator();
validator.validate(FooModel, bindResult);
if (bindResult.hasErrors())
{
model = this.fillModel(fooModel.getItemId());
return "redirect:" + referrer;
}
return "account";
}
Short answer: No.
What happens is a server-side redirect (forward), which is within the same request, and so the submitted values are preserved (and displayed in the form)
The url will change if you use a client-side redirect (return "redirect:item";), but in that case a new request will come and the submitted values will be lost.
But here are two options that you have:
use the same URL in the mappings for both methods and distinguish them based on request method - GET for the former, POST for the latter. This might be confusing, so document it.
find / implement flash scope for spring-mvc. There's nothing built-in. The flash scope means that values are preserved (in the session usually) for a submit and the subsequent redirect. This option includes the manual handling, by putting the submitted object in the session, and later retrieving & removing it

Insert info into an HTTP header

I’m trying to add some data to the http header that comes back from a RESTful web service call. Is it possible to use JAX-RS or something else to add data to the response header?
Example of my method:
#GET
#Path("getAssets")
public List<Asset> getAssets(#QueryParam("page") #DefaultValue("1") String page,
#QueryParam("page_size") #DefaultValue(UNLIMITED) String pageSize) throws Exception
{
stuff…
}
Thanks for your help.
Using something such as Spring's MVC controller, you can easily get and set response headers as in the below example. A list of common headers can be found here Wikipedia - Common Headers
...
#RequestMapping(method = RequestMethod.GET)
public String myGetMethod(#PathVariable string owner, #PathVariable string pet, HttpServletResponse response) {
response.setContentType("text/html");
response.setHeader("Content-disposition","Content-Disposition:attachment;filename=fufu.png");
}
...

Categories

Resources