Chamada RESTful em Java

150

Vou fazer uma chamada RESTful em Java. No entanto, não sei como fazer a ligação. Preciso usar o URLConnection ou outros? Alguém pode me ajudar. obrigado.

Questões
fonte
Depende de como você realiza as chamadas em seu aplicativo. Você usa uma implementação JaxRS? Um em particular? Você está fazendo solicitações manualmente?
Colin Hebert
@Colin Hebert, obrigado pela sua resposta. Mas não tenho ideias da chamada RESTful. você poderia me fornecer mais informações sobre diferentes partes da chamada RESTful.
Perguntas
checkout http restful client clique aqui
Gaurav J

Respostas:

91

Se você estiver chamando um serviço RESTful de um provedor de serviços (por exemplo, Facebook, Twitter), poderá fazê-lo com qualquer sabor de sua escolha:

Se você não quiser usar bibliotecas externas, poderá usar java.net.HttpURLConnectionou javax.net.ssl.HttpsURLConnection(para SSL), mas isso é chamada encapsulada em um padrão de tipo Factory em java.net.URLConnection. Para receber o resultado, você terá connection.getInputStream()que retornar um InputStream. Você precisará converter seu fluxo de entrada em string e analisá-la em seu objeto representativo (por exemplo, XML, JSON, etc.).

Como alternativa, o Apache HttpClient (versão 4 é a mais recente). É mais estável e robusto que o padrão do java URLConnectione suporta a maioria (se não todos) do protocolo HTTP (e pode ser definido no modo Estrito). Sua resposta ainda estará disponível InputStreame você poderá usá-la conforme mencionado acima.


Documentação em HttpClient: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html

Buhake Sindi
fonte
5
Não reinvente a roda, use uma das implementações RESTful existentes.
Qwerky
13
Não está reinventando a roda, estou dizendo que você pode usar o flavourque quiser. Alguns querem o padrão URLConnection, outros querem HttpClient. De qualquer maneira, está lá para você usar.
Buhake Sindi
@ The Elite Gentleman, obrigado por sua resposta. Depois de verificar toda a biblioteca, quero usar o Apache HttpClient. Gostaria de me dar mais referência sobre essa?
Perguntas
@ Questões, o link para os exemplos do HttpClient 4 parece estar quebrado, por isso, se você tiver alguma dúvida (trocadilhos ... lol), avise-me ... Eu lido quase diariamente.
Buhake Sindi 13/10/10
Por favor, mostre exemplo de código de como usar essas classes, ao invés de apenas observando sua existência
Jonathan
150

Atualização: Faz quase 5 anos desde que escrevi a resposta abaixo; hoje eu tenho uma perspectiva diferente.

99% do tempo em que as pessoas usam o termo REST, elas realmente significam HTTP; eles poderiam se importar menos com "recursos", "representações", "transferências de estado", "interfaces uniformes", "hipermídia" ou quaisquer outras restrições ou aspectos do estilo de arquitetura REST identificados por Fielding . As abstrações fornecidas por várias estruturas REST são, portanto, confusas e inúteis.

Portanto: você deseja enviar solicitações HTTP usando Java em 2015. Você deseja uma API clara, expressiva, intuitiva, idiomática, simples. O que usar? Eu não uso mais o Java, mas nos últimos anos a biblioteca do cliente HTTP Java que parecia a mais promissora e interessante é o OkHttp . Confira.


Você pode definitivamente interagir com os serviços da Web RESTful usando URLConnectionou HTTPClient para codificar solicitações HTTP.

No entanto, geralmente é mais desejável usar uma biblioteca ou estrutura que forneça uma API mais simples e semântica projetada especificamente para esse fim. Isso facilita a gravação, leitura e depuração do código e reduz a duplicação de esforços. Essas estruturas geralmente implementam alguns ótimos recursos que não são necessariamente presentes ou fáceis de usar em bibliotecas de nível inferior, como negociação de conteúdo, armazenamento em cache e autenticação.

Algumas das opções mais maduras são Jersey , RESTEasy e Restlet .

Eu estou mais familiarizado com Restlet e Jersey, vamos ver como faríamos uma POSTsolicitação com as duas APIs.

Exemplo de Jersey

Form form = new Form();
form.add("x", "foo");
form.add("y", "bar");

Client client = ClientBuilder.newClient();

WebTarget resource = client.target("http://localhost:8080/someresource");

Builder request = resource.request();
request.accept(MediaType.APPLICATION_JSON);

Response response = request.get();

if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
    System.out.println("Success! " + response.getStatus());
    System.out.println(response.getEntity());
} else {
    System.out.println("ERROR! " + response.getStatus());    
    System.out.println(response.getEntity());
}

Exemplo de Restlet

Form form = new Form();
form.add("x", "foo");
form.add("y", "bar");

ClientResource resource = new ClientResource("http://localhost:8080/someresource");

Response response = resource.post(form.getWebRepresentation());

if (response.getStatus().isSuccess()) {
    System.out.println("Success! " + response.getStatus());
    System.out.println(response.getEntity().getText());
} else {
    System.out.println("ERROR! " + response.getStatus());
    System.out.println(response.getEntity().getText());
}

Obviamente, as solicitações GET são ainda mais simples, e você também pode especificar itens como tags e Acceptcabeçalhos de entidade , mas esperamos que esses exemplos sejam úteis e não triviais, mas não muito complexos.

Como você pode ver, Restlet e Jersey têm APIs de cliente semelhantes. Eu acredito que eles foram desenvolvidos na mesma época e, portanto, influenciaram um ao outro.

Acho que a API do Restlet é um pouco mais semântica e, portanto, um pouco mais clara, mas YMMV.

Como eu disse, eu estou mais familiarizado com o Restlet, eu o uso em muitos aplicativos há anos e estou muito feliz com isso. É uma estrutura muito madura, robusta, simples, eficaz, ativa e bem suportada. Não posso falar com Jersey ou RESTEasy, mas minha impressão é que as duas também são escolhas sólidas.

Avi Linho
fonte
2
Mas ainda é um ótimo post. E eu tenho que concordar com "99% do tempo em que as pessoas usam o termo REST, elas realmente significam HTTP; ... As abstrações fornecidas por várias estruturas REST são, portanto, confusas e inúteis".
AlexD
2
No seu exemplo de Jersey, onde / como o objeto Form é usado? Ele foi criado, mas não parece adicionar nada ao exemplo.
splungebob
24

Se você apenas precisar fazer uma chamada simples para um serviço REST a partir de java, use algo nesse sentido

/*
 * Stolen from http://xml.nig.ac.jp/tutorial/rest/index.html
 * and http://www.dr-chuck.com/csev-blog/2007/09/calling-rest-web-services-from-java/
*/
import java.io.*;
import java.net.*;

public class Rest {

    public static void main(String[] args) throws IOException {
        URL url = new URL(INSERT_HERE_YOUR_URL);
        String query = INSERT_HERE_YOUR_URL_PARAMETERS;

        //make connection
        URLConnection urlc = url.openConnection();

        //use post mode
        urlc.setDoOutput(true);
        urlc.setAllowUserInteraction(false);

        //send query
        PrintStream ps = new PrintStream(urlc.getOutputStream());
        ps.print(query);
        ps.close();

        //get result
        BufferedReader br = new BufferedReader(new InputStreamReader(urlc
            .getInputStream()));
        String l = null;
        while ((l=br.readLine())!=null) {
            System.out.println(l);
        }
        br.close();
    }
}
nervosismo
fonte
1
Existem algumas APIs REST realmente boas, recomendo usar uma em vez de reinventar a roda.
Qwerky
como eu disse: complicado pra caramba. (não, eu não downvote isso, é uma solução perfeitamente válido)
Sean Patrick Floyd
4
As bibliotecas de API do lado do cliente @Qwerky geralmente são uma violação das restrições REST. Eles introduzem muito acoplamento. Usar uma boa biblioteca HTTP é uma opção muito melhor a longo prazo.
Darrel Miller
10

Existem várias APIs RESTful por aí. Eu recomendaria Jersey;

https://jersey.java.net/

A documentação da API do cliente está aqui;

https://jersey.java.net/documentation/latest/index.html

O
local da atualização para os documentos do OAuth no comentário abaixo é um link morto e foi movido para https://jersey.java.net/nonav/documentation/latest/security.html#d0e12334

Qwerky
fonte
6
O OP não está criando um aplicativo RESTful, ele está fazendo chamadas RESTful, ou seja, como chamar um recurso de método da API do Twitter.
Buhake Sindi
@ Qwerky - Eu acho que seria útil incluir por que você recomenda Jersey em sua resposta.
precisa
7

Quero compartilhar minha experiência pessoal, chamando uma chamada REST WS com Post JSON:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;

public class HWS {

    public static void main(String[] args) throws IOException {
        URL url = new URL("INSERT YOUR SERVER REQUEST");
        //Insert your JSON query request
        String query = "{'PARAM1': 'VALUE','PARAM2': 'VALUE','PARAM3': 'VALUE','PARAM4': 'VALUE'}";
        //It change the apostrophe char to double colon char, to form a correct JSON string
        query=query.replace("'", "\"");

        try{
            //make connection
            URLConnection urlc = url.openConnection();
            //It Content Type is so importan to support JSON call
            urlc.setRequestProperty("Content-Type", "application/xml");
            Msj("Conectando: " + url.toString());
            //use post mode
            urlc.setDoOutput(true);
            urlc.setAllowUserInteraction(false);

            //send query
            PrintStream ps = new PrintStream(urlc.getOutputStream());
            ps.print(query);
            Msj("Consulta: " + query);
            ps.close();

            //get result
            BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
            String l = null;
            while ((l=br.readLine())!=null) {
                Msj(l);
            }
            br.close();
        } catch (Exception e){
            Msj("Error ocurrido");
            Msj(e.toString());
        }
    }

    private static void Msj(String texto){
        System.out.println(texto);
    }
}
Lisandro
fonte
5

Você pode conferir o CXF . Você pode visitar o artigo JAX-RS aqui

A chamada é tão simples como esta (citação):

BookStore store = JAXRSClientFactory.create("http://bookstore.com", BookStore.class);
// (1) remote GET call to http://bookstore.com/bookstore
Books books = store.getAllBooks();
// (2) no remote call
BookResource subresource = store.getBookSubresource(1);
// {3} remote GET call to http://bookstore.com/bookstore/1
Book b = subresource.getDescription();
Joopiter
fonte
5

De fato, isso é "muito complicado em Java":

De: https://jersey.java.net/documentation/latest/client.html

Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://foo").path("bar");
Invocation.Builder invocationBuilder = target.request(MediaType.TEXT_PLAIN_TYPE);
Response response = invocationBuilder.get();
JRun
fonte
4

A solução mais fácil será usar a biblioteca cliente http Apache. consulte o seguinte código de amostra. esse código usa segurança básica para autenticação.

Adicione a seguinte dependência.

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
Credentials credentials = new UsernamePasswordCredentials("username", "password");
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build();
HttpPost request = new HttpPost("https://api.plivo.com/v1/Account/MAYNJ3OT/Message/");HttpResponse response = client.execute(request);
    // Get the response
    BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    String line = "";
    while ((line = rd.readLine()) != null) {    
    textView = textView + line;
    }
    System.out.println(textView);
Hemin
fonte
1

Vejo muitas respostas, eis o que estamos usando no 2020 WebClient , e o BTW RestTemplate ficará obsoleto. (pode verificar isso) RestTemplate será preterido

Francis Raj
fonte
Em vez de fornecer o link, você pode adicionar uma explicação aqui?
Kishan Bharda
-1

Você pode usar o cliente HTTP assíncrono (a biblioteca também suporta o protocolo WebSocket ) assim:

    String clientChannel = UriBuilder.fromPath("http://localhost:8080/api/{id}").build(id).toString();

    try (AsyncHttpClient asyncHttpClient = new AsyncHttpClient())
    {
        BoundRequestBuilder postRequest = asyncHttpClient.preparePost(clientChannel);
        postRequest.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
        postRequest.setBody(message.toString()); // returns JSON
        postRequest.execute().get();
    }
kayz1
fonte
ele não funciona (não pode instanciar ASyncHttpClient).
Java Main