How to redirect from spring ajax controller? - spring

I have a controller with #ResponseBody annotation. What I want to do is if this user doesn't exists process user's Id and return a json object. If exists redirect to user page with userInfo. Below code gives ajax error. Is there any way to redirect to user page with userInfo?
#RequestMapping(value = "/user/userInfo", method = {RequestMethod.GET})
#ResponseBody
public String getUserInfo(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
if(...){
.....//ajax return
}else{
modelMap.addAttribute("userInfo", userInfoFromDB);
return "user/user.jsp";
}
}

Well, this method is annotated with #ResponseBody. That means that the String return value will be the body of the response. So here you are just returning "user/user.jsp" to caller.
As you have full access to the response, you can always explicitely do a redirect with response.sendRedirect(...);. It is even possible to explicitely ask Spring to pass userInfoFromDB as a RedirectAttribute through the flash. You can see more details on that in this other answer from me (this latter is for an interceptor, but can be used the same from a controller). You would have to return null to tell spring that the controller code have fully processed the response. Here it will be:
...
}else{
Map<String, Object> flash = RequestContextUtils.getOutputFlashMap(request);
flash.put("userInfo", userInfoFromDB);
response.redirect(request.getContextPath() + "/user/user.jsp");
return null;
}
...
The problem is that the client side expects a string response that will not arrive and must be prepared to that. If it is not, you will get an error client side. The alternative would then be not to redirect but pass a special string containing the next URL:
...
}else{
Map<String, Object> flash = RequestContextUtils.getOutputFlashMap(request);
flash.put("userInfo", userInfoFromDB); // prepare the redirect attribute
return "SPECIAL_STRING_FOR_REDIRECT:" + request.getContextPath() + "/user/user.jsp");
}
and let the javascript client code to process that response and ask for the next page.

Related

RedirectAttributes in Spring MVC 3.2.8

I have a project based in Spring Web model-view-controller (MVC) framework. The version of the Spring Web model-view-controller (MVC) framework is 3.2.8.
I have this method
#RequestMapping(value = { "/newdesign/manage/device/award",
"/newdesign/manage/device/award/"}, method = {RequestMethod.POST})
public String awardDeviceProduct(
#ModelAttribute("deviceForm") DeviceForm deviceForm,
HttpServletRequest request,
Model model,
final RedirectAttributes redirectAttributes) throws Exception {
checkUser (request, UserRole.MARKETING);
Device device = manageLicenseService.getDeviceById(deviceForm.getDevice().getId());
if (deviceForm.getDevice().getIos()==null) {
model.addAttribute ("errorMessage", "Licence Number cannot be null !");
redirectAttributes.addFlashAttribute("errorMessage", "Licence Number cannot be null !");
} else if (deviceForm.getSelectedItems()!=null &&
!deviceForm.getSelectedItems().isEmpty()) {
// check LICENCE DUPLICATED
manageLicenseService.applyStatusChange (device, deviceForm.getSelectedItems(), Status.AWARDED );
} else {
model.addAttribute ("errorMessage", "no Items selected !");
model.addAttribute ("productGroup", getNotExpiredProductGroups (request));
}
return "redirect:/newdesign/manage/device/" + deviceForm.getDevice().getId();
}
But in the JSP I can't find the attribute "errorMessage" !!!! when (deviceForm.getDevice().getIos()==null)
The problem with your code relies in the difference between "redirect" and "forward".
If you return with a redirect statement, the response will first return to the browser, and then it will request the new url. The problem with this approach is, that the redirected new request will have a completely new context, and will not have access to the Model, set in your previous response.
The forward response however is processed by the server side itself, transferring the request to the new URL. It is faster and the context can be maintained.
You can find more details here

HttpHeaders and status value

I have a spring boot application. I use a rest architecture.
I have this method.
#RequestMapping(value = "/members/card/{cardId}", method = RequestMethod.HEAD)
public ResponseEntity hasCardIdValid(#PathVariable(value = "cardId") String cardId) {
return memberService.hasCardIdValid(cardId) ? new ResponseEntity(HttpStatus.OK) : new ResponseEntity(HttpStatus.NOT_FOUND);
}
I another application, I would like to call hasCardIdValid method.
I wrote this code
HttpHeaders response = restTemplate.headForHeaders("/rest/members/card/{cardId}", cardId);
I don't find a way to get the 200 or 404 value from response. I don't see any method for that.
Is it possible?
This is because you are getting back HttpHeaders as a result of your restTemplate#headForHeaders() method call.
If you want to get hold of the status you'll have to invoke one of the RestTemplate#exchange() methods instead (there are a few overloaded method signatures) that is giving you back a ResponseEntity on which you can invoke getStatus().

How exactly Spring MVC handle cookie?

I am studying how Spring handle cookie on a tutorial and I have some doubts.
In this example there is this CookieControllerExample that perform some cookie operation when are performed.
#Controller
public class CookieControllerExample {
#RequestMapping(value = "/readcookie", method=RequestMethod.GET)
public ModelAndView readCookie(#CookieValue(value = "URL") String URL, HttpServletRequest request,
HttpServletResponse response) {
System.out.println("CookieControllerExample readcookie is called");
return new ModelAndView("/cookie/cookieView", "cookieValue", URL);
}
#RequestMapping(value = "/writecookie", method=RequestMethod.GET)
public String writeCookie(HttpServletRequest request,
HttpServletResponse response) {
System.out.println("CookieControllerExample writeCookie is called");
Cookie cookie = new Cookie("URL", request.getRequestURL().toString());
response.addCookie(cookie);
return "/cookie/cookieView";
}
#RequestMapping(value = "/readAllCookies", method=RequestMethod.GET)
public ModelAndView readAllCookies(HttpServletRequest request) {
System.out.println("CookieControllerExample readAllCookies is called");
Cookie[] cookies = request.getCookies();
System.out.println("All Cookies in your browsers");
String cookiesStr = "";
for(Cookie cookie : cookies){
System.out.println(cookie.getName() + " : " + cookie.getValue());
cookiesStr += cookie.getName() + " : " + cookie.getValue() + "<br/>";
}
return new ModelAndView("/cookie/cookieView", "cookieValue", cookiesStr);
}
}
From what I have understand the first method (readcookie()) read the content of a coockie named URL stored inside my computer.
The second method (writecookie()) create a cookie named URL and store it on my computer.
And the third method read the contet of all the cookies stored on my computer.
I have 2 doubts:
1) I know that cookies are textual file. Where exactly are stored?
2) Why the **writeCookie() method, after create a new cookie, add it to the response? How can I examinate the cookie stored on my system?
response.addCookie(cookie);
I think that it could depend by the fact that the response come back to the user browser and it retrieve the cookie from this response and create a textual file somewhere on my system. Is it true or am I missing something?
You asked:
1) I know that cookies are textual file. Where exactly are stored?
The cookies are stored by the clients browser, somewhere at the clients machine. - The exact location depends on the browser
2) Why the **writeCookie() method, after create a new cookie, add it to the response? How can I examinate the cookie stored on my system?
As I told in answer for question 1), the cookie is stored at client side. So it's values need to be send to the client (in the header of the http-response). And that is the reason why the cookie (object) is added to the http response.
I strongly recommend you to read the wikipedia article about Http Cookies. And do not get confused by mixing cookies and sessions (sessions are often implement with a session-tracking-cookie, but its data resist on the server side.)

how to prevent confirm alert In Spring MVC on F5

In Spring I usually did a redirect-after-submit(get method mapping) to prevent the user of submitting a form ,
but when i pressing F5 it will go to get method mapping again and display me this kind of confirm message. how could i prevent this message every time on F5.
Here is the code for controller -
ScheduleDetail objScheduleDetail = new ScheduleDetail();
HttpSession session = request.getSession(true);
String condition = "";
try{
int careProfessionalIDF = (Integer) session.getAttribute("careProfessionalIDF");
condition = "CareProfessionalIDF = "+careProfessionalIDF;
objScheduleDetail.setCareProfessionalIDF(careProfessionalIDF);
}catch (Exception e) {
int careProviderIDF = (Integer) session.getAttribute("careProviderIDF");
condition = "CareProviderIDF = "+careProviderIDF;
objScheduleDetail.setCareProviderIDF(careProviderIDF);
}
List<ScheduleDetail> ScheduleDetailList = objScheduleDetailManager.getAllScheduleDetail(condition+" ORDER BY ScheduleDetailIDP DESC");
model.addObject("List_of_ScheduleDetail",ScheduleDetailList);
model.addAttribute("ScheduleDetail", objScheduleDetail);
return "hospital/scheduleDetail";//jsp page
edited code
#RequestMapping("/editAddressType.html")
public String editAddressType(ModelMap model,HttpServletRequest request)
{
int addressTypeIDP = Integer.parseInt(request.getParameter("AddressTypeIDP"));
AddressType objAddressType = new AddressType();
objAddressType = objAddressTypeManager.getByID(addressTypeIDP);
model.addAttribute("AddressType", objAddressType);
return "jsp/addressType";
it open addressType.jsp with data tht we bind with `model.addAttribute`. now if i press F5 it show alert message as above image.
**get method**
#RequestMapping(value="/getAddressType.html", method=RequestMethod.GET)
public String getAddressType(ModelMap model, HttpServletRequest request) throws RemoteException
{
AddressType objAddressType = new AddressType();
model.addAttribute("AddressType", objAddressType);
return "hospital/addressType";
}
If you implement the POST - REDIRECT - GET pattern correctly, you will not see the warning from the browser that you mentioned. The warning is shown when the Page being viewed is in response to a POST request. The traditional pattern, FORM - POST - SUCCESS page.
The code you provided in the question is not enough to reach the root cause of the problem. I'm listing key points of the implementation here, please compare with your code and you'll understand what the mistake is.
To show the user the form, where they are supposed to enter data for submission. (Just the starting point, could be any page in your application.)
#RequestMapping(value = "/checkout/{cartId}.htm", method = RequestMethod.GET)
public ModelAndView showCheckoutForm(...) {
......
return new ModelAndView("/WEB-INF/jsp/form.jsp")
}
The form POSTs to a handler method, which issues a redirect to the user, pointing to a URL that will show the details of the resource created as a result of the POST.
#RequestMapping(value = "/checkout/{cartId}.htm", method = RequestMethod.POST)
public View submitCheckoutForm(....) {
return new RedirectView("/checkout/confirmation/" + cartId + ".htm");
}
The details of the created resource will be shown by a handler method like the following. Note that at this point, if your implementation worked properly, the URL in the user's browser will change to the path redirected by the POST handler. And a fresh GET request will be issued to the server.
#RequestMapping(value = "/checkout/confirmation/{cartId}.htm", method = RequestMethod.GET)
public ModelAndView showCheckoutConfirmation(....) {
return new ModelAndView("viewThatShowsCheckoutConfirmation");
}
If your implementation is similar, the confirmation page is a result of a GET request, so browsers won't issue a warning for re-POSTing data if you refresh the page.
My suspicion is that your POST handler is not issuing a redirect to the user, it is instead rendering the confirmation page itself.
Hope this helps. Please let me know if this does not solve your problem.

Set HTTP status code for redirect when returning a String in a Spring 3 controller

Is there a way to specify the HTTP status code when returning "redirect:/new/url" in Spring 3?
Haven't tried it, but looking at the source of org.springframework.web.servlet.view.RedirectView it has getHttp11StatusCode() method that determines the HTTP status of response.
It seems like you can override the default response code by settings org.springframework.web.servlet.View#RESPONSE_STATUS_ATTRIBUTE property on request. Simply set:
httpServletRequest.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, status)
before returning with "redirect:" view.
As noted by Scolytus, you must return a RedirectView with the statusCode set. Using the "redirect:" prefix will always result in a status of HttpStatus.MOVED_TERMPORARILY (302).
If you need the ability to return String from your controller method as well as RedirectView, you must change the method signature to return Object. Example:
#RequestMapping
public Object someMethod() {
if (doRedirect) {
RedirectView rv = new RedirectView("/new/url");
rv.setStatusCode(HttpStatus.MOVED_PERMANENTLY); // set our own status code
return rv;
} else {
return "someView";
}
}

Resources