gpt4 book ai didi

android - 改造忽略查询参数

转载 作者:行者123 更新时间:2023-11-29 19:15:55 31 4
gpt4 key购买 nike

我正在尝试使用 Retrofit 和 Gson 解析 JSON 文件。问题在于 URL 接受参数 forceDeviceId。如果此值设置为 -111,则可以检索正确的文件。默认情况下,此参数设置为 -1 并抛出 404 错误:

不工作 https://www.mediamarkt.de/de/product/productlistajax.json?categoryId=563612&sort=topseller&lazyLoading=true&forceDeviceId=-1

工作 https://www.mediamarkt.de/de/product/productlistajax.json?categoryId=563612&sort=topseller&lazyLoading=true&forceDeviceId=-111

我尝试了两种方法:在 API url 中硬编码参数并使用查询:

// either hardcoded in the URL
@GET("de/product/productlistajax.json?forceDeviceId=-111")
Call<ProductListParent> loadProductList(
@Query("categoryId") String categoryId,
@Query("sort") String sort,
@Query("lazyLoading") String lazyLoading,
// alternatively use this query
@Query("forceDeviceId") String forceDeviceId
);

但是这两种方法都返回 404。所以我想知道我缺少什么让它工作(就像在浏览器中一样)。我还认识到,在加载浏览器中的 URL 后,该参数会立即被删除。那么这是他们的后端阻止的事情吗?

这是我调用的方法:

  @Subscribe
public void getProductListRequest(MMSATServices.ProductListRequest request) {
final MMSATServices.ProductListResponse productListResponse = new MMSATServices.ProductListResponse();
productListResponse.productListParent = new ProductListParent();

Call<ProductListParent> call = liveApi.loadProductList(
request.categoryId, request.sort, request.lazyLoading, request.forceDeviceId);
call.enqueue(new Callback<ProductListParent>() {
@Override
public void onResponse(Call<ProductListParent> call, Response<ProductListParent> response) {
productListResponse.productListParent = response.body();
bus.post(productListResponse);
}

@Override
public void onFailure(Call<ProductListParent> call, Throwable t) {
t.printStackTrace();
}
});
}

这是我收到的错误信息:

Response{protocol=http/1.1, code=404, message=Not Found, url=https://www.mediamarkt.de/de/product/productlistajax.json?categoryId=563612&sort=topseller&lazyLoading=true}

编辑:这是我创建 Retrofit 对象的方式

private static Retrofit createMMSATService(String baseUrl) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.cookieJar(new CustomCookieJar())
.build();

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();

return retrofit;
}

使用 CustomCookieJAr 类:

public class CustomCookieJar implements CookieJar {

private List<Cookie> cookies = new ArrayList<>();

@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
if (cookies != null) {
this.cookies = cookies;
}
}

@Override
public List<Cookie> loadForRequest(HttpUrl url) {
return cookies;
}
}

最佳答案

执行此请求时会附加 2 件事,首先您会收到 302 响应,然后 OkHTTP 在 302 请求提供的新位置执行请求。第二个请求失败并返回 404 响应。我发现 302 响应的 header 中有 2 个新 cookie:MC_DEVICE_IDMC_DEVICE_ID_EXT。所以我配置了 OkHTTP(Retrofit 使用的请求引擎)将 302 响应中收到的 cookie 发送到第二个请求并且它有效!

这就是它在网络浏览器中工作的原因,因为网络浏览器会存储返回的 cookie 并在第二次请求时再次发送它。 OkHTTP 默认没有这种机制,你必须在新请求中手动设置 302 响应中的 cookie。

这是我的代码:

 Retrofit retrofit = new Retrofit.Builder()
.client(new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
private List<Cookie> cookies = new ArrayList<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
if (cookies != null) {
this.cookies = cookies;
}
}

@Override
public List<Cookie> loadForRequest(HttpUrl url) {
return cookies;
}
}).build())
.baseUrl("https://www.mediamarkt.de/")
.build()

上一个答案

即使我正在调试,Retrofit/OkHTTP 堆栈跟踪也很难解码,但据我所知,url https://www.mediamarkt.de/de/product/productlistajax.json ?categoryId=563612&sort=topseller&lazyLoading=true&forceDeviceId=-111 返回 302 http 代码(暂时移动)并在响应 header 中返回新地址。

问题是 header location 提供的 url 不包含查询参数 forceDeviceId。这是 mediamarkt API 的错误,我建议您向 mediamarkt 开发人员报告此错误,并暂时找到其他方式发送此参数(我帮不上忙,我不懂德语)。

一些细节:

第一次调用返回 302 的响应:响应{protocol=http/1.1, code=302, message=Found, url=https://www.mediamarkt.de/de/product/productlistajax.json?forceDeviceId=-111&categoryId=563612&sort=topseller&lazyLoading=true}

OkHTTP 通过调用这个获取新位置:

String location = userResponse.header("Location");

(参见此处 RetryAndFollowUpInterceptor.java:301)

location 的值为 /de/product/productlistajax.json?categoryId=563612&sort=topseller&lazyLoading=true。如您所见,缺少参数 forceDeviceId :/

关于android - 改造忽略查询参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43514800/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com