domingo, 11 de febrero de 2018

MissingServletRequestParameterException: Como pasar un parámetro a través de JQuery a Spring

Este es un problema que tuve hace un tiempo. Me saltaba la excepción 'MissingServletRequestParameterException' al intentar enviar un parámetro post a un controlador de Spring a través de JQuery. 

Error Status: 400
Error Code: Bad Request
Error Message: Required Integer parameter 'id' is not present
  org.springframework.web.bind.MissingServletRequestParameterException: Required Integer parameter
 'idSpecie' is not present

En principio el error es muy sencillo y habla por si mismo, basicamente que no encuentra el parámetro de la request que se solicita en el controlador. Pero así además veremos un completo de como hacer la llamada con JQuery y ser tratada por Spring. El código java será el mismo siempre, en el tenemos un método para recibir el parámetro 'idSpecie' de una llamada POST a la url '/animal/specie'.

@PostMapping( value = "/animal/specie" )
public String findBySpecies( @RequestParam final Integer idSpecie, final Model model ) {

En la petición JQuery indicamos el código 'X-CSRF' (esto puede dar para otro post), que es una llamada POST con json incluido, a que URL la enviamos (que debe ser la misma indicada en el método java) y el valor que queremos enviar (que se debe llamar igual que en el método java).

jsonObj = {};
jsonObj["idTag"] = $('#species').val();
...
$.ajax({
type : "POST",
contentType : "application/json",
beforeSend : function(jqXHR) {
var csrf_token = $('meta[name=_csrf]').attr('content');
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
},
url : config.contextPath + "/animals/specie" ,
data : JSON.stringify(jsonObj),
dataType : 'html',
timeout : 600000,
success : function(data) {
...
}});

En este caso el error provenia del uso de '@RequestParam' y la función 'stringify'. Y se soluciono con el siguiente cambio en la llamada JQuery

data: { idSpecie: $('#species').val()},

Si se quiere enviar un objeto JSON y que sea tratado por Spring y almacenado en un único objeto deberiamos usar '@RequestBody' en vez de '@RequestParam'. Si lo que se quiere es enviar un único valor (como era este caso), es preferible usar '@RequestParam' pero enviar el el parámetro de forma individualizada y no como parte de un objeto JSON (operación que realiza stringify).

No hay comentarios:

Publicar un comentario