Pergunta

Vamos dizer que tenho um formulário para editar as propriedades de um pônei, e na minha aplicação web, existem vários lugares onde você pode optar por editar um pônei. Por exemplo, em uma lista de pôneis pode haver um link "Editar" ao lado de cada Pony, e quando o usuário está vendo um pônei, também pode haver um link "editar" nesse ponto de vista.

Quando um usuário clica em "enviar" depois de editar um pônei, eu gostaria de retornar o usuário para a página que ele ou ela foi ao clicar no link "editar".

Como faço para escrever meu controlador para redirecionar o usuário de volta para onde começou? Certamente eu posso fazer isso passando um parâmetro para o controlador, mas que parece um pouco pateta. Am I pensamento sobre esta tudo errado ou isso é muito bonito o que eu vou ter que fazer?

Foi útil?

Solução

Uma opção, é claro, seria para abrir o formulário de edição em uma nova janela, assim que todo o usuário tem a fazer é fechá-lo e eles estão de volta onde eles estavam.

Há alguns lugares em meu aplicativo atual, onde eu preciso fazer algo complicado, em seguida, passar o usuário a um formulário, e então eles têm que voltar ao ponto de partida. Nesses casos eu armazenar o ponto de partida na sessão antes de passá-los fora. Isso é provavelmente um exagero para o que você está fazendo.

Outras opções: 1) você pode armazenar o cabeçalho "Referer" e usar isso, mas que pode não ser confiável; nem todos os navegadores definir esse cabeçalho. 2) você poderia ter javascript na página de confirmação após o envio do formulário que as chamadas "history.go(-2)".

Outras dicas

Aqui está como fazê-lo meninos (Note que este é RESTful Spring 3 MVC sintaxe, mas ele vai trabalhar em controladores de Primavera mais velhos):

@RequestMapping(value = "/rate", method = RequestMethod.POST)
public String rateHandler(HttpServletRequest request) {
    //your controller code
    String referer = request.getHeader("Referer");
    return "redirect:"+ referer;
}

A minha resposta é semelhante a Sam Brodkins's (i recomendado também). Mas tendo em conta que o valor "Referer" pode não estar disponível eu fiz esta função para usá-lo em meus controladores

/**
* 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);
}

Assim, em sua função de controlador de chamadas que você deve retornar algo como isto:

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

Sim, eu acho que a idéia de Jacob para a forma em uma nova janela pode ser uma boa opção. Ou em uma div oculta. Como um diálogo dojo. http://dojocampus.org/explorer/#Dijit_Dialog_Basic

uma outra opção seria a de projetar seus urls para que eles revelam o contexto do que você está fazendo, e por convenção, que permitem que você "sabe" onde o início de uma operação era.

Por exemplo, você poderia ter urls como assim

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

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

ambas as urls permitir a edição pônei e exclusão. Para voltar para o início para ambos, você simplesmente ir "para cima" 2 pastas. Isso poderia ser feito através de uma função javascript que olha para a url atual, e apenas vai até 2 pastas, ou você poderia descobrir isso no lado do servidor 2, e fazer um redirecionamento assim também.

Você também pode acompanhar o ModelAndView (ou apenas a vista) que foram última apresentada ao usuário com um interceptor. Este exemplo mantém o controle de apenas o último modelo e vista, mas você pode usar uma lista para navegar de volta mais níveis.

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);
    }

}

Com a configuração XML do Spring:

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

E, em seguida, usar o seguinte código para voltar a esse ponto de vista em um controlador:

ModelAndView mv = (ModelAndView)request.getSession().getAttribute(LastModelAndViewInterceptor.LAST_MODEL_VIEW_ATTRIBUTE);
return mv;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top