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

StackOverflow https://stackoverflow.com/questions/804581

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

Вы также можете отслеживать 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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top