我使用a HttpURLConnection来检查服务器URL是否可用,使用以下代码:
try {
boolean connectionFailed = false;
URL knownURL = new URL("http://www.google.com");
httpConnection = (HttpURLConnection) knownURL.openConnection();
httpConnection.setConnectTimeout(5000);
responseCode = httpConnection.getResponseCode();
if (responseCode != 200) {
status = ConnectionStatus.NOT_CONNECTED;
}
}
catch(Exception e) {
connctionFailed = true;
}
Run Code Online (Sandbox Code Playgroud)
此代码在正常条件下正常工作.但是当没有Internet连接时(因为路由器断开连接或者没有热点),httpConnection.getResponseCode()没有执行(函数不返回).我怎样才能解决这个问题?
android web-services httpurlconnection ws-client android-webservice
文档建议使用模拟 Web 服务测试基于 WSClient 的 API 客户端,即创建一个play.server.Server将响应真实 HTTP 请求的客户端。
我更喜欢WSResponse直接从文件创建对象,包括状态行、标题行和正文,没有真正的 TCP 连接。这将需要更少的依赖并运行得更快。也可能有其他情况,这很有用。
但我找不到一个简单的方法来做到这一点。似乎所有包装的实现WSResponse都与从网络读取有关。
我应该为此创建自己的 WSResponse 子类,还是我错了并且它已经存在?
对于Play 2.3.X,非常容易使用WS模块:
WS.url(s"http://$webEndpoint/hand/$handnumber").get()
Run Code Online (Sandbox Code Playgroud)
对于这种简单而直接的用法。
在Play 2.6.x中,根据链接:https : //www.playframework.com/documentation/2.6.x/JavaWS 您需要首先创建一个http客户端。
WSClient customWSClient = play.libs.ws.ahc.AhcWSClient.create(
play.libs.ws.ahc.AhcWSClientConfigFactory.forConfig(
configuration.underlying(),
environment.classLoader()),
null, // no HTTP caching
materializer);
Run Code Online (Sandbox Code Playgroud)
而且,您还需要一个实现器和一个akka系统来支持实现器。
String name = "wsclient";
ActorSystem system = ActorSystem.create(name);
ActorMaterializerSettings settings = ActorMaterializerSettings.create(system);
ActorMaterializer materializer = ActorMaterializer.create(settings, system, name);
// Set up AsyncHttpClient directly from config
AsyncHttpClientConfig asyncHttpClientConfig = new DefaultAsyncHttpClientConfig.Builder()
.setMaxRequestRetry(0)
.setShutdownQuietPeriod(0)
.setShutdownTimeout(0).build();
AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient(asyncHttpClientConfig);
// Set up WSClient instance directly from asynchttpclient.
WSClient client = new AhcWSClient(
asyncHttpClient,
materializer
Run Code Online (Sandbox Code Playgroud)
);
我知道它将为WS客户端添加更多功能,但是当我只想要一个简单的http客户端时,用法变得难以接受,它是如此连接。
我正在使用 Play 的 WSClient 与第三方服务进行交互
request = ws.url(baseUrl)
.post(data)
.map{ response =>
response.json.validate[MyResponseClass]
Run Code Online (Sandbox Code Playgroud)
响应可能是 aMyResponseClass也可能是ErrorResponse类似{ "error": [ { "message": "Error message" } ] }
是否有解析类或错误的典型方法?
我应该做这样的事情吗?
response.json.validateOpt[MyResponseClass].getOrElse(response.json.validateOpt[ErrorClass])
Run Code Online (Sandbox Code Playgroud) 我WSClient用来做休息请求.每个请求都返回一些Future.
结果我需要发出请求1并获取一些数据.然后,我需要做的请求2与请求结果数据1.然后我需要用来自请求2的结果的数据发出请求3.等等
在我的代码中它看起来像
def wsChain(data: Data): Future[NewData] = {
getOne(data).flatMap(data2 => {
getTwo(data2).flatMap(data3 => {
getThree(data3).flatMap(data4 => {
getFour(data4).map(result => foo(result))
})
})
})
}
Run Code Online (Sandbox Code Playgroud)
这是非常原始的样本,没有任何响应和请求的修改.但我认为即使很难阅读.我现在有关Await的Future,但它的反模式
可能我可以做得更漂亮吗?没有N个内部函数.
当创建 Play 框架项目并用于WSClient进行 REST 调用时,官方 Play 框架文档建议添加ws到build.sbt管理依赖项。如果使用 Maven,则 ws 依赖项包含在:
<dependency>
<groupId>com.typesafe.play</groupId>
<artifactId>play-ws_2.12</artifactId>
<version>${play2.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
但是,当尝试使用如下所示的片段调用 Web 服务时:
@Singleton
class Controller @Inject()(
ws: WSClient,
controllerComponents: ControllerComponents
)(implicit ec: ExecutionContext)
extends AbstractController(controllerComponents) {
def callApi(): Action[AnyContent] = Action.async { _ =>
ws
.url("https://mywebservice.com/api/bla")
.get()
.map(response => Ok(response.body.toString))
}
}
Run Code Online (Sandbox Code Playgroud)
然后出现如下错误:
CreationException: Unable to create injector, see the following errors:
1) No implementation for play.api.libs.ws.WSClient was bound.
while locating play.api.libs.ws.WSClient
for the 1st parameter of controllers.MyController.<init>(MyController.scala:13) …Run Code Online (Sandbox Code Playgroud) ws-client ×6
scala ×4
android ×1
future ×1
java ×1
maven ×1
play-json ×1
scala-2.12 ×1
testing ×1
web-services ×1