2012-01-21 16 views
35

Próbuję umieścić 2 przyciski wysyłania w formularzu, z każdą akcją przycisku odwzorowaną na różne kontrolery. Oto moje mapowaniaSpring MVC - przycisk wielokrotnego wysyłania do formularza

@RequestMapping(value="/save", method=RequestMethod.POST, params="save") 
@RequestMapping(value="/save", method=RequestMethod.POST, params="renew") 

i moi złożyć przyciski wyglądają jak te -

<input type="submit" name="save" class="button" value="Save" /> 
<input type="submit" name="renew" class="button" value="Renew" /> 

Jak widać z mojego mapowanie, jestem powołując się na wykorzystaniu params odróżnić co przycisk został kliknięty. Problemem jest to, że działa ona 90% czasu, ale czasami mam wyjątek poniżej -

java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path 'http://localhost:8090/myapp/save': {public java.lang.String com.myapp.SaveController.save(MyEntity,javax.servlet.http.HttpSession), public java.lang.String com.myapp.SaveController.saveAndRenew(MyEntity,javax.servlet.http.HttpSession)} 
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:248) 
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:194) 

dziwnie, kiedy to się dzieje, a ja ponownie przesłać stronę, wszystko działa dobrze, potem. Czy istnieje lepszy sposób osiągnięcia tego, co próbuję zrobić?

Dzięki!

+1

nie wiem, czy jego problem, ale należy pamiętać, niektóre przeglądarki przyzwyczajenie wysłać parę klucz/wartość jakichkolwiek przycisków, jeśli użytkownik wysyła formularz za pomocą klawisza Enter lub niektórych innych metod oprócz kliknięcia przycisku. Dlatego należy przyjąć domyślną akcję, która dla zgodności przeglądarki musi być działaniem * pierwszego przycisku * w źródle HTML tego formularza. – goat

Odpowiedz

6

Wystarczy utworzyć jeden kontroler z metodą podobną do tej

@RequestMapping(value="/save", method=RequestMethod.POST) 
public String handlePost(@RequestParam(required=false , value = "save") String saveFlag , @RequestParam(required=false , value = "renew") String renewFlag){ 

if(saveFlag != null{ 
    //handle save 
} 
else if(renewFlag !=null{ 
    //handle renew 
} 

} 
32

Dlaczego nie:

<input type="submit" name="action" value="save" /> 

, a następnie:

@RequestMapping(value="/save", method=RequestMethod.POST) 
public String handlePost(@RequestParam String action){ 

    if(action.equals("save")){ 
     //handle save 
    } 
    else if(action.equals("renew")){ 
     //handle renew 
    } 

} 
+7

Wydaje się nieco niebezpieczne, ponieważ atrybut 'value' na tagu' input' zawiera tekst przycisku. Myślę, że i18n nie będzie twoim przyjacielem z tą metodą. –

+0

Miałem problemy z IE (10), nie publikując wartości konsekwentnie, i przyjęliśmy Twoje podejście. Chociaż nie był on czysty, zadziałało to dla mnie. Twoje zdrowie. –

34

jeśli formularz określił te przyciski:

input type="submit" class="button" name="save" value="Save" 
input type="submit" class="button" name="delete" value="Delete" 
input type="submit" class="button" name="cancel" value="Cancel" 

możesz kierować do różnych żądań adresu URL, naciskając przycisk z jednym kontrolerem.

na przycisk Anuluj,

@RequestMapping(params = "cancel", method = RequestMethod.POST) 
public String cancelUpdateUser(HttpServletRequest request) { 
    return "redirect:/users.html"; 
} 

co prośba mapowanie robi jest skanowanie żądania POST, jeśli zawiera ona nazwę params = anulować.

na przycisk Zapisz,

@RequestMapping(params = "save", method = RequestMethod.POST) 
public String saveUser(HttpServletRequest request, @ModelAttribute User user, BindingResult result, SessionStatus status) { 
    // validate your result 
    // if no errors, save it and redirect to successView. 
} 
9

Jeśli masz więcej metod kontrolera z tego samego @RequestMapping która różni się tylko w atrybucie params, trzeba wyraźnie napisać:

  • który parametr ma być obecny w żądaniu, np params="save"
  • który parametr NIE powinien znajdować się w żądaniu, np. params="!save"

w Twoim przypadku:

@RequestMapping(value="/save", method=RequestMethod.POST, params={"save", "!renew"}) 
@RequestMapping(value="/save", method=RequestMethod.POST, params={"renew", "!save"}) 

ten powinien naprawić błąd niejednoznacznych metod obsługi odwzorowanych na ścieżce HTTP ...

Zobacz Spring Web API 4.0.x - RequestMapping#params

1

Jeszcze rozwiązanie:

@RequestMapping(value="/save", method={RequestMethod.POST}, params={"save=Save"}) 
@RequestMapping(value="/save", method={RequestMethod.POST}, params={"renew=Renew"}) 
Powiązane problemy