OAuth2 Client Credentials flow klient v Javě - poradíte, kde mám chybu?

Palecek.x

Zdravím Javisty a současně prosím o radu. Napsal jsem si jak v CSharpu tak i v Javě klienta na getování tokenu zde v Javě pomocí org.apache.httpcomponentsˇ4.5.6. Nevím ale, proč mi to v CSharpu běhá (200 OK, vrací Json s tokenem atd.) a v Javě ne. (taktéž vrací 200 OK, ale nedostanu se ke kontentu responsy, to bych chápal u 204.) Když změním cokoliv v headeru nebo body, dostanu Bad Request stejně v obou klientech. Takže buď to vyčítám z něčeho, z čeho nemám, nebo nevím...

Je tam něco zjevně blbě? Kód je následující:

Kód: [Vybrat]
public class BearerTokenProvider {

    private BearerToken _bearerToken;
    private String _authAddress;
    private String _authHeaderValue;
    private List<NameValuePair> _commonBodyParams;

    public BearerTokenProvider(CredentialsModel credentialsModel)
    {
        _authAddress = credentialsModel.get_authAddress();

        _authHeaderValue = Base64.getEncoder().encodeToString((
                credentialsModel.get_clientId() + ":" + credentialsModel.get_clientSecret()).getBytes());

        _commonBodyParams = new ArrayList<>();
        _commonBodyParams.add(new BasicNameValuePair("grant_type", "client_credentials"));
        _commonBodyParams.add(new BasicNameValuePair("scope", credentialsModel.get_scope()));
    }

    public BearerToken get_tokenClass() throws NumberFormatException
    {
        if (_bearerToken != null && _bearerToken.get_expires().after(Date.from(Instant.now())))
        {
            return _bearerToken;
        }

        try
        {
            HttpClient httpClient = HttpClients.createDefault();

            HttpPost postRequest = new HttpPost(_authAddress);

            postRequest.setHeader("Accept", "application/json");
            postRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
            postRequest.setHeader("Authorization", "Basic " + _authHeaderValue);

            postRequest.setEntity(new UrlEncodedFormEntity(_commonBodyParams, "UTF-8"));

            HttpResponse response = httpClient.execute(postRequest);
            HttpEntity entity = response.getEntity();

            InputStream responseContent = entity.getContent();

            System.out.println(responseContent.readAllBytes());

            _bearerToken = null; // will be parsed from response
        }
        catch (Exception ex)
        {
            System.err.println("Can't get Bearer token, check credentials and network connection.");
        }

        return _bearerToken;
    }
}


Co znamená „nedostanu se ke kontentu responsy“? Každopádně pokud chcete obsah entity vrátit jako String, slouží k tomu utilitní metoda

Kód: [Vybrat]
String responseString = EntityUtils.toString(entity);

Palecek.x

Pomohlo, no mám zjevně nedostatky.:-) Děkuju.

Ještě bych se zeptal, mám tedy jednoduchý json s třemi hodnotami. Znáte nějaké jednoduché řešení, když si napíšu třídu, abych to do ní mohl deserializovat?

Palecek.x

No, dá se použít např com.fasterxml.jackson.core.

Ten příklad byl jenom pro situace, kdy víte, že vrácený obsah je textový, malý a potřebujete ho jako text, a dál už ho nebudete zpracovávat. Typicky se to hodí pro ladění, když potřebujete vědět, co vám ten server vlastně vrátil. Pokud to chcete parsovat jako JSON, je lepší parseru předat ten InputStream nebo Reader, protože pak může postupně zpracovávat přicházející data.

Pro parsování z JSONu se asi nejčastěji používá právě Jackson. Já osobně dávám přednost JSON-P a případně JSON-B pro bindování na Java Beany – ty knihovny jsou o něco modernější, než Jackson, a staly se součástí Java EE standardu, takže předpokládám, že se budou postupně stávat standardem v ostatních Java knihovnách, které pracují s JSONem.