2012-02-02 10 views
5

Tengo un servicio de descanso de primavera usando Spring 3.1.0.RELEASE. Aquí está el código relevante para el servicio de llamada en cuestión:¿Por qué mi servicio Spring devuelve cualquier tipo de contenido solicitado por el cliente?

@RequestMapping(value="/{var1}", method=RequestMethod.GET, produces="application/json") 
@ResponseBody 
public String getSomeStuff(@PathVariable final String var1) { 
    return myJsonString; 
} 

Si llamo a esto usando el siguiente comando curl, que felizmente me devuelve mi cadena JSON con un tipo de contenido application/xml, mientras que se puede esperar una 406 basadas en la primavera 3,1 docs:

curl -v -H "Accept: application/xml" http://localhost:8080/MyServiceSite/myvalue 

no hay ninguna configuración adicional en mi aplicación para este servicio (sin serialización), Voy a volver JSON en bruto sin post-procesamiento para el servicio configurado. Estoy seguro de haberme perdido algo, ¿alguien puede señalar algo que me haya pasado por alto?

Editar: Aquí está el documentation que estaba buscando al intentar hacer que esto funcione. Específicamente la sección 16.3.2.5. Mi código es muy similar, excepto que su código parece que asume la configuración de configuración para permitir que Spring maneje la serialización. Quizás el produce no funciona al pasar por alto la serialización de primavera?

Editar: Cambié mi expectativa por el código de respuesta. Un 415 indicaría que estaba enviando contenido inapropiado en mi cuerpo de solicitud, mientras que 406 es apropiado para tener un encabezado de aceptación que no coincida con el tipo de contenido del servidor.

De todas formas, he cambiado este método, devuelvo un Mapa y agregué la configuración para serializarlo a json y ahora si envío un tipo de contenido inválido del cliente obtengo la respuesta 406 correcta. Parece que tal vez la configuración "produce" se ignora cuando la salida del método no se serializa.

+0

Quizás pueda responder su propia pregunta con el código modificado y la configuración aplicable para que alguien que esté viendo en el futuro pueda beneficiarse. – digitaljoel

+0

Lo haré si no puedo encontrar la forma de hacerlo sin activar la serialización. Los datos que tengo ya están serializados, por lo que sería desafortunado si tuviera que deserializarlo y volver a serializarlo para obtener el comportamiento adecuado. Así que todavía estoy buscando otra forma de hacerlo funcionar. – mockobject

Respuesta

1

La condición de producción es nueva en Spring MVC 3.1 y solo es compatible con RequestMappingHandlerMapping y clases de soporte de @MVC relacionadas, también new in Spring 3.1. Supongo que estás usando las clases de soporte 3.0 @MVC, que no admiten la condición produce. De lo contrario, su código es correcto y también lo son sus expectativas sobre lo que debería suceder.

El uso de encabezados = "Aceptar = aplicación/json" no es necesario en 3.1. Para eso se introdujo exactamente la condición de producción.

+0

Estoy usando la primavera 3.1 y había verificado mis dependencias, pero cuando mencionó esto, me pregunté si algo en mi configuración estaba configurado para usar el controlador anterior. Efectivamente, aparentemente usando usa los manejadores antiguos, mientras que usar parece usar los nuevos manejadores y todo funciona como se espera. Por alguna razón, este hecho no fue realmente obvio para mí cuando leí la documentación. – mockobject

1

¿Qué pasa con el atributo headers para el @RequestMapping. Puede establecer el encabezado Aceptar allí. Algo como:

@RequestMapping(value="/{var1}", method=RequestMethod.GET, produces="application/json", headers = "Accept=application/json") 
@ResponseBody 
public String getSomeStuff(@PathVariable final String var1) { 
    return myJsonString; 
} 

No sé cómo Spring podría manejar una solicitud a esa ruta sin un encabezado coincidente. Si no da lo que desea, podría necesitar definir un mapeo similar sin los encabezados y hacer que devuelva una ResponseEntity y establecer el código de respuesta o algo así, pero espero que lo maneje adecuadamente.

+0

Desafortunadamente, la configuración de los encabezados parece tambaleante. El problema menor con esto es que devuelve un 404 en lugar de un 406. El problema más grande es que no se resuelve, excepto explícitamente por alguna razón. Por ejemplo, si el cliente envía accept */*, se producirá un error. Solo se resuelve si el cliente envía accept application/json. Lo cual, probablemente, también está bien para nosotros, parece estar mal. – mockobject

+0

Eso es una pena. – digitaljoel

Cuestiones relacionadas