I had an old application with Java and Struts.
I do some refactoring and recode this application with SpringBoot.
But I have a problem handling the redirection between application and some external url, keeping my session attribute values.
To simplify, I have two endpoints, one in post, one in get.
First, the POST endpoint is called :
#RequestMapping(value = "/Action.do", method = RequestMethod.POST)
public String saveConfigurationPost(HttpServletRequest request){
logger.info("Set session param");
request.getSession().setAttribute("someAttribute", "value");
return "redirect:http://external-url.fr#redirectUri=internal-server/Action.do"
}
The external website do some treatment, and redirect me back to my application with a get request on the specified uri Action.do
#RequestMapping(value = "/Action.do", method = RequestMethod.GET)
public String saveConfigurationGet(HttpServletRequest request){
String myParamValue = (String) request.getSession().getAttribute("someAttribute");
logger.info("Get session param : "+myParamValue); // Return null
....
return "success"
}
But after redirect me to the GET endpoint, I always have a null value for my session attribute.
Why ?
With my old application, I used new ActionForward(forwardUrl, true) to redirect.
How could I get the same thing, simple as possible ?
Related
I have two spring controller methods :
#RequestMapping(value="/requestotp",method = RequestMethod.POST,params = "!applicationId") //new customer
public OTPResponseDTO requestOTP( #RequestBody CustomerDTO customerDTO){
return customerService.requestOTP(customerDTO);
}
#RequestMapping(value="/requestotp",method = RequestMethod.POST,params = {"idNumber","applicationId"}) //existing customer
public String requestOTP( #RequestParam(value="idNumber") String idNumber , #RequestParam(value="applicationId") String applicationId) {
return customerService.requestOTP(idNumber, applicationId);
}
using "!applicationId" , I am expecting that when I call the url with applicationId parameter there that the second method will be called , but actually when I pass a request like this :
{"idNumber":"345","applicationId":"64536"}
The first method gets called
This is the part of the params paremeters documentation that I rely on :
Finally, "!myParam" style expressions indicate that the specified
parameter is not supposed to be present in the request.
Can't you just simply delete first request params?
#RequestMapping(value="/requestotp",method = RequestMethod.POST) //new customer
public OTPResponseDTO requestOTP( #RequestBody CustomerDTO customerDTO){
return customerService.requestOTP(customerDTO);
}
The issue actually wasn't with negating the parameter, the issue was that I was sending {"idNumber":"345","applicationId":"64536"} in the POST body and I was expecting the variables to be mapped to the method parameters annotated with #RequestParam ... this is not correct ... #RequestParam only map URL parameters .... so the controller was trying to find the best match so it was using the first method as it contained #RequestBody
I'm using Spring 3.2.8. I get a mapping from a URL p to a URL q from an external API. The mapping changes at runtime. I want to redirect (302) the URL before the controller request mappings are called. How can I do that?
Thanks!
I have a solution. A default controller mapping for every RequestMethod.GET request is called if the requested URL does not exist. You have also to load static content (images, css, js, …) by your servlet container without touching Spring.
#Controller
public class DynamicURIForwardController {
#RequestMapping(method = RequestMethod.GET)
public String forward(final HttpServletRequest request) {
final String requestURI = request.getRequestURI();
// Stuff comes here.
// final String forwardURI = ...
return "forward:" + forwardURI;
}
}
Now I have a login code like this,UserInfo is a form with username and password
#RequestMapping(value = "/login/loginCheck", method = RequestMethod.POST)
public Map<String, Object> loginCheck(UserInfo userInfo)
#RequestMapping(value = "/login/PageA", method = RequestMethod.POST)
public Map<String, Object> PageA(){
//maybe check the session
//if session expired ,then redirect to login page
}
After login, I should redirect page to Page A, and record the username in session, So in spring framework, Do I just configure it or get Session from request ?
Hope to be clear.
There are many ways, one is to simply inject HttpSession into your handler method
#RequestMapping(value = "/login/PageA", method = RequestMethod.POST)
public Map<String, Object> PageA(HttpSession httpSession){
//maybe check the session
//if session expired ,then redirect to login page
}
The getAttribute method of HttpSession will throw IllegalStateException if session is no longer valid, but I have a feeling Spring MVC will create a new session for you when that happen, so also check for non-existence (null value)
Also have a look at the usage of #SessionAttributes and #ModelAttribute annotation on Spring doc, and Spring Security framework
I build my web application based on Spring MVC and come across a problem whilst trying to add a cookie in a method handling an ajax request.
I realized that method with #ResponseBody (in my example it returns a string value) does not create a "real" response and added cookies are lost.
Is there any way to add a cookie in a method called via ajax (and therefore annotated with #ResponseBody) in Spring MVC?
You can use the following signature to do this
#ResponseBody
public String x((HttpServletRequest request, HttpServletResponse response){
Cookie userCookie = new Cookie("<name>", "<valie>");
//set other cookie properties
response.addCookie(userCookie);
return "xxx";
}
My applications redirects after POST operation some information to the GET controller but lose the information when using with Apache and reverse proxy. When I do this operation without the reverse proxy in the middle everything works fine. Some ideas?
#PreAuthorize("hasRole('ROLE_ADMIN')")
#RequestMapping(value = "aCategory", method = RequestMethod.POST)
public String category(#RequestParam("aCategoryName") String name, Model model, RedirectAttributes attr,
HttpServletRequest request) {
String redirect = "redirect:" + "http://localhost:8080/aCategory";
aService.saveACategory(name);
attr.addFlashAttribute("aCategoryName", name);
return redirect;
}
#RequestMapping(value = "aCategory", method = RequestMethod.GET, produces = "text/html")
public String appCategory(Model model, Principal principal) {
String name = principal.getName(); // get logged in username
model.addAttribute("username", name);
return "aCategory";
}
It depends on your cluster configuration and session replication configuration. Because FlashAttributes are first stored in a session temporarily before adding it to the model map to display it on the redirected view. So if your cluster is not well configured for proper session replication then your FlashAttribute might be lost when request is served by another cluster than where the FlashAttribute is actually stored in session.
For further details you can refer my question.
Hope this helps you. Cheers.