After pressing back button session doesnot destroy - java

am facing a strange issue.
my logout code is as :
#RequestMapping(value = "/logout", method = RequestMethod.GET)
public String thanks(HttpSession session) {
session.removeAttribute("parentEmail");
session.invalidate();
return "redirect:parent-login";
}
but after logout i get link as /logout?email=xyz#xyz.com
so when i press back button am again on last accessed page and can update the data.
email I have set as session attribute.
Can anybody tell me why am getting this URL.

By default all model attributes are considered to be exposed as URI
template variables in the redirect URL. Of the remaining attributes
those that are primitive types or collections/arrays of primitive
types are automatically appended as query parameters.
use redirectAttributes.addAttribute() to append required query parameters.
You should also invalidate any authentication related object from ModelMap by setting that object null
model.addAttribute("parentLogin",null);
So your method should look like:
#RequestMapping(value = "/logout", method = RequestMethod.GET)
public String thanks(Model model,RedirectAttributes redirectAttributes,HttpSession session) {
redirectAttributes.addAttribute("logout", "1234");
model.addAttribute("parentLogin",null);
session.removeAttribute("parentEmail");
session.invalidate();
return "redirect:parent-login";
}

Related

Spring MVC ModelAttribute values being lost

I'm running into a situation where my model attribute is losing values between pages.
I've got two controller methods that handle GET and POST requests respectively.
GET Method
#RequestMapping(value = "/checkout/billing", method = RequestMethod.GET)
public String getBillingPage(Model model, final HttpServletRequest request) throws CMSItemNotFoundException {
// other code
checkoutForm.setCustomFieldsForm(customFieldsForm);
model.addAttribute("checkoutForm", checkoutForm);
// other code
}
Debug View After GET Method completes
POST Method
#RequestMapping(value = "/checkout/billing", method = RequestMethod.POST)
public String submitPayment(
#Valid #ModelAttribute("checkoutForm") final CheckoutForm checkoutForm,
final BindingResult bindingResult,
Model model,
final HttpServletRequest request,
final HttpServletResponse response) throws CMSItemNotFoundException
{}
Debug View When POST Method is Invoked
The 1234 comes from the user entering that data in the form field. The other values should still be there and not null though.
What could be happening here?
Your model is not stored in the session. Each request creates a new model object. That's why it's empty.
You can add your model as a session attribute. Please find the documentation here https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-sessionattrib

Get #RequestMapping value of different method in same controller

Using Spring Boot, I have a couple methods in my RegisterController which handles new user registration.
The createNewUser method is responsible for saving the new user to the database and sending a confirmation e-mail containing a link that has a unique token.
The confirmUser method handles processing the GET request for the confirmation link.
Is there a way for the createNewUser method to get the #RequestMapping value assigned to confirmUser? I'd like to use this value to generate the confirmation link instead of hard coding it.
// Process form input data
#RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView createNewUser(#Valid User user, BindingResult bindingResult) {
}
// Process confirmation link
// Link in confirmation e-mail will be /registerConfirmation?token=UUID
#RequestMapping(value="/registerConfirmation", method = RequestMethod.GET)
public ModelAndView confirmUser( #RequestParam("token") String token) {
}
I don't know of a way to get it from the #RequestMapping value but you have a couple of different options.
Option 1: Create a constant for the mapping and use that which allows you to reference it in both methods.
private final static String REGISTER_CONF_VAL = "/registerConfirmation";
#RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView createNewUser(#Valid User user, BindingResult bindingResult) {
}
// Process confirmation link
// Link in confirmation e-mail will be /registerConfirmation?token=UUID
#RequestMapping(value=REGISTER_CONF_VAL, method = RequestMethod.GET)
public ModelAndView confirmUser( #RequestParam("token") String token) {
}
Option 2: Less ideal, but if you add registerConfirmation to your config file, you can access it like:
#RequestMapping(value="${register.conf.val}", method = RequestMethod.GET)
public ModelAndView confirmUser( #RequestParam("token") String token) {
}
The reason this isn't ideal is because you probably don't want it to be different from environment to environment. That said, it would work.
If you need to generate the link based on user request, you can use the Path Variable in the controller. U can get the path variable and use some mechanism to validate the path as well.
Replace registerConfirmation with {registerConfirmation} and in the method, use #PathVariable annotation to get the path. Use the variable to check if the path is valid.

Setting Cookie not working in Spring web-mvc 4

I need to set a cookie with redirect in my login controller. I used code below to set cookie.
#RequestMapping("/fbresponse")
public String getToken(#RequestParam(required = false, value = "code") String code, HttpServletResponse sResponse) {
sResponse.addCookie(new Cookie("logged", "123"));
return "redirect:"+user.getLastPage();
}
In my index I try to retrive the cookie using following code:
#RequestMapping("/")
public String getIndex(#CookieValue(value="logged", required=false)String test){
user.setLastPage("/");
loginCheck();
System.out.println(test);
return "index";
}
But it always returns null. I tried returning new ModelAndView. It also did not work and since I need some components in model it does not suit my requirement.
How can set and retrieve a cookie? Is it possible to do it with redirect?
UPDATE
I have class level #RequestMapping in my login controller.
#Controller
#RequestMapping("/login")
public class LoginController {
#RequestMapping("/fbresponse")
public String getToken(#RequestParam(required = false, value = "code") String code, HttpServletResponse sResponse) {
sResponse.addCookie(new Cookie("logged", "123"));
return "redirect:"+user.getLastPage();
}
}
When I remove the class level request mapping add cookies works. How can I add a cookie correctly with class level request mapping?
You need to set the path of the cookie, otherwise it's valid only for the current path.

What is the difference between #ModelAttribute, model.addAttribute in spring?

i am new Spring learner.i'm really confused about what is the difference between two concept:
#ModelAttribute
model.addAttribute
in below there are two "user" value.Are these same thing?Why should I use like this?
Thank you all
#RequestMapping(method = RequestMethod.GET)
public String setupForm(ModelMap model) {
model.addAttribute("user", new User());
return "editUser";
}
#RequestMapping(method = RequestMethod.POST)
public String processSubmit( #ModelAttribute("user") User user, BindingResult result, SessionStatus status) {
userStorageDao.save(user);
status.setComplete();
return "redirect:users.htm";
}
When used on an argument, #ModelAttribute behaves as follows:
An #ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model, the argument should be instantiated first and then added to the model. Once present in the model, the argument’s fields should be populated from all request parameters that have matching names. This is known as data binding in Spring MVC, a very useful mechanism that saves you from having to parse each form field individually.
http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#mvc-ann-modelattrib-method-args
That's a very powerful feature. In your example, the User object is populated from the POST request automatically by Spring.
The first method, however, simply creates an instance of Userand adds it to the Model. It could be written like that to benefit from #ModelAttribute:
#RequestMapping(method = RequestMethod.GET)
public String setupForm(#ModelAttribute User user) {
// user.set...
return "editUser";
}

Spring MVC 3.1 - RedirectAttributes not part of model after redirect

I'm looking to develop a Spring MVC application that incorporates the POST/Redirect/GET pattern and input validation. In the POST phase, I execute a Validator and get back a BindingResult/Errors collection. If there are errors, I'd like to redirect back to the form with my validation errors in tact. I want this to be a redirect that resolves as a GET request as to avoid expired caches and form resubmission prompts when using the browser's navigation buttons (back, forward, refresh).
This is how I'm handling the initial form display and is where I want to redirect the user back to if there are validation errors.
#RequestMapping("/account/list")
public String listAccounts(HttpServletRequest request, Map<String, Object> map) {
log.debug("start of list accounts");
map.put("accountList", entityService.listAccounts());
map.put("account", new Account());
map.put("accountTypeValues", AccountTypes.values());
// Map<String, ?> inputFlashMap = RequestContextUtils.getInputFlashMap(request);
// if (inputFlashMap != null) {
// map.putAll(inputFlashMap);
// }
return "account";
}
This is a snippet of the method that processes the POST:
#RequestMapping(value = "/account/add", method = RequestMethod.POST)
public String addAccount(#ModelAttribute("account") #Valid Account account, BindingResult result, RedirectAttributes redirectAttributes, HttpServletRequest request, Map<String, Object> model) {
accountValidator.validate(account, result);
if (result.hasErrors()) {
redirectAttributes.addFlashAttribute("account", account);
redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX + "account", result);
return "redirect:/account/list";
}
I can see the FlashMap in the HttpServletRequest object at the end of the addAccount method and again after the redirect in the listAccounts method. However, that map is never merged with the Model in listAccounts. If I uncomment the inputFlashMap bit in listAccounts, then I get the desired results.
Why aren't the RedirectAttributes (aka FlashMap) merged into the Model after the redirect?
The method listAccounts needs #ModelAttribute("account") Account account in the params like addAccount
You do not need to worry about caching POST requests. Because POST requests should not been chached at all.
So it it valid to return the input form in response of an invalid POST request.
I think you can achieve the desired behavor by adding
#SessionAttributes("account")
to your controller instead of using flash scope. However, in this case you need to take care about removing attribute from the session when needed.

Categories