troyzhxu / okhttps Goto Github PK
View Code? Open in Web Editor NEW如艺术一般优雅,像 1、2、3 一样简单,前后端通用,轻量却强大的 HTTP 客户端(同时支持 WebSocket 与 Stomp 协议)
Home Page: https://ok.zhxu.cn
License: Apache License 2.0
如艺术一般优雅,像 1、2、3 一样简单,前后端通用,轻量却强大的 HTTP 客户端(同时支持 WebSocket 与 Stomp 协议)
Home Page: https://ok.zhxu.cn
License: Apache License 2.0
在进行网络请求的时候报错,
com.ejlchina.okhttps.ConvertProvider: module okhttps does not declare 'uses'
Describe the bug
服务器正常应返回json,但是异常情况下返回html,exceptionListener 和 setOnException不会走直接崩溃
com.ejlchina.okhttps.internal.HttpException: 转换失败
Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
To Reproduce
这样用的
http = HTTP.builder()
.addMsgConvertor(new GsonMsgConvertor())
.baseUrl(Constant.getApiBaseUrl())
.exceptionListener((HttpTask<?> task, IOException error) -> {
error.printStackTrace();
return true;
})
.build();
try{
http.async(Constant.LOGIN_SUFFIX)
.bodyType("json")
.setBodyPara(user)
.setOnResBean(new TypeRef<BaseResp<LoginResp>>() {}, result -> {
callback.onResponse(result);
})
.setOnException(ex ->{
callback.onFail(ex);
})
.post();
}catch (Exception e){
e.printStackTrace();
}
Expected behavior
期望 json转换异常也会在onexception抛出.
Smartphone (please complete the following information):
每次都是在Stomp连接成功的回调里面开始订阅,订阅之前会执行一次取消订阅方法,但是有时候过了很久APP会奔溃报上述异常;
还有登录成功或者打开首页都会执行Stomp的连接方法导致同时可能发起多个连接请求;只通过stomp.isConnected()判断也不可靠,因为有时候真在连接中
//设置监听
stomp.setOnConnected(new OnCallback() {
@OverRide
public void on(Stomp data) {
// 服务器连接成功回调
Log.i("Stomp", "OnConnected");
//开始订阅消息
subscribe();
}
});
//取消订阅
stomp.unsubscribe(destination);
//订阅
stomp.subscribe(destination,null,(com.ejlchina.stomp.Message msg) -> {
}
支持类似spring-retry的请求失败重试吗?
如:请求timeout时,可自动重试几次。
目前使用上传功能的时候boundary不能自定义。无法模拟浏览器上传方式。
stomp unsubscribe和subscribe出现
java.lang.IllegalStateException: The destination [/user/00f6d11e26-d49a-40e4-b39d-6bf2742ee8dc/message] has already been subscribed
直接崩溃,希望提供函数来处理IllegalStateException
E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: com.dppdkai.luckypandemo, PID: 10154
com.ejlchina.okhttps.internal.HttpException: WebSockt 连接异常: ws://myphp.com
at com.ejlchina.okhttps.internal.WebSocketTask$MessageListener.onFailure(WebSocketTask.java:278)
at okhttp3.internal.ws.RealWebSocket.failWebSocket(RealWebSocket.java:570)
at okhttp3.internal.ws.RealWebSocket$1.onResponse(RealWebSocket.java:199)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:929)
Caused by: java.net.ProtocolException: Expected HTTP 101 response but was '200 OK'
at okhttp3.internal.ws.RealWebSocket.checkUpgradeSuccess(RealWebSocket.java:224)
at okhttp3.internal.ws.RealWebSocket$1.onResponse(RealWebSocket.java:195)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:929)
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
若我设置了baseurl,后期无需其他参数的时候,总是需要在.sync(""),虽然可以将整个请求方案设为util,但我总觉得这不是一个好的办法。
如题,假如需求要求同时发送大量http请求,单用OkHttps或HttpUtils工具类去执行,是否可行?要不要考虑用connectionpool?
.callbackExecutor((Runnable run) -> {
new Handler(Looper.getMainLooper()).post(run);
})
配置这个以后,进行网络请求会报NetworkOnMainThreadException异常
请问下 OkHttps.sync 该用法怎么配置proxy 代理地址和端口?
最近遇到一个问题 就是 一个URL 多次重定向,我该如何很方便的 取出 头中的重定向网址和 cookies
看到依赖的还是okhttp3,版本3.14.9。
为什么不用okhttp4呢?
在activity界面初始化连接stomp activity destory调用的disconnect之后回到首页 断网之后还能收到setOnException里面的回调 disconnect没有销毁websocket吗
stomp.topic("/your-topic", (Message msg)
订阅收到数据后,我的Message是多条消息,请问这个该如何解析?
10-25 12:36:18.967 7197-7215/? E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: com.dppdkai.luckypandemo, PID: 7197
com.ejlchina.okhttps.internal.HttpException: WebSockt 连接异常: ws://127.0.0.1/aka/dserver
at com.ejlchina.okhttps.internal.WebSocketTask$MessageListener.onFailure(WebSocketTask.java:278)
at okhttp3.internal.ws.RealWebSocket.failWebSocket(RealWebSocket.java:570)
at okhttp3.internal.ws.RealWebSocket$1.onResponse(RealWebSocket.java:199)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.net.ProtocolException: Expected HTTP 101 response but was '403 Forbidden'
at okhttp3.internal.ws.RealWebSocket.checkUpgradeSuccess(RealWebSocket.java:224)
at okhttp3.internal.ws.RealWebSocket$1.onResponse(RealWebSocket.java:195)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
环境okhttps 最新版
java8
windows11
Describe the bug
Exception in thread "main" com.ejlchina.okhttps.internal.HttpException: 没有匹配[json]类型的转换器!
at com.ejlchina.okhttps.internal.TaskExecutor.doMsgConvert(TaskExecutor.java:145)
at com.ejlchina.okhttps.HttpTask.toRequestBody(HttpTask.java:699)
at com.ejlchina.okhttps.HttpTask.buildRequestBody(HttpTask.java:689)
at com.ejlchina.okhttps.HttpTask.prepareRequest(HttpTask.java:596)
at com.ejlchina.okhttps.HttpTask.prepareCall(HttpTask.java:585)
at com.ejlchina.okhttps.internal.AsyncHttpTask.lambda$request$0(AsyncHttpTask.java:263)
at com.ejlchina.okhttps.internal.HttpClient.preprocess(HttpClient.java:184)
at com.ejlchina.okhttps.internal.AsyncHttpTask.request(AsyncHttpTask.java:255)
at com.ejlchina.okhttps.internal.AsyncHttpTask.post(AsyncHttpTask.java:217)
at com.hellosouth.file_transfer.utils.OkHttpUtils.main(OkHttpUtils.java:231)
To Reproduce
Map<String, Object> map = new HashMap<>();
map.put("uploadId", "uploadId");
// map.put("base64",base64);
map.put("total", 10);
map.put("current", 2);
HTTP http = HTTP.builder().bodyType(OkHttps.JSON).build();
http.async(UPLOAD_URL)
.bodyType(OkHttps.JSON)
.addBodyPara(map)
// .setBodyPara(map)
.setOnException((IOException e) -> {
// 异常回调
e.printStackTrace();
})
.setOnResponse((HttpResult res) -> {
// 响应回调
int status = res.getStatus(); // 状态码
Headers headers = res.getHeaders(); // 响应头
HttpResult.Body body = res.getBody(); // 报文体
System.out.println(body);
})
.post();
<!-- okhttps -->
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps</artifactId>
<version>2.4.2</version>
</dependency>
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
很多人估计都不知道application/json需要单独设置
WebSocketTask webSocketTask = OkHttps.webSocket(UrlConfig.WS_STOMP);
stomp = Stomp.over(webSocketTask);
这么没有api可以获取到OkHttps中的http来设置sslSocketFactory
public static WebSocketTask webSocket(String url) {
return getHttp().webSocket(url);
}
static synchronized HTTP getHttp() {
if (http != null) {
return http;
}
HTTP.Builder builder = HTTP.builder();
ConvertProvider.inject(builder);
Config.config(builder);
http = builder.build();
return http;
}
我需要Https中的http对象
http .config(b -> {
b.sslSocketFactory(mySSLSocketFactory, myTrustManager);
b.hostnameVerifier(myHostnameVerifier);
})
com.ejlchina.okhttps.internal.WebSocketTask
private void schedulePing() {
if (!isConnected()) {
return;
}
int delay = (int) (pingSeconds + lastPingSecs - nowSeconds());
httpClient.executor.requireScheduler().schedule(() -> {
if (!isConnected()) {
return;
}
WebSocket ws = webSocket;
if (nowSeconds() - lastPingSecs >= pingSeconds && ws != null) {
ByteString ping = pingSupplier != null ? pingSupplier.getPing() : ByteString.EMPTY;
ws.send(ping);
lastPingSecs = nowSeconds();
}
schedulePing();
}, delay, TimeUnit.SECONDS);
}
/**
* 检测服务器的心跳响应
*/
private void schedulePong() {
if (!isConnected()) {
return;
}
int delay = (int) (pongSeconds + lastPongSecs - nowSeconds());
httpClient.executor.requireScheduler().schedule(() -> {
if (!isConnected()) {
return;
}
long noPongSeconds = nowSeconds() - lastPongSecs;
if (noPongSeconds > 3L * pongSeconds) {
WebSocketImpl ws = webSocket;
if (ws != null) {
Exception e = new SocketTimeoutException("Server didn't pong heart-beat on time. Last received at " + noPongSeconds + " seconds ago.");
((RealWebSocket) ws.webSocket).failWebSocket(e, null);
}
} else {
schedulePong();
}
}, delay, TimeUnit.SECONDS);
}
如代码中所示,两个心跳检测中,判断与服务器连接断开!isConnected()后,直接return,此处是否应该抛出异常或触发onDisconnected回调。
com.ejlchina.okhttps.internal.HttpException: WebSockt 连接异常: ws://192.168.101.233:10002/api/ws/websocket
at com.ejlchina.okhttps.internal.WebSocketTask$MessageListener.onFailure(WebSocketTask.java:252)
at okhttp3.internal.ws.RealWebSocket.failWebSocket(RealWebSocket.java:570)
at okhttp3.internal.ws.RealWebSocket$1.onFailure(RealWebSocket.java:216)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:180)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:776)
Caused by: java.net.ConnectException: Failed to connect to /192.168.101.233:10002
.setOnException {
if (!this.isDestroyed) {
Log.e("cxp", "error:${it.message}")
mStomp.connect()
}
}
并且在异常中重新connect 无效
Describe the bug
服务端主动断开连接, Stomp中状态未能刷新, 扔是已连接状态
主要原因在 okhttp3.internal.ws.RealWebSocket 中 536行 未能进入条件执行listener.onClosed方法
因为多处判断isConnected==false 就去重新发起连接请求,有时候会出现多个连接都在请求中的情况
如果在无web服务(mvc)中不能使用
那在mvc里又有controller getmapping作为回调接口 感觉有点多余
不知道是不是我理解有偏差
Describe the bug
STOMP 重连时, 服务器关闭状态下在次调用stomp.connect()时, WebSocket status 任然是 STATUS_CONNECTING.
主要原因在WHttpTask.onFailure中未能重置WebSocket状态
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
形如以下代码:
OkHttps.sync("http://xxxxx")
.bodyType(OkHttps.JSON)
.post();
期望发出的 Content-Type
是 application/json
,但实际发出的却是 application/x-www-form-urlencoded
即:
所有应该有报文体,但没有添加 bodyPara 的请求,都会默认以空表单的形式提交。
当前的可行的避免方案有:
OkHttps.sync("http://xxxxx")
.bodyType(OkHttps.JSON)
.addBodyPara(null) // 添加一个 空 报文体参数
.post();
No deadline
okio.Timeout.deadlineNanoTime(Timeout.kt:74)
目前我的操作是在连接成功的回调里面订阅某个主题 新版本断开重连后又会走到连接成功的回调导致报错不能重复订阅
请问,TypeRef的T如何动态指定Class呢?
就是包装了一个方法,传入一个Class类型,然后TypeRef根据这个类型来反序列化json
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.