Trying to show the #Path in #Get in Download Progress in Retrofit - java

Trying to show the #Path in #Get in Download Progress in Retrofit
I wanted to show the passed #Path during progress update using ProgressResponseBody
this is my ProgressListener
public interface ProgressListener {
void update(long bytesRead, long contentLength, boolean done , String param);
}
this is my ProgressResponseBody
public class ProgressResponseBody extends ResponseBody {
private final Response response;
private final ResponseBody responseBody;
private final ProgressListener progressListener;
private BufferedSource bufferedSource;
public ProgressResponseBody(Response response, ProgressListener progressListener) {
this.response = response;
this.responseBody = response.body();
this.progressListener = progressListener;
}
#Override public MediaType contentType() {
return responseBody.contentType();
}
#Override public long contentLength() {
return responseBody.contentLength();
}
#Override public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
#Override public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
// read() returns the number of bytes read, or -1 if this source is exhausted.
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1 , "Dont know how to get it here");
return bytesRead;
}
};
}
}
and this is my Retrofit Library
#Module(
library = true,
complete = false
)
public class RetrofitLibrary {
#Provides
#Singleton
#Named(Constants.MAP_HTTP_CONSTANTS)
public Retrofit provideRetrofitForHttp(#ForApplication Context context , #ForEventBus EventBus mBus){
final OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse, new ProgressListener(){
#Override
public void update(long bytesRead, long contentLength, boolean done, String param) {
// sending data using EventBus here
}
}))
.build();
}
})
.build();
return new Retrofit.Builder()
.baseUrl("URL here")
.client(client)
.build();
}
}
this is my DownloadService
#GET("/someurl/{map_name}.mbtiles")
#Streaming
Call<ResponseBody> downloadMap(#Path("map_name") String map_name );
Now Im wondering if ever this is is going to work, I dont know how to get the #Path specifically map_name.

Related

Java Filter modified response is getting truncated

I have a spring java application that has a EncryptDecryptFilter.java which is a "OncePerRequestFilter" within which I am trying to modify the response payload based on certain conditions. All is going well for happy path.
During the un-happy path, when my application code in the RestController throws an exception, that exception is captured by a #ControllerAdvice class and the controller advice class returns a ResponseEntity. Let's say this response is "string1" with a length 105 characters. After this, the call is intercepted by the "OncePerRequestFilter" and when I attempt to modify the response in this filter with a new response, lets say the modified response is "string2" with a length 200 characters, the modified response string2 is truncated to 105 characters and delievered to the client. So, while the response it self is being modified, the setContentLength() on the response has no effect.
Any suggestions on how to fix this?
See response.setContentLength(encryptedResponse.length()); in the below filter
#Component
public class EncryptDecryptFilter extends OncePerRequestFilter {
public static final Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new GsonExclusionStrategy())
.setPrettyPrinting()
.create();
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String requestURI = request.getRequestURI();
String requestMethod = request.getMethod();
HttpServletRequest requestToUse = new ResettableStreamHttpServletRequest(request);
BufferResponseWrapper responseToUse = new BufferResponseWrapper(response); // declared as a member of this filter class below
interceptRequest(requestToUse, request);
filterChain.doFilter(requestToUse, responseToUse);
interceptResponse(response, responseToUse);
}
private void interceptRequest(HttpServletRequest requestToUse, HttpServletRequest request) throws IOException {
byte[] payload = IOUtils.toByteArray(requestToUse.getReader(), requestToUse.getCharacterEncoding());
String urlEncodedEncryptedBody = new String(payload, requestToUse.getCharacterEncoding());
System.out.println(urlEncodedEncryptedBody);
AesDecryptionRequest decryptionRequest = gson.fromJson(urlEncodedEncryptedBody, AesDecryptionRequest.class);
decryptionRequest.initialize();
String plainTextBody = AesUtil.decrypt(decryptionRequest);
requestToUse.setAttribute("requestBody", plainTextBody);
}
private void interceptResponse(HttpServletResponse response, BufferResponseWrapper responseToUse) throws IOException {
String responseStr = new String(responseToUse.getWrapperBytes());
System.out.println(responseStr); // full response string with length 105 from #ControllerAdvice
AesEncryptionResponse encryptionResponse = AesUtil.encrypt(responseStr);
String encryptedResponse = gson.toJson(encryptionResponse); // encrypted form of #ControllerAdvice response length 200n chars
response.setContentLength(encryptedResponse.length()); // this does not seem to have any effect, the response is still truncated to 105 chars
response.getOutputStream().write(encryptedResponse.getBytes(StandardCharsets.UTF_8));
}
private final class BufferResponseWrapper extends HttpServletResponseWrapper
{
MyServletOutputStream stream = new MyServletOutputStream();
public BufferResponseWrapper(HttpServletResponse httpServletResponse)
{
super(httpServletResponse);
}
public ServletOutputStream getOutputStream() throws IOException
{
return stream;
}
public PrintWriter getWriter() throws IOException
{
return new PrintWriter(stream);
}
public byte[] getWrapperBytes()
{
return stream.getBytes();
}
}
private final class MyServletOutputStream extends ServletOutputStream
{
private ByteArrayOutputStream out = new ByteArrayOutputStream();
public void write(int b) throws IOException
{
out.write(b);
}
public byte[] getBytes()
{
return out.toByteArray();
}
#Override
public boolean isReady() {
return false;
}
#Override
public void setWriteListener(WriteListener writeListener) {
}
}
}
public class ResettableStreamHttpServletRequest extends HttpServletRequestWrapper {
// this class allows the input stream to be read more than once
private static final String UTF_8 = "UTF-8";
private byte[] rawData;
private HttpServletRequest request;
private ResettableServletInputStream servletStream;
public ResettableStreamHttpServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
this.servletStream = new ResettableServletInputStream();
}
public void resetInputStream() {
servletStream.stream = new ByteArrayInputStream(rawData);
}
public void resetInputStream(byte[] newRawData) {
servletStream.stream = new ByteArrayInputStream(newRawData);
}
#Override
public ServletInputStream getInputStream() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getReader(), UTF_8);
servletStream.stream = new ByteArrayInputStream(rawData);
}
return servletStream;
}
#Override
public BufferedReader getReader() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getReader(), UTF_8);
servletStream.stream = new ByteArrayInputStream(rawData);
}
return new BufferedReader(new InputStreamReader(servletStream, UTF_8));
}
private class ResettableServletInputStream extends ServletInputStream {
private ByteArrayInputStream stream;
#Override
public int read() throws IOException {
return stream.read();
}
#Override
// Returns true when all the data from the stream has been read else it returns false.
public boolean isFinished() {
return stream.available() == 0;
}
#Override
// Returns true if data can be read without blocking else returns false.
public boolean isReady() {
return true;
}
#Override
public void setReadListener(ReadListener listener) {
throw new RuntimeException("Not implemented");
}
}
}
Controller Advice class
#ControllerAdvice
public class ExceptionAdvice extends ResponseEntityExceptionHandler {
#ExceptionHandler(value = {Exception.class})
protected ResponseEntity<Object> handleException(Exception exception, WebRequest request) {
return handleExceptionInternal(exception, exception.getMessage(), getStandardHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request);
}
}
Try using .reset() method on response object before you rewrite it.
private void interceptResponse(HttpServletResponse response, BufferResponseWrapper responseToUse) throws IOException {
String responseStr = new String(responseToUse.getWrapperBytes());
System.out.println(responseStr); // full response string with length 105 from #ControllerAdvice
AesEncryptionResponse encryptionResponse = AesUtil.encrypt(responseStr);
String encryptedResponse = gson.toJson(encryptionResponse); // encrypted form of #ControllerAdvice response length 200n chars
response.reset(); <-------------
response.setContentLength(encryptedResponse.length()); // this does not seem to have any effect, the response is still truncated to 105 chars
response.getOutputStream().write(encryptedResponse.getBytes(StandardCharsets.UTF_8));
}
According to the doc
void reset() Clears any data that exists in the buffer as well as the
status code and headers. If the response has been committed, this
method throws an IllegalStateException.
Throws: IllegalStateException
if the response has already been committed

How to fix Expected BEGIN_OBJECT but was STRING in Retrofit? [duplicate]

This question already has an answer here:
How to fix Expected BEGIN_OBJECT in Retrofit?
(1 answer)
Closed 4 years ago.
In my application i want use Retrofit for get some data from server.
I write below codes but when run application and call api show me below error :
E/socketLogResponse: Err : com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
Please see my above codes and help me
API response from server :
{
"status": "ok",
"time": 0.014972925186157227
}
ApiService interface :
#POST("api/log")
Call<SocketPingResponse> getSocketPingLog(#Header("jwt") String jwt, #Body SocketPingBodySendData socketPingBodySendData);
SocketPingResponse class :
public class SocketPingResponse {
#SerializedName("status")
#Expose
private String status;
#SerializedName("time")
#Expose
private Double time;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Double getTime() {
return time;
}
public void setTime(Double time) {
this.time = time;
}
}
SocketPingBodySendData class :
public class SocketPingBodySendData {
#SerializedName("auction_id")
#Expose
int auction_id;
#SerializedName("data")
#Expose
List<SocketPingEntity> data;
public int getAuction_id() {
return auction_id;
}
public void setAuction_id(int auction_id) {
this.auction_id = auction_id;
}
public List<SocketPingEntity> getData() {
return data;
}
public void setData(List<SocketPingEntity> data) {
this.data = data;
}
}
Api call codes in activity :
pingEntityList.addAll(socketPingDatabase.socketPingDao().getSocketPingEntityList());
SocketPingBodySendData pingBodySendData = new SocketPingBodySendData();
pingBodySendData.setAuction_id(auctionID);
pingBodySendData.setData(pingEntityList);
Toast.makeText(context, ""+pingEntityList.size(), Toast.LENGTH_SHORT).show();
Call<SocketPingResponse> pingResponseCall = apis.getSocketPingLog(jwtToken, pingBodySendData);
pingResponseCall.enqueue(new Callback<SocketPingResponse>() {
#Override
public void onResponse(Call<SocketPingResponse> call, Response<SocketPingResponse> response) {
if (response.body() != null) {
Toast.makeText(context, response.body().getStatus(), Toast.LENGTH_SHORT).show();
if (response.body().getStatus().equals("ok")) {
pingEntityList.clear();
socketPingDatabase.socketPingDao().deleteAll();
}
}
}
#Override
public void onFailure(Call<SocketPingResponse> call, Throwable t) {
Log.e("socketLogResponse", "Err : " + t.toString());
}
});
ApiClient class :
public class ApiClient {
private static final String BASE_URL = Constants.SERVER;
private static Retrofit retrofit = null;
private static Context context;
public static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.interceptors().add(interceptor);
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("X-Client-Version", Constants.getAppVersionName()).build();
return chain.proceed(request);
}
});
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("uuid", Constants.getUUID(Constants.currentActivity)).build();
return chain.proceed(request);
}
});
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("agent", Constants.getAgent()).build();
return chain.proceed(request);
}
});
OkHttpClient client2 = client
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client2)
.build();
}
return retrofit;
}
}
How can i fix this issue?
I think the problem returns string when no data is returned. Backend can usually do such errors. this error had happened to me before. you should check the response json when no data is available
Retrofit is typesafe library. It means that it waits only particular (predefined) types of objects. If server sends something else - it crashes with error. This is your case. Just check raw server response and you'll see what's wrong.
Try changing your API call
from
#POST("api/log")
Call<SocketPingResponse> getSocketPingLog(#Header("jwt") String jwt, #Body SocketPingBodySendData socketPingBodySendData);
to
#POST("api/log")
Call<String> getSocketPingLog(#Header("jwt") String jwt, #Body SocketPingBodySendData socketPingBodySendData);
pingEntityList.addAll(socketPingDatabase.socketPingDao().getSocketPingEntityList());
SocketPingBodySendData pingBodySendData = new SocketPingBodySendData();
pingBodySendData.setAuction_id(auctionID);
pingBodySendData.setData(pingEntityList);
Toast.makeText(context, ""+pingEntityList.size(), Toast.LENGTH_SHORT).show();
Call<String> pingResponseCall = apis.getSocketPingLog(jwtToken, pingBodySendData);
pingResponseCall.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.body() != null) {
//Convert here your string response to Other POJO format
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.e("socketLogResponse", "Err : " + t.toString());
}
});

How to save Retrofit 2 response into SharedPreferences

I have a retrofit 2 response by which i gets data from server. my code is working fine.
But i want cache this response using SharedPreferences and keep it till that activity is running and after activity is destroyed. i want to delete this response from SharedPreferences.
This is my Code:
public class SampleClass {
private DataInterface mListener;
public SampleClass() {
super();
}
public void getDataForId(final String id) {
ApiInterface apiInterface = APIClient.getApiInterface();
Call<MyResponse> call = apiInterface.getResponse();
call.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (response!=null && response.body() != null && mListener != null) {
mListener.responseData(response.body());
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
}
});
}
public void setOnDataListener(DataInterface listener) {
mListener = listener;
}
public interface DataInterface {
void responseData( MyResponse myResponse );
}
}
SecondData class file
sampleClass.setOnDataListener(new SampleClass.DataInterface() {
#Override
public void responseData(MyResponse myResponse) {
// i wanna store this response into SharedPreferences for temp and delete after activity is destroyed.
List<Detail> details = myResponse.getDetails();
for (Detail d : details) {
if (d.getId().equals(id)) {
reqDetail = d;
name.setText(reqDetail.getName());
Picasso.with(SecondData.this)
.load(reqDetail.getName())
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(image);
}
}
}
});
ApiInterface
public interface ApiInterfaceNew {
#GET("/display.php")
Call<MyResponse> getResponse();//imp to include MyResponse as a call
}
Api class
private static final String ROOT_URL = "";
private static Retrofit retrofit1 = null;
private static final String CACHE_CONTROL = "Cache-Control";
public static Retrofit getClient() {
if (retrofit1 == null) {
retrofit1 = new Retrofit.Builder()
.baseUrl(ROOT_URL)
.client(provideOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit1;
}
public static ApiInterfaceNew getApiInterface() {
return getClient().create(ApiInterfaceNew.class);
}
private static OkHttpClient provideOkHttpClient() {
return new OkHttpClient.Builder()
.addInterceptor(provideHttpLoggingInterceptor())
.addInterceptor(provideOfflineCacheInterceptor())
.addNetworkInterceptor(provideCacheInterceptor())
.cache(provideCache())
.build();
}
private static Cache provideCache() {
Cache cache = null;
try {
cache = new Cache(new File(AppControler.getInstance().getCacheDir(), "http-cache"),
10 * 1024 * 1024); // 10 MB
} catch (Exception e) {
Timber.e("Could not create Cache!");
}
return cache;
}
private static HttpLoggingInterceptor provideHttpLoggingInterceptor() {
HttpLoggingInterceptor httpLoggingInterceptor =
new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
Timber.e(message);
}
});
httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? HEADERS : NONE);
return httpLoggingInterceptor;
}
public static Interceptor provideCacheInterceptor() {
return new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// re-write response header to force use of cache
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(2, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl.toString())
.build();
}
};
}
public static Interceptor provideOfflineCacheInterceptor() {
return new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!AppControler.hasNetwork()) {
CacheControl cacheControl = new CacheControl.Builder()
.maxStale(7, TimeUnit.DAYS)
.build();
request = request.newBuilder()
.cacheControl(cacheControl)
.build();
}
return chain.proceed(request);
}
};
}
AppControler class
public class AppControler extends Application {
private static AppControler instance;
#Override
public void onCreate()
{
super.onCreate();
instance = this;
if (BuildConfig.DEBUG)
{
Timber.plant(new Timber.DebugTree());
}
Timber.i("Creating our Application");
}
public static AppControler getInstance ()
{
return instance;
}
public static boolean hasNetwork ()
{
return instance.checkIfHasNetwork();
}
public boolean checkIfHasNetwork()
{
ConnectivityManager cm = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
Add below code in your Retrofit response when a response is success.
First convert JSON to string and store.
Gson gson = new Gson();
String favData = gson.toJson(response.body());
save strings to prefrance.
preferenceManager is my SharedPref class
preferenceManager.setStringPreference(Global.OFFLINE_WORD, favData);
now when you want to get pref data call below method.
public ArrayList<MyResponse> getData(String key) {
String data = getStringPreference(key);
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<MyResponse>>() {
}.getType();
return gson.fromJson(data, type);
}
You can use either ObjectMapper or Gson.
For ObjectMapper you can refer the below code
public static void updateUserInfo(UserInfo userInfo, Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Crashlytics.log("updating User Info "+(userInfo!=null?userInfo.toString():"UserInfo is null"));
final SharedPreferences.Editor edit = preferences.edit();
ObjectMapper objectMapper = new ObjectMapper();
try {
String value = objectMapper.writeValueAsString(userInfo);
edit.putString("USER_INFO_MODEL", value);
edit.commit();
} catch (JsonProcessingException e) {
Exceptions.propagate(e);
}
}
you can also get the stored response from shared preferences
public static UserInfo getUserInfo(Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String userDetatails = preferences.getString(AppConstants.USER_INFO_MODEL, "");
Crashlytics.log("get UserInfo "+userDetatails);
ObjectMapper mapper = new ObjectMapper();
if (StringUtils.isEmpty(userDetatails)) {
return null;
}
UserInfo userInfo = null;
try {
userInfo = mapper.readValue(userDetatails, UserInfo.class);
} catch (IOException e) {
Exceptions.propagate(e);
}
return userInfo;
}

"OkHttpClient cannot be converted to MyOkHttpClient"

Why wont this compile:
MyOkHttpClient okClient = new MyOkHttpClient.Builder()
.addInterceptor(new AddCookiesInterceptor())
.addInterceptor(new ReceivedCookiesInterceptor()).build();
Incompatible types.
Required:
my.path.util.auth.MyOkHttpClient
Found:
okhttp3.OkHttpClient
This is MY class:
public class MyOkHttpClient extends okhttp3.OkHttpClient implements Authenticator {
private static int MAX_AUTHENTICATE_TRIES = 3;
#Override
public Request authenticate(Route route, Response response) throws IOException {
if (responseCount(response) >= MAX_AUTHENTICATE_TRIES) {
return null; // If we've failed 3 times, give up. - in real life, never give up!!
}
String credential = Credentials.basic(AUTHTOKEN_USERNAME, AUTHTOKEN_PASSWORD);
return response.request().newBuilder().header("Authorization", credential).build();
}
private int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
}
Based on your comments, you incorrectly believe that you are decorating OkHttpClient with custom authentication logic.
Instead, you are unnecessarily extending OkHttpClient and implementing the Authenticator interface. You can simply build the standard OkHttpClient with any custom authenticator you would like.
As such, this is more like what you actually want
public class MyAuthenticator implements Authenticator {
private static int MAX_AUTHENTICATE_TRIES = 3;
#Override
public Request authenticate(Route route, Response response) throws IOException {
if (responseCount(response) >= MAX_AUTHENTICATE_TRIES) {
return null; // If we've failed 3 times, give up. - in real life, never give up!!
}
String credential = Credentials.basic(AUTHTOKEN_USERNAME, AUTHTOKEN_PASSWORD);
return response.request().newBuilder().header("Authorization", credential).build();
}
private int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
}
And then when you build your client
OkHttpClient okClient = new OkHttpClient.Builder()
.addInterceptor(new AddCookiesInterceptor())
.addInterceptor(new ReceivedCookiesInterceptor())
.authenticator(new MyAuthenticator())
.build();

Retrofit2 How to get redirect url #HEAD("/")

I have a minified URL and I want to have the final URL
With Retrofit 1.9 I used to do this :
#HEAD("/XXXXXXXXX")
void fetchFinalUrl(Callback<String> cb);
public void getUrl() {
mMinifyService.fetchFinalUrl(new Callback<String>() {
#Override
public void success(String s, Response response) {
response.getUrl();
}
[...]
}
But now with Retrofit 2 .getUrl() not exist any ideas how to do this?
Thanks in advance.
EDIT
Finally got it!
public class ApiProvider<T> {
private Retrofit retrofit;
private static final String END_POINT_MINIFY = "XXXXXXX";
public ApiProvider() {
initAdapter();
}
public T getService(Class<T> service) {
return retrofit.create(service);
}
private void initAdapter() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.followRedirects(false)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(END_POINT_MINIFY)
.addConverterFactory(new ToStringConverterFactory())
.client(client)
.build();
}
}
public interface IMinifyService {
#HEAD("/XXXXXXXXX")
Call<Void> fetchFinalUrl(Callback<String> cb);
}
public class MinifyServiceImpl {
private ApiProvider<IMinifyService> mApiProvider = new ApiProvider<>();
private IMinifyService mMinifyService = mApiProvider.getService(IMinifyService.class);
public Promiser<String, Integer> fetchMinifyUrl() {
return new Promiser<>((resolve, reject) -> mMinifyService.fetchMinifyUrl().enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Void> call, Response<Void> response) {
if (response.code() >= 300 && response.code() < 400){
resole.run(response.headers().get("Location"));
} else {
reject.run(response.code());
}
}
#Override
public void onFailure(Call<Void> call, Throwable t) {
reject.run(t.hashCode());
}
}));
}
}
if you want to use Promizer --> Click here
response.raw().request().url()

Categories

Resources