当我抓住SocketTimeoutException
时,我需要以不同的方式处理它。我发现的唯一依据是getMessage()
。到目前为止,我找到了两个:
java.net.SocketTimeoutException: connect timed out
java.net.SocketTimeoutException: Read timed out
消息(连接超时,读取超时)是否已硬编码?他们在哪里生成?这些消息至少有任何常量值吗?
答案 0 :(得分:2)
您可以检查Socket.isConnected。但是,由于异常是通过不同的方法抛出的,因此最好使用两个具有不同操作的catch块。
try {
socket.connect(address);
} catch (SocketTimeoutException e) {
throw new SocketConnectionException(e);
}
try {
socket.getInputStream();
...
} catch (SocketTimeoutException e) {
throw new SocketReadException(e);
}
答案 1 :(得分:2)
所以,这是我声名鹊起。在这里,我们沿着StackTrace走,寻找异常的起源方法。
public class ExceptionOriginTracing {
public static void main(String[] args){
try {
originOne();
originTwo();
} catch (Exception e){
// Now for the magic:
for (StackTraceElement element : e.getStackTrace()){
if (element.getMethodName().equals("originOne")){
System.out.println("It's a read error!");
break;
} else if (element.getMethodName().equals("originTwo")){
System.out.println("It's a write error!");
break;
}
}
}
}
public static void originOne() throws Exception{
throw new Exception("Read Failed...", null);
}
public static void originTwo() throws Exception{
throw new Exception("Connect failed...", null);
}
}
解析Exception给出的消息的区别在于,一个简单的字符串比实际方法的名称更容易改变。
除此之外,这不是最佳解决方案!但遗憾的是,这里没有最佳解决方案。
此外,使用此方法时,在使用源模糊处理时必须格外小心,这会更改方法名称,从而更改getMethodName()
的返回值。
设计这样的事情的正确方法是将异常包装在一个新的Exception中,它提供了通过使用标志或枚举来实际找出真实原点的方法。
解析消息/ StackTrace总是感觉很脏,并且可以在将来的版本中破解!
答案 2 :(得分:0)
他们来自不同的方法。调用connect()时,隐式或显式地发生'连接超时';调用read()或其中一个同源词时会发生'read timed out'。所以你可以区分只有两个不同的catch块。但无论哪种情况,你都可能要关闭连接......
答案 3 :(得分:0)
回复晚了一点。 我只是有一个布尔标志'isConnected'初始化为false。 连接后,我将其设置为true。 如果连接超时,您将永远无法到达那里。
在抛出异常之后检查Socket.isConnected听起来是个坏主意。然后可以关闭套接字。
通过在try
之前定义标志,可以在catch
处理程序中读取它。