Java Netty-句柄AnnotatedConnectionException

Java Netty-句柄AnnotatedConnectionException,java,network-programming,netty,Java,Network Programming,Netty,我是网络图书馆和Netty的新手,我正在建立一个客户。从测试中,我了解到我的代码可以正常工作,但是当它不能正确连接到主机时,我想给出一个更有意义的消息。所以我所做的是尝试让它在端口连接到localhost,而我在那里没有托管任何东西,所以它会抛出一个异常。下面是堆栈跟踪: Exception in thread "main" io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no fur

我是网络图书馆和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
我尝试捕获AnnotatedConnectionException,但是似乎没有任何导入到该类。我怀疑这个类是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;
    }
}
我还发现,我可以通过对异常执行try-catch来处理此异常。然而,如果可能的话,我想避免这样做,因为我觉得这是一个糟糕的想法。关于是否可以做到这一点以及如何做到这一点,有什么想法吗

编辑:以下是我捕获ConnectException的尝试(对AnnotatedConnectException尝试了相同的操作。这是在ConnectException所在的位置完成的):

public void connectToServer(字符串主机,int端口){
Bootstrap Bootstrap=新的Bootstrap();
/*
*创建/配置将处理连接并保持连接的处理程序组
*活着。
*/
EventLoopGroup handlerGroup=新的NioEventLoopGroup();
bootstrap.group(handlerGroup).channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE,true).handler(新的ChannelInitializer(){
@凌驾
受保护的通道(SocketChannel SocketChannel){
/*
*连接时处理连接(即解码/编码数据包和
*处理服务器发送回客户端的数据包)。
*/
socketChannel.pipeline().addLast(“MapleProtocoldCoder”,新的MapleProtocoldCoder());
socketChannel.pipeline().addLast(“ServerHandler”,newserverhandler());
socketChannel.pipeline().addLast(“MapleProtocolEncoder”,新的MapleProtocolEncoder());
}
});
试一试{
//连接客户端
ChannelFuture=bootstrap.connect(主机、端口).sync();
//等待连接关闭
channelFuture.channel().closeFuture().sync();
}捕捉(中断异常e){
handlerGroup.shutdownGracefully();
System.out.println(“[Info]客户端已断开连接!”);
}捕获(连接异常){
System.out.println(e.getClass().getCanonicalName());
System.out.println(“[Info]服务器处于脱机状态”);
}
}


谢谢

该库可能是由您的容器在运行时提供的,在开发过程中,如果不将其专门添加到项目的类路径中,可能无法使用该库。但您不一定要这样做,因为这样会创建一个对项目的依赖,使其依赖于低级别的容器实现细节。在这种情况下,如果最终部署到另一个应用服务器(tomcat、jboss、weblogic等),netty库可能只在本地开发期间存在

我建议只捕获更通用的
ConnectException
,它扩展了
AnnotatedConnectException
ConnectException
是标准Java JDK的一部分,因此不需要额外的类路径修改,并且可以跨所有应用服务器移植

您认为捕获异常不是一个好主意,这是正确的。最好只捕获您试图执行的代码将抛出的特定异常,以便向用户或在日志中显示更准确的消息。关于异常处理的技术可能很有用

编辑:

如果您正在调用的框架没有指示is可以抛出
ConnectException
,则您可能会被迫捕获异常:

    try {
        // your code
    } catch (InterruptedException e) {
       // Do something
    } catch (Exception e) {
       // Do something else 
    }
这并不理想,但框架API让您别无选择。

删除
sync()
并使用侦听器处理连接的成功或失败

try {
    ChannelFuture channelFuture = bootstrap.connect(host, port);
    channelFuture.addListener(f -> {
        if (!f.isSuccess() && f.cause() instanceof ConnectException) {
            System.out.println("[Info] The server is offline.");
        }
    });
    channelFuture.await();
} catch (InterruptedException e) {
    e.printStackTrace();
}

您在哪里尝试捕获异常?我添加了一段代码来演示如何尝试捕获异常。而代码段当前显示ConnectException。这和AnnotatedConnectionException的想法是一样的。谢谢你的澄清。我明白为什么捕获ConnectException是有意义的,但它似乎不起作用。但这似乎是一个遥不可及的障碍?我在这里的第一篇文章中附上了我的代码。
try {
    ChannelFuture channelFuture = bootstrap.connect(host, port);
    channelFuture.addListener(f -> {
        if (!f.isSuccess() && f.cause() instanceof ConnectException) {
            System.out.println("[Info] The server is offline.");
        }
    });
    channelFuture.await();
} catch (InterruptedException e) {
    e.printStackTrace();
}