spring-boot - 从方法调用时@Retryable 不起作用
问题描述
下面是我的应用程序类。流程就像DEToken
从这里开始的类,从DEToken
我调用RestConnection
我有@retryable
方法的地方开始。
@SpringBootApplication
@EnableRetry
public class SpringBootTrfficApplication implements CommandLineRunner {
Enter code here
@Autowired
DEToken deToken;
@Autowired
SyncService syncService;
public static void main(String[] args) {
SpringApplication.run(SpringBootTrfficApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
deToken.getToken();
}
}
DEToken 类:从getToken
我调用RestConnect
我有@Retrable
方法的地方:
@Service
public class DEToken {
private Logger logger = LogManager.getLogger(getClass());
@Autowired
RestConnection restConnection;
@Autowired
private Environment env;
public String accessToken;
public void getToken() {
System.out.println("hello from get token");
//String getJsonPayload = "{\"Query\":{\"RegisterExtensionWithDE\":{\"pid\": \"\",\"providerInsName\":" +
//env.getProperty("provider.ins") + "}}}";
//String str = restConnection.restPost(
// env.getProperty("rest.de.url"), getJsonPayload);
try {
String getJsonPayload =
"{\"Query\":{\"RegisterExtensionWithDE\":{\"pid\": \"\",\"providerInsName\":" +
env.getProperty("provider.ins") + "}}}";
StringBuffer tokenResult =
restConnection.restPost(env.getProperty("rest.de.url"),
getJsonPayload);
System.out.println(tokenResult);
JSONObject xmlJSONObj = XML.toJSONObject(tokenResult.toString());
JSONObject registration = new JSONObject();
if (xmlJSONObj.has("Registration")) {
registration = xmlJSONObj.getJSONObject("Registration");
if (registration.has("accessToken")) {
accessToken = registration.get("accessToken").toString();
}
else
logger.info("no accessToken from DE");
}
else
logger.info("no Registration object from DE");
}
catch (Exception e) {
logger.error("Exception while fetching accesstoken from DE ");
logger.error(e.getMessage());
}
}
}
我有retryable
方法的 REST 连接类:
@Service
public class RestConnection {
private Logger logger = LogManager.getLogger(getClass());
@Autowired
private Environment env;
public void setBaseUrl(String value, String ip) {
//baseUrl = value;
HttpsURLConnection.setDefaultHostnameVerifier(
(hostname, session) -> hostname.equals(ip));
}
/*
* REST post call
*/
@Retryable(value = {IOException.class, ConnectException.class},
maxAttempts = 4,
backoff = @Backoff(5000))
public StringBuffer restPost(String restUrl, String payload) {
StringBuffer sb = new StringBuffer();
HttpURLConnection conn = null;
try {
URL url = new URL(restUrl);
String protocol = url.getProtocol();
if (protocol.toLowerCase().equals("http")) {
conn = (HttpURLConnection)url.openConnection();
}
else if (protocol.toLowerCase().equals("https")) {
//setTrustedCert();
conn = (HttpsURLConnection)url.openConnection();
}
else {
logger.info("Protocol is neither HTTP nor HTTPS");
}
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("version", env.getProperty("de.version"));
conn.setRequestProperty("accessToken", env.getProperty("access.token"));
conn.setRequestProperty("requestHost", env.getProperty("server.de.host"));
conn.setRequestProperty("requestPort", env.getProperty("server.port"));
conn.setRequestProperty("requestProtocol",
env.getProperty("server.de.protocol"));
PrintWriter pout =
new PrintWriter(
new OutputStreamWriter(
conn.getOutputStream(), "UTF-8"),
true);
pout.print(payload);
pout.flush();
pout.close();
InputStream isi = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(isi);
int numCharsRead1;
char[] charArray1 = new char[1024];
while ((numCharsRead1 = isr.read(charArray1)) > 0) {
sb.append(charArray1, 0, numCharsRead1);
}
isr.close();
isi.close();
}
catch (MalformedURLException e) {
logger.error("MalformedURLException in restAccessTokenPOST..." +
e.getMessage());
//e.printStackTrace();
}
catch (IOException e) {
logger.error("IOException in restAccessTokenPOST..." +
e.getMessage());
e.printStackTrace();
}
catch (Exception e) {
logger.error("Exception in restAccessTokenPOST..." +
e.getMessage());
e.printStackTrace();
}
finally {
if (null != conn)
conn.disconnect();
}
return sb;
}
@Recover
public String helpHere(ConnectException cause) {
System.out.println("Recovery place! ConnectException");
return "Hello";
}
@Recover
public String helpHere(IOException cause) {
System.out.println("Recovery place! ArithmeticException");
return "Hello";
}
@Recover
public String helpHere(Exception cause) {
System.out.println("Recovery place! Exception");
return "Hello";
}
@Recover
public String helpHere() {
System.out.println("Recovery place! Exception");
return "Hello";
}
@Recover
public String helpHere(Throwable cause) {
System.out.println("Recovery place! Throwable");
return "Hello";
}
}
解决方案
考虑到你看到你的函数restPost()
实现,
@Retryable(value = {IOException.class, ConnectException.class},
maxAttempts = 4,
backoff = @Backoff(5000))
public StringBuffer restPost(String restUrl, String payload) {
try {
// Your code
}
catch(IOException ex){ // These catch block handles the exception
// and nothing to throw to retryable.
}
catch(MalformedURLException ex){ // More catch blocks that you
// define to handle exception.
}
}
在这里,您处理所有可能导致撤销retry
andrecover
方法的异常。
注意:可恢复方法仅在抛出异常时执行,不由任何
try-catch
块处理。
方法引发的任何异常restPost()
都由方法try-catch
块本身处理,并且没有由 catch 块重新引发的异常。
现在,Spring-Retry
无法获得任何异常(因为它是由方法try-catch
块处理的)。因此,不会执行任何恢复方法。
解决方案:您应该从要对其执行重试或恢复的方法定义中删除那些 catch 块。
请做必要的事情,它会像魅力一样工作...... :)
推荐阅读
- javascript - 在 React 中使用添加按钮添加输入
- scala - Alpakka S3Client 抛出 OptionVal$.contains NoSuchMethodError
- ios - 应用程序在 isHidden 属性上崩溃
- latex - Tex Studio:编译后 PDF 不更新?
- tfs - TFS 2018.2 升级
- c - 对于通用内存池,如何在 C 中的指针之间自由转换?
- c# - PRNG 的最小范围
- python - 如何使用 Tkinter 限制 Entry 小部件中的标志数量
- angularjs - angularjs文本框必须有最大长度数字
- sql - 如何对 Oracle Sql 中 hh24:mi:ss 中存储时间的列求和?