5
respostas

Manipulação de Header

Boa Noite, Muito show o curso e gostei bastante do retrofit, mas agora estou com uma dificuldade pois eu quero também ter acesso aos parâmetros do header da requisição ao servidor e na resposta também. Vi que quando faz a requisição assincrona nó retrofit eu tenho o acesso ao header de resposta, mas não vi como setar na requisição. Olhando o site do retrofit ele disponibiliza o okHttp para ser usado (Link https://github.com/square/okhttp/wiki/Interceptors) mas estou com dificuldade de fazer o retrofit entender o interceptor. Necessito disso para atender alguns requisitos de segurança.

Att

5 respostas

Boa Noite depois ler com mais calma o link da wiki entendi como vinculo meu interceptor ao retrofit, mas tarde depois depois de testar posto a solução

Oi Robson tudo bem?

Obrigado pelo feedback do curso!

Em relação à visualização do header: O interceptor logging, por meio da configuração Level.BODY, já pega todas as informações da request http, seja envio ou resposta, veja na documentação. Claro, se o que precisa é apenas do header, você pode utilizar apenas o Level.HEADERS que ele vai filtra apenas essa parte da requesição.

Em relação ao envio do header no Retrofit: Nesse primeiro curso não é abordado o envio de header, porém, na parte 3 tem um capítulo que usamos o header. Dando um spoiler sobre o uso do header, basta apenas você utilizar a annotation específica para header. Veha alguns exemplos apresentados na documentação:

  • Para um header único
    @Headers("Cache-Control: max-age=640000")
    @GET("widget/list")
    Call<List<Widget>> widgetList();
  • Para mais de um header
    @Headers({
      "Accept: application/vnd.github.v3.full+json",
      "User-Agent: Retrofit-Sample-App"
    })
    @GET("users/{username}")
    Call<User> getUser(@Path("username") String username);
  • Para enviar header a partir de parâmetros (comum quando queremos mandar uma informação variável)
    @GET("user")
    Call<User> getUser(@Header("Authorization") String authorization)

Acredito que esses passos já tiram suas dúvidas, porém, se tiver mais algum detalhe, é só avisar :)

Abraços.

Olá Alex, Eu li com mais calma sobre o OkHttp é achei a solução para o que eu quero, pois o que desejo era enviar um parâmetro no header da requisição que é 1 token e envia-lo ao servidor para validar. Veja a solição:

public class RetrofitInicializador {
    private final Retrofit retrofit;
    private static final String ENDERECO_SERVIDOR="http://MEU-IP:8080/contexto/web/";
    private LoginDTO loginDTO;

    public RetrofitInicializador(LoginDTO dto) {
        loginDTO = dto;
        retrofit = new Retrofit.Builder().baseUrl(ENDERECO_SERVIDOR).addConverterFactory(GsonConverterFactory.create())
                .client(aplicarInterceptor())
                .build();
    }

    private OkHttpClient aplicarInterceptor(){
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new HeaderInterceptor(loginDTO))
                .build();
        return client;
    }


    public LoginService getLoginService(){
        return retrofit.create(LoginService.class);
    }
}

Na Classe acima é criado a instancia do OKHttpClient e nele é adicionado o interceptor e o retorno e o mesmo é informado ao retrofit. Abaixo segue o Interceptor

public class HeaderInterceptor implements Interceptor {
    private LoginDTO loginDTO;
    private static final String HEADER_AUTORIZACAO="Authorization";
    private static final String TIPO_TOKEN="MeuTOKEN ";
    public HeaderInterceptor(LoginDTO dto) {
        loginDTO=dto;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request requisicao=chain.request();
        Request.Builder construtorRequisicao=requisicao.newBuilder();
        if (loginDTO.getLogin()!=null && loginDTO.getSenha()!=null) {
            construtorRequisicao.addHeader(HEADER_AUTORIZACAO, "Basic " + encripta(loginDTO.getLogin(), loginDTO.getSenha()));
            Log.i("RETROFI-HEAD","BASIC-AUTH");
        }else{
            construtorRequisicao.addHeader(HEADER_AUTORIZACAO,TIPO_TOKEN +loginDTO.getToken());
            Log.i("RETROFI-HEAD","JWT-AUTH");
        }
        Request novaRequisicao=construtorRequisicao.build();
        return chain.proceed(novaRequisicao);
    }

    private String encripta(String username, String password) {
        String userPassword = username + ":" + password;
        String encoding=new String(Base64.encode(userPassword.getBytes()));
        return encoding;
    }

    public static String extratirTokenAutorizacao(Headers headers){
        return headers.get(HEADER_AUTORIZACAO).substring(TIPO_TOKEN.length());
    }
}

Oi Robson, entendi o motivo de você querer usar o interceptor, é apenas para pela questão de criptografia, certo? Se for isso, é realmente por esse caminho mesmo :)

Sim senhor ! :)