Spring-MVC контроллер перенаправить на «предыдущую» страницу? - PullRequest
22 голосов
/ 30 апреля 2009

Допустим, у меня есть форма для редактирования свойств Пони, и в моем веб-приложении есть несколько мест, где вы можете редактировать Пони. Например, в списке Пони может быть ссылка «изменить» рядом с каждым Пони, а когда пользователь просматривает Пони, в этом представлении также может быть ссылка «Редактировать».

Когда пользователь нажимает «отправить» после редактирования Пони, я хотел бы вернуть пользователя на страницу, на которой он был, когда нажимал ссылку «изменить».

Как мне написать свой контроллер, чтобы перенаправить пользователя туда, откуда он начал? Конечно, я могу сделать это, передав параметр в контроллер, но это выглядит немного глупо. Я думаю об этом все неправильно или это в значительной степени то, что мне придется делать?

Ответы [ 6 ]

50 голосов
/ 06 октября 2009

Вот как это сделать, парни (обратите внимание, что это синтаксис RESTful Spring 3 MVC, но он будет работать на старых контроллерах Spring):

@RequestMapping(value = "/rate", method = RequestMethod.POST)
public String rateHandler(HttpServletRequest request) {
    //your controller code
    String referer = request.getHeader("Referer");
    return "redirect:"+ referer;
}
5 голосов
/ 06 мая 2009

Конечно, один из вариантов - открыть форму редактирования в новом окне, поэтому все, что нужно сделать пользователю, это закрыть его, и они вернулись на прежнее место.

В моем текущем приложении есть несколько мест, где мне нужно сделать что-то сложное, затем передать пользователю форму и затем вернуть его в исходную точку. В этих случаях я сохраняю отправную точку в сеансе перед тем, как передать их. Это, вероятно, излишне для того, что вы делаете.

Другие варианты: 1) вы можете сохранить заголовок «Referer» и использовать его, но это может быть ненадежным; не все браузеры устанавливают этот заголовок. 2) у вас может быть javascript на странице подтверждения после отправки формы, которая вызывает "history.go(-2)".

3 голосов
/ 24 августа 2015

Мой ответ похож на ответ Сэма Бродкинса (я также рекомендовал его). Но учитывая, что значение «Referer» может быть недоступно, я сделал эту функцию для использования в моих контроллерах

/**
* Returns the viewName to return for coming back to the sender url
*
* @param request Instance of {@link HttpServletRequest} or use an injected instance
* @return Optional with the view name. Recomended to use an alternativa url with
* {@link Optional#orElse(java.lang.Object)}
*/
protected Optional<String> getPreviousPageByRequest(HttpServletRequest request)
{
   return Optional.ofNullable(request.getHeader("Referer")).map(requestUrl -> "redirect:" + requestUrl);
}

Итак, в функции вызова вашего контроллера вы должны вернуть что-то вроде этого:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody
String testRedirection(HttpServletRequest request)
{
      //Logic....
      //Returns to the sender url
      return getPreviousPageByRequest(request).orElse("/"); //else go to home page
}
1 голос
/ 03 августа 2013

Вы также можете отслеживать ModelAndView (или просто представление), который был последний раз представлен пользователю с перехватчиком. В этом примере отслеживаются только последние модель и вид, но вы можете использовать список для перехода на другие уровни.

package com.sample;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LastModelAndViewInterceptor extends HandlerInterceptorAdapter {

    public static final String LAST_MODEL_VIEW_ATTRIBUTE = LastModelAndViewInterceptor.class.getName() + ".lastModelAndView";

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        request.getSession(true).setAttribute(LAST_MODEL_VIEW_ATTRIBUTE, modelAndView);
        super.postHandle(request, response, handler, modelAndView);
    }

}

С конфигурацией Spring XML:

<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
        <bean class="com.sample.LastModelAndViewInterceptor"/>
    </property>
</bean>

И затем используйте следующий код, чтобы вернуться к этому представлению в контроллере:

ModelAndView mv = (ModelAndView)request.getSession().getAttribute(LastModelAndViewInterceptor.LAST_MODEL_VIEW_ATTRIBUTE);
return mv;
1 голос
/ 15 июня 2012

еще один вариант - создать ваши URL-адреса, чтобы они раскрыли контекст того, что вы делаете, и по соглашению позволили бы вам «знать», где было начало операции.

Например, у вас могут быть URL-адреса, например

site/section1/pony/edit
site/section1/pony/delete

site/somewhere/else/entirely/pony/edit
site/somewhere/else/entirely/pony/delete

оба эти URL позволяют редактировать и удалять пони. Чтобы вернуться к началу работы с ними обоими, вам нужно просто перейти «вверх» на 2 папки. Это можно сделать с помощью функции javascript, которая просматривает текущий URL-адрес и просто просматривает 2 папки, или вы можете выяснить это на стороне сервера 2, а также выполнить такое же перенаправление.

1 голос
/ 05 июня 2009

Да, я думаю, идея Джейкоба для формы в новом окне может быть хорошим вариантом. Или в скрытом div. Как в диалоге додзе. http://dojocampus.org/explorer/#Dijit_Dialog_Basic

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...