Подтвердить что ты не робот

Spring -MVC-контроллер перенаправляется на "предыдущую" страницу?

Скажем, у меня есть форма для редактирования свойств Pony, и в моем веб-приложении есть несколько мест, где вы можете редактировать Pony. Например, в списке Ponies может быть ссылка "edit" рядом с каждым Pony, и когда пользователь просматривает Pony, в этом представлении может также быть ссылка "edit".

Когда пользователь нажимает кнопку "отправить" после редактирования Pony, я хотел бы вернуть пользователя на страницу, которую он или она нажали, нажав ссылку "Изменить".

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Здесь, как это сделать, мальчики (обратите внимание, что это синтаксис 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;
}

Ответ 3

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

Ответ 4

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

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

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

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

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

Ответ 5

Вы также можете отслеживать 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;

Ответ 6

Мой ответ похож на Сэма Бродкинса (я тоже рекомендовал его). Но имея в виду, что значение "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);
}

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

@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
}