以下是该方案。
我正在使用Play框架。在给定的处理程序内,play框架调用我的API webservice并将API响应返回给客户端。客户端通过Ajax调用调用处理程序。有时响应很好,但我常常看到客户端的错误响应。检查播放框架的日志,我看到java.nio.channels.ClosedChannelException。
我正在使用Play 2.1.1。 我的API Webservice在localhost:8888上运行。 Play框架在9000上运行。 API服务响应是正确的。 Play框架也正确执行Callback,因为我可以看到日志。从Play发出ok()调用后发生错误。
以下是失败请求的错误日志 -
[debug] application - find...
[debug] application - id = 647110558
[trace] c.jolbox.bonecp - Check out connection [9 leased]
[trace] c.jolbox.bonecp - Check in connection [9 leased]
[debug] application - socialUser = SocialUser(UserId(647110558,facebook),Arvind,Batra,Arvind Batra,Some(arvindbatra@gmail.com),null,AuthenticationMethod(oauth2),null,Some(OAuth2Info(CAAHNVOUuNZAEBAMa3CPLUEsZA2Tp5xWGXylO9HggBY0TCfwsIn4iGUdlRMpuNPLxYcObKO5ZBZCU0ghS9ymHZC3s9YXpsfPix9AM1EhNyETvDR85HHYg8j7JO0h2WzGZBsKJdbFPhPmkD6ZBZAq6KTT8RLSQrmpfnHQZD,null,null,null)),null)
[info] application - Calling interest for fff
[info] application - user is not null
[trace] c.jolbox.bonecp - Check out connection [9 leased]
[info] application - interest=fff, userInfo:models.EBUser@14a420e1
[info] application - http://localhost:8888/api/add_interest/1/fff
[debug] c.n.h.c.p.n.NettyAsyncHttpProvider - Using cached Channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
for uri http://localhost:8888/api/add_interest/1/fff
[debug] c.n.h.c.p.n.NettyAsyncHttpProvider -
Using cached Channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
for request
DefaultHttpRequest(chunked: false)
GET /api/add_interest/1/fff HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept: */* User-Agent: NING/1.0
[debug] c.n.h.c.p.n.NettyAsyncHttpProvider -
Request DefaultHttpRequest(chunked: false)
GET /api/add_interest/1/fff HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept: */*
User-Agent: NING/1.0
Response DefaultHttpResponse(chunked: true)
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Thu, 04 Jul 2013 12:14:40 GMT
Transfer-Encoding: chunked
[debug] c.n.h.c.p.n.NettyConnectionsPool - Adding uri: http://localhost:8888 for channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
[info] application - {"status":"success"}
[info] application - {"status":"ok","exists":false}
[trace] play - Sending simple result: SimpleResult(200, Map(Content-Type -> application/json; charset=utf-8, Set-Cookie -> ))
[debug] play - java.nio.channels.ClosedChannelException
[trace] application - Exception caught in Netty
java.nio.channels.ClosedChannelException: null
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:409) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:127) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:99) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:36) ~[netty.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:725) ~[netty.jar:na]
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.doEncode(OneToOneEncoder.java:71) ~[netty.jar:na]
[debug] c.n.h.c.p.n.NettyConnectionsPool - Entry count for : http://localhost:8888 : 2
这是我的示例代码 -
public static Result addInterestCallback(WS.Response response) {
if (response == null) {
return badRequest();
}
ObjectNode result = (ObjectNode) response.asJson();
try {
Logger.info(result.toString());
if (result.has("status")) {
String status = result.get("status").getTextValue();
if(status.equals("error")) {
result.put("error", "Oops, cannot process your request. Sorry.");
Logger.info("error");
return badRequest(result);
}
else if(status.equals("exists")) {
result.put("exists",true);
}
else {
result.put("exists",false);
}
result.put("status", "ok");
} else {
//do something
Logger.info("result has no status");
}
Logger.info(result.toString());
} catch (Exception e) {
e.printStackTrace();
}
return ok(result);
}
@BodyParser.Of(BodyParser.Json.class)
@SecureSocial.UserAwareAction
public static Result addInterest() {
JsonNode json = request().body().asJson();
String interestName = json.findPath("interestName").getTextValue();
Logger.info("Calling interest for " + interestName);
Identity user = (Identity) ctx().args.get(SecureSocial.USER_KEY);
if (user == null) {
ObjectNode result = Json.newObject();
result.put("error", "requires-login");
Http.Context ctx = Http.Context.current();
ctx.flash().put("error", play.i18n.Messages.get("securesocial.loginRequired"));
result.put("redirect", RoutesHelper.login().absoluteURL(ctx.request(), IdentityProvider.sslEnabled()));
return ok(result);
}
Logger.info("user is not null");
if(interestName == null) {
ObjectNode result = Json.newObject();
result.put("error", "Empty input");
return badRequest(result);
}
//get user
EBUser ebUser = Application.getEBUser();
Logger.info("interest="+interestName+", userInfo:" + ebUser.toString());
//Call addInterst API.
String apiEndpoint = Play.application().configuration().getString(AppConstants.EB_API_ENDPOINT);
String url = "";
try {
url = apiEndpoint + "add_interest/" + ebUser.getId() + "/" + URLEncoder.encode(interestName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
ObjectNode result = Json.newObject();
result.put("error", "Cant parse interest properly");
Logger.info("error " + result.toString());
return badRequest(result);
}
Logger.info(url);
Promise<WS.Response> promiseOfAPI = WS.url(url).get();
Promise<Result> promiseOfResult = promiseOfAPI.map(
new Function<WS.Response, Result>() {
@Override
public Result apply(WS.Response response) throws Throwable {
return addInterestCallback(response);
}
});
return async(promiseOfResult);
}
Handler的名称是addInterest。
关于这里可能发生什么的任何指示?
答案 0 :(得分:1)
java.nio.channels.ClosedChannelException
这意味着你关闭了频道,然后继续使用它。