2012-01-21 21 views
35

Estoy tratando de que 2 botones de envío se publiquen en un formulario, con cada acción de botón asignada a diferentes controladores. Aquí están mis asignacionesSpring MVC - Botón de envío múltiple a un formulario

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

Y mis botones de envío parecerse a ellos -

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

Como se puede ver en mi asignación, yo estoy confiando en el uso de los parametros para diferenciar lo que el botón se ha hecho clic en. El problema es que funciona el 90% del tiempo, pero a veces tengo la excepción abajo -

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) 

Curiosamente, cuando esto sucede y volver a presentar la página, todo funciona bien después. ¿Hay una mejor manera de lograr lo que estoy tratando de hacer?

Gracias!

+1

No estoy seguro si es su problema, pero tenga en cuenta que algunos navegadores suele enviar el par clave/valor de los botones si el usuario envía el formulario a través de la tecla Intro u otros métodos además de hacer clic en el botón. Por lo tanto, asegúrese de asumir una acción predeterminada, que para la compatibilidad del navegador debe ser la acción del * primer botón * en el origen html de ese formulario. – goat

Respuesta

6

Basta con crear un controlador con un método similar a este

@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

Por qué no:

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

y luego:

@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

Parece un poco peligroso, ya que el atributo 'value' en la etiqueta' input' contiene el texto del botón. Creo que no seré tu amigo con este método. –

+0

Tuve problemas con IE (10) no publicando valores consistentemente, y adopté su enfoque. Aunque no ultra-limpio, funcionó para mí. Aclamaciones. –

34

si el formulario ha especificado estos botones:

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" 

puede dirigir a diferentes solicitudes de URL según el botón presionado con un controlador.

para el botón de cancelar,

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

lo asignación de solicitud hace es escanear solicitud posterior si contiene el nombre params = cancelar.

para guardar el botón,

@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

Si tiene más métodos de controlador con el mismo @RequestMapping que difiere sólo en params atributo, usted tiene que escribir de forma explícita:

  • qué parámetro se supone que es presente en la solicitud, por ejemplo params="save"
  • cuyo parámetro NO se supone que esté presente en la solicitud, p. params="!save"

En su caso:

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

Esto debería solucionar el error métodos de controlador ambiguas asignadas para la ruta de HTTP ...

Ver Spring Web API 4.0.x - RequestMapping#params

1

Uno más solución:

@RequestMapping(value="/save", method={RequestMethod.POST}, params={"save=Save"}) 
@RequestMapping(value="/save", method={RequestMethod.POST}, params={"renew=Renew"}) 
Cuestiones relacionadas