invocar - Cliente Java REST sin esquema
java consume rest service json (4)
Gol
Cliente Java para HotJobs Resumé Search REST API de Yahoo.
Fondo
Estoy acostumbrado a escribir clientes de servicios web para las API de SOAP, donde wsimport genera stubs de proxy y está apagado y en funcionamiento. Pero esta es una API REST, que es nueva para mí.
Detalles
- API REST
- No WADL
- Sin esquema XML formal (archivos XSD o DTD). Hay ejemplos de pares de solicitud / respuesta XML .
- No se proporcionó un código de ejemplo
Progreso
Miré a la pregunta Rest Customers para Java? , pero las soluciones automatizadas allí suponen que está proporcionando el servidor y el cliente, con JAXB invocado en POJO para generar un esquema y una API REST.
Utilizando Jersey (una implementación JAX-RS ), he podido hacer una solicitud HTTP manual:
import com.sun.jersey.api.client.*;
...
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
WebResource webResource = client.resource("https://hj.yahooapis.com/v1/HJAuthTokens");
webResource.accept("application/xml");
// body is a hard-coded string, with replacements for the variable bits
String response = webResource.post(String.class, body);
// parse response into a org.w3c.dom.Document
// interface with Document via XPATH, or write my own POJO mappings
La respuesta puede verse así:
<?xml version="1.0" encoding="utf-8"?>
<Response>
<ResponseCode>0</ResponseCode>
<ResponseMessage>Login successful</ResponseMessage>
<Token>NTlEMTdFNjk3Qjg4NUJBNDA3MkJFOTI3NzJEMTdDNDU7bG9jYWxob3N0LmVnbGJwLmNvcnAueWFob28uY29tO0pVNWpzRGRhN3VhSS4yQVRqRi4wWE5jTWl0RHVVYzQyX3luYWd1TjIxaGx6U0lhTXN3LS07NjY2MzM1OzIzNDY3NTsxMjA5MDE2OTE5OzZCM1RBMVNudHdLbl9VdFFKMFEydWctLQ==</Token>
</Response>
O bien, puede verse así:
<?xml version="1.0" encoding="utf-8"?>
<yahoo:error xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xml:lang="en-US">
<yahoo:description>description</yahoo:description>
<yahoo:detail>
<ErrorCode>errorCode</ErrorCode>
</yahoo:detail>
</yahoo:error>
Preguntas
Es interesante que proporcionen una URL HTTP como el URI de espacio de nombres para el esquema, pero en realidad no guardan su esquema allí. Eso podría ser un descuido de su parte, que una publicación por correo electrónico o lista de discusión podría corregir.
Un enfoque es crear su propio esquema, pero esto parece mucho trabajo con poco rendimiento. Dado lo simples que son los mensajes, me pregunto si incluso necesitas un POJO para envolverlos. ¿Por qué no tener un controlador que extraiga la información que necesita con XPath?
Editar: ráfaga del pasado, pero vi el comentario, volví a leer la pregunta y me di cuenta de que la primera frase era difícil de entender. Entonces, aclaración:
Un buen hábito, si va a escribir un servicio web de acceso público, es hacer que su documento de esquema esté disponible en la misma URL que usa para el URI del espacio de nombres del esquema, o mejor, tener esa URL como un enlace para completar documentación (el espacio de nombres W3C XSD es en sí mismo un buen ejemplo: http://www.w3.org/2001/XMLSchema ).
Sugiero escribir frijoles a mano, y solo anotar con anotaciones JAXB si es necesario. Para la mayoría de los accessors / mutators (getters / setters) no es necesario; de forma predeterminada, se consideran todos los accesores y campos de frijol público, el nombre se deriva usando la convención de frijol, y por defecto es usar elementos en lugar de atributos (por lo que los atributos deben ser anotados).
Alternativamente, por supuesto, puede escribir el esquema a mano, generar frijoles usando JAXB, si le gusta mucho el esquema W3C. Y solo use el código resultante, no el esquema, para el enlace de datos.
En cuanto a POJO: eso puede ser muy simple. Algo como:
@XmlRootElement("Response")
class Response {
public int responseCode;
public String responseMessage;
public String token; // or perhaps byte[] works for automated base64?
}
y de manera similar para otros. O bien, usa getters / setters si te gustan y no te importa un poco más de detalle. Estos son solo contenedores de datos, no es necesario ser demasiado elegante.
Y si debe detectar automáticamente el tipo de contenido, considere usar el analizador de Stax para ver cuál es el elemento raíz, y luego agréguelo utilizando JAXB Unmarshaller, y entregue XMLStreamReader que apunta a ese elemento raíz. De esa forma puedes pasar diferentes tipos de objetos para enlazar.
Y finalmente: enviar / recibir solicitudes: simple viejo HttpURLConnection funciona bien para solicitudes GET y POST (construye usando, digamos, URL.openConnection ()). Jakarta HttpClient tiene más funciones si es necesario. Por lo tanto, muchas veces no se necesita un cliente REST por separado; pueden ser útiles, pero generalmente se basan en simples piezas de cliente HTTP.
Creo que HTTP4E es muy útil para realizar llamadas REST. Es un impresionante plugin de Eclipse, tiene pestañas, coloreado de sintaxis, sugerencia automática, generación de código, reproducción de llamadas HTTP REST, etc. Hace un gran trabajo de depuración de HTTP, manipulación de HTTP, piratería. Me estoy divirtiendo mucho con eso.
Prueba JdkRequest
desde jcabi-http (soy desarrollador). Así es como funciona:
String body = new JdkRequest("http://www.google.com")
.header("User-Agent", "it''s me")
.fetch()
.body()
Consulte esta publicación en el blog para obtener más información: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html