java - query - Spring MVC: objeto complejo como GET @RequestParam
spring query param (3)
Agregaré un breve ejemplo de mi parte.
La clase DTO:
public class SearchDTO {
private Long id[];
public Long[] getId() {
return id;
}
public void setId(Long[] id) {
this.id = id;
}
// reflection toString from apache commons
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
Asignación de solicitud dentro de la clase de controlador:
@RequestMapping(value="/handle", method=RequestMethod.GET)
@ResponseBody
public String handleRequest(SearchDTO search) {
LOG.info("criteria: {}", search);
return "OK";
}
Consulta:
http://localhost:8080/app/handle?id=353,234
Resultado:
[http-apr-8080-exec-7] INFO c.g.g.r.f.w.ExampleController.handleRequest:59 - criteria: SearchDTO[id={353,234}]
Espero que ayude :)
Supongamos que tengo una página que enumera los objetos en una tabla y necesito poner un formulario para filtrar la tabla. El filtro se envía como Ajax GET a una URL como esa: http://foo.com/system/controller/action?page=1&prop1=x&prop2=y&prop3=z
Y en lugar de tener muchos parámetros en mi Controlador como:
@RequestMapping(value = "/action")
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
@RequestParam(value = "prop1", required = false) String prop1,
@RequestParam(value = "prop2", required = false) String prop2,
@RequestParam(value = "prop3", required = false) String prop3) { ... }
Y suponiendo que tengo MyObject como:
public class MyObject {
private String prop1;
private String prop2;
private String prop3;
//Getters and setters
...
}
Quiero hacer algo como:
@RequestMapping(value = "/action")
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
@RequestParam(value = "myObject", required = false) MyObject myObject,) { ... }
¿Es posible? ¿Cómo puedo hacer eso?
Puede hacerlo, solo elimine la anotación @RequestParam
, Spring enlazará limpiamente sus parámetros de solicitud a su instancia de clase:
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
MyObject myObject)
Tengo un problema muy similar. En realidad, el problema es más profundo, como yo pensaba. Estoy usando jquery $.post
que usa Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
como predeterminado. Desafortunadamente basé mi sistema en eso y cuando necesité un objeto complejo como @RequestParam
no pude hacerlo.
En mi caso, estoy tratando de enviar preferencias de usuario con algo así como;
$.post("/updatePreferences",
{id: ''pr'', preferences: p},
function (response) {
...
Del lado del cliente, los datos brutos reales enviados al servidor son;
...
id=pr&preferences%5BuserId%5D=1005012365&preferences%5Baudio%5D=false&preferences%5Btooltip%5D=true&preferences%5Blanguage%5D=en
...
analizado como;
id:pr
preferences[userId]:1005012365
preferences[audio]:false
preferences[tooltip]:true
preferences[language]:en
y el lado del servidor es;
@RequestMapping(value = "/updatePreferences")
public
@ResponseBody
Object updatePreferences(@RequestParam("id") String id, @RequestParam("preferences") UserPreferences preferences) {
...
return someService.call(preferences);
...
}
Intenté @ModelAttribute
, agregué setter / getters, constructores con todas las posibilidades a UserPreferences
pero no tuve la oportunidad, ya que reconocía los datos enviados como 5 parámetros, pero de hecho el método mapeado tiene solo 2 parámetros. También probé la solución de Biju; sin embargo, lo que sucede es que Spring crea un objeto UserPreferences con el constructor predeterminado y no completa los datos.
Resolví el problema enviando cadena JSon de las preferencias desde el lado del cliente y lo manejo como si fuera una Cadena en el lado del servidor;
cliente:
$.post("/updatePreferences",
{id: ''pr'', preferences: JSON.stringify(p)},
function (response) {
...
servidor:
@RequestMapping(value = "/updatePreferences")
public
@ResponseBody
Object updatePreferences(@RequestParam("id") String id, @RequestParam("preferences") String preferencesJSon) {
String ret = null;
ObjectMapper mapper = new ObjectMapper();
try {
UserPreferences userPreferences = mapper.readValue(preferencesJSon, UserPreferences.class);
return someService.call(userPreferences);
} catch (IOException e) {
e.printStackTrace();
}
}
para resumir, hice la conversión manualmente dentro del método REST. En mi opinión, el motivo por el cual Spring no reconoce los datos enviados es el tipo de contenido.