我是网络图书馆和Netty的新手,我正在建立一个客户端。通过测试,我了解到我的代码可以按预期正常工作,但是当它无法正确连接到主机时,我想给出一条更有意义的消息。因此,我要做的是尝试将其连接到端口上的localhost,而我在该端口上没有任何主机,因此它将引发异常。下面是堆栈跟踪:
Exception in thread "main" io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /127.0.0.1:8484
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source)
at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:353)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:340)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:633)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.ConnectException: Connection refused: no further information
... 11 more
我尝试尝试捕获AnnotatedConnectException,但是该类似乎没有任何导入。我怀疑此类是AbstractChannel中的一个私有异常。我检查了实现,它是:
private static final class AnnotatedConnectException extends ConnectException {
private static final long serialVersionUID = 3901958112696433556L;
AnnotatedConnectException(ConnectException exception, SocketAddress remoteAddress) {
super(exception.getMessage() + ": " + remoteAddress);
initCause(exception);
setStackTrace(exception.getStackTrace());
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}
我还发现我可以通过对Exception进行try-catch来处理此异常。但是,如果可能的话,我想避免这种情况,因为我觉得这是一个糟糕的主意。关于是否可以做到以及如何做到的任何想法?
编辑:这是我尝试捕获ConnectException的尝试(对AnnotatedConnectException尝试了相同的操作。在ConnectException所在的位置完成了此操作):
public void connectToServer(String host, int port) {
Bootstrap bootstrap = new Bootstrap();
/*
* Creates/configures the handler group which will handle the connection and keep the connection
* alive.
*/
EventLoopGroup handlerGroup = new NioEventLoopGroup();
bootstrap.group(handlerGroup).channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true).handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) {
/*
* Handles a connection when it is connected (ie. decoding/encoding packets and
* handling the packets that the server sends back to the client).
*/
socketChannel.pipeline().addLast("MapleProtocolDecoder", new MapleProtocolDecoder());
socketChannel.pipeline().addLast("ServerHandler", new ServerHandler());
socketChannel.pipeline().addLast("MapleProtocolEncoder", new MapleProtocolEncoder());
}
});
try {
// Connects the client
ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
// Waits until the connection is closed
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
handlerGroup.shutdownGracefully();
System.out.println("[Info] The client has disconnected!");
} catch (ConnectException e) {
System.out.println( e.getClass().getCanonicalName());
System.out.println("[Info] The server is offline.");
}
}
谢谢!
最佳答案
该库可能是由您的容器在运行时提供的,并且在开发过程中可能没有提供,除非您将其专门添加到项目的类路径中。但是您不一定要这样做,因为这样会在项目上创建对底层容器实现细节的依赖。在这种情况下,如果最终要部署到另一个应用程序服务器(tomcat,jboss,weblogic等),则netty库可能仅在本地开发期间存在。
我建议仅捕获更通用的ConnectException
,它是AnnotatedConnectException
扩展的。 ConnectException
是标准Java JDK的一部分,因此不需要进行其他类路径修改,并且可以在所有应用服务器之间移植。
您认为捕获Exception不是一个好主意,这是正确的。最好只捕获要尝试执行的代码引发的特定异常,以便可以向用户或在日志中显示更准确的消息。关于异常处理技术的This article可能会有用。
编辑:
如果您正在调用的框架没有表明可以抛出ConnectException
,那么您可能会被迫捕获Exception:
try {
// your code
} catch (InterruptedException e) {
// Do something
} catch (Exception e) {
// Do something else
}
这并不理想,但是框架API却让您别无选择。
关于java - Netty-处理AnnotatedConnectException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46488786/