从调用者类停止异步 Spring 方法

2024-04-08

我有一个类调用 Rest Web 服务来从服务器接收文件。在传输字节时,我创建了一个异步任务,它检查与服务器的连接是否正常,以便在出现错误时允许停止连接。 这个异步任务有一个我必须停止的循环:

@Component
public class ConnectionTest {

    @Async
    //Check connection with the server, if for three attemp it failes, throw exception
    public void checkServerConnection(String serverIp) throws Exception{
        int count=0;
        for(;;Thread.sleep(7000)){
            try{
                System.out.println("TEST");
                URL url = new URL(serverIp);
            HttpURLConnection con = (HttpURLConnection) url
                    .openConnection();
            con.connect();
            if (con.getResponseCode() == 200){
                System.out.println("Connection established!!");
            }
                if (count>0) count=0;
            }catch(Exception e){
                count++;
                if (count==3)   
                    throw new Exception("Connection error");
            }
        }
    }
}

但我怎样才能阻止调用者使用这个方法呢?

@Autowired 
    private ConnectionTest connectionTest;

    @Override
    public Response getFile(String username, String password, String serverIp, String toStorePath, String filePath){


        ResponseEntity<byte[]> responseEntity = null;
        try{
            //it is used to check if connection of the client with the server goes down
            connectionTest.checkServerConnection();
            RestClient restClient = new RestClient(username, password);     

            //          SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
            //          requestFactory.setBufferRequestBody(false);     
            //          restClient.setRequestFactory(requestFactory);
            //          RestTemplate restClient = new RestTemplate();
            responseEntity  = restClient.getForEntity(serverIp + "client/file/?filePath={filePath}", byte[].class, filePath);   

            //TODO kill async task and return false

UPDATE:正如@Thomas建议我在ConnectionTest中使用了布尔变量,我将循环更改为while (!stop)在网络服务调用之后我设置了ConnectionTest.setStop(true). 注意在循环之前设置 stop=false (而不是作为实例字段),否则只有第一个请求具有此值并进入 while 内。

UPDATE 2这是我的最后一个代码,它似乎有效,也许我应该用 wait-notify 更改 while 循环:

public Response getFile(String username, String password, String serverIp, String toStorePath, String filePath){
        try{
            //it is used to check if connection of the client with the server goes down
            Future<Boolean> isConnect = connectionTest.checkServerConnection(serverIp);
            Future<ResponseEntity<byte[]>> downloadResult = downloadAsync.makeRequest(username, password, serverIp, filePath);

            while(!isConnect.isDone() && !downloadResult.isDone()){
            }
            if (isConnect.isDone()){
                downloadResult.cancel(true);
                return new Response(false, false, "Error with server connection!", null);
            }else{
                connectionTest.setStop(true);
                ResponseEntity<byte[]> responseEntity = downloadResult.get();

                if (MediaType.TEXT_PLAIN.toString().equals(responseEntity.getHeaders().getContentType().toString())){
                    ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(new FileException("Error with file transfert!"));
                    return new Response(false, false, new String(Base64.decodeBase64(responseEntity.getBody()),Charset.forName("UTF-8")), errorResponse);
                }else{
                    Path p = Paths.get(filePath);
                    String fileName = p.getFileName().toString();
                    FileOutputStream fos = new FileOutputStream(toStorePath+"\\"+ fileName);
                    fos.write(responseEntity.getBody());
                    fos.close();
                    return new Response(true, true, "Your file has been downloaded!", null);
                }
            }
        }catch(Exception e){
            ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
            return new Response(false, false, "Error on the client side!" , errorResponse);
        }
    }

连接检查异步:

@Component
public class ConnectionTest {

    private boolean stop;

    @Async
    //Check connection with the server, if for three attemp it failes, throw exception
    /**
     * 
     * @param serverIp
     * @throws IOException
     */
    public Future<Boolean> checkServerConnection(String serverIp)  throws IOException {
        int count=0;
        stop = false;
        while (!stop){
            try{
                Thread.sleep(7000);
                System.out.println("TEST");
                //java.net.InetAddress.getByName(SERVER_ADDRESSS);
                URL url = new URL(serverIp);
                HttpURLConnection con = (HttpURLConnection) url
                        .openConnection();
                con.connect();
                if (count>0) count=0;
            }catch(Exception e){
                count++;
                System.out.println(count);
                if (count==3)   
                    return new AsyncResult<Boolean>(stop);
            }
        }
        return new AsyncResult<Boolean>(stop);
    }

    /**
     * @return the stop
     */
    public boolean isStop() {
        return stop;
    }

    /**
     * @param stop the stop to set
     */
    public void setStop(boolean stop) {
        this.stop = stop;
    }
}

下载异步:

@Component
public class DownloadAsync {

    @Async
    public Future<ResponseEntity<byte[]>> makeRequest(String username, String password, String serverIp, String filePath){
        RestClient restClient = new RestClient(username, password);
        ResponseEntity<byte[]> response= restClient.getForEntity(serverIp + "client/file/?filePath={filePath}", byte[].class, filePath);    
        return new AsyncResult<ResponseEntity<byte[]>>(response);
    }
}

当你处理一个@Async方法,一个好的做法是返回一个Future对象,因为您需要客户端和任务代码之间的连接点。

让我们让你的任务方法返回一个Future:

public Future<Integer> checkServerConnection(String serverIp) {
    // other code here
    return new AsyncResult<>(count);
}

您需要添加一些导入:

import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.AsyncResult;

最后,在客户端代码中让我们得到Future:

Future<Integer> checkTask = connectionTest.checkServerConnection();

现在,您可以使用checkTask。例如:

// Check if the task was completed including by an exception being thrown.
checkTask.isDone();

// Get the task result.
Integer count = checkTask.get(); // Note: this is a blocking method.

// If the task was finished by throwing an exception,
// get() method will also throw an exception.
// You can get the cause exception like this:
if (checkTask.isDone()) {
    try {
        checkTask.get();
    } catch(Exception e) {
        Exception cause = e.getCause(); // this will be your new Exception("Connection error")
    }
}

// Not recommended, but you can also cancel the task:
checkTask.cancel(mayInterruptIfRunning);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从调用者类停止异步 Spring 方法 的相关文章

  • 使用 GWT 读取非常大的本地 XML 文件

    我正在使用 GWT 构建我的第一个 Java 应用程序 它必须从一个非常大的 XML 文件中读取数据 当我尝试发送对文件中信息的请求时遇到问题 并且我不太确定它是否与文件的大小或我的语义有关 在我的程序中 我有以下内容 static fin
  • 在 Mysql 上使用 EntityManager JPA 运行脚本

    我正在尝试运行脚本 sql 文件 但由于我尝试了多种方法 因此出现多个错误 这是我的主要 sql 脚本 INSERT INTO Unity VALUES 11 paq 0 2013 04 15 11 41 37 Admin Paquete
  • 打印星号的 ASCII 菱形

    我的程序打印出这样的钻石 但只有当参数或菱形的每一面为4 例如如果我输入6 底部三角形的间距是错误的 我一直在试图找出答案 当参数改变时 底部的三角形不会改变 只有顶部的三角形会改变 它只适用于输入4 public static void
  • 不同类型的数组

    是否可以有一个包含两种不同类型数据的数组 我想要一个包含双精度型和字符串的数组 我尝试过 ArrayList
  • 通往楼梯顶部的可能路径

    这是一个非常经典的问题 我听说谷歌在他们的面试中使用过这个问题 问题 制定一个递归方法 打印从楼梯底部到楼梯顶部的所有可能的独特路径 有 n 个楼梯 您一次只能走 1 步或 2 步 示例输出 如果它是一个有 3 级楼梯的楼梯 1 1 1 2
  • 是否可以使用 Flying Saucer (XHTML-Renderer) 将 css 解析为类路径资源?

    我正在尝试将资源打包到 jar 中 但我无法让 Flying Saucer 在类路径上找到 css 我无法轻松构建 URL 来无缝解决此问题 https stackoverflow com questions 861500 url to l
  • 大数据使用什么数据结构

    我有一个包含一百万行的 Excel 工作表 每行有 100 列 每行代表一个具有 100 个属性的类的实例 列值是这些属性的值 哪种数据结构最适合在这里使用来存储数百万个数据实例 Thanks 这实际上取决于您需要如何访问这些数据以及您想要
  • 如何在代理后面安装 Eclipse Neon

    对于 Neon Eclipse 附带了一个安装程序 我在安装程序中找不到任何配置菜单 我的java版本是 java version java version 1 8 0 72 Java TM SE Runtime Environment b
  • 自动生成Flyway的迁移SQL

    当通过 Java 代码添加新模型 字段等时 JPA Hibernate 的自动模式生成是否可以生成新的 Flyway 迁移 捕获自动生成的 SQL 并将其直接保存到新的 Flyway 迁移中 以供审查 编辑 提交到项目存储库 这将很有用 预
  • 使用 Guice 优化注册表

    你好 今天思考了一种优化 有一些疑问 语境 我正在使用 Guice 2 进行 Java 开发 在我的网络应用程序中 我有一个转换器注册表 可以即时转换为某种类型 转换器描述如下 public class StringToBoolean im
  • 生成的序列以 1 开头,而不是注释中设置的 1000

    我想请求一些有关 Hibernate 创建的数据库序列的帮助 我有这个注释 下面的代码 在我的实体类中 以便为合作伙伴表提供单独的序列 我希望序列以 1000 开头 因为我在部署期间使用 import sql 将测试数据插入数据库 并且我希
  • 了解joda时间PeriodFormatter

    我以为我明白了 但显然我不明白 你能帮我通过这些单元测试吗 Test public void second assertEquals 00 00 01 OurDateTimeFormatter format 1000 Test public
  • 使用 Mockito 模拟某些方法,但不模拟其他方法

    有没有办法使用 Mockito 模拟类中的某些方法 而不模拟其他方法 例如 在这个 诚然是人为的 Stock我想嘲笑的班级getPrice and getQuantity 返回值 如下面的测试片段所示 但我想要getValue 执行乘法 如
  • 使用架构注册表对 avro 消息进行 Spring 云合约测试

    我正在查看 spring 文档和 spring github 我可以看到一些非常基本的内容examples https github com spring cloud samples spring cloud contract sample
  • 在 SWT/JFace RCP 应用程序中填充巨大的表

    您将如何在 SWT 表中显示大量行 巨大是指超过 20K 行 20 列的东西 不要问我为什么需要展示那么多数据 这不是重点 关键是如何让它尽可能快地工作 这样最终用户就不会厌倦等待 每行显示某个对象的实例 列是其属性 一些 我想使用 JFa
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • Java Swing:需要一个高质量的带有复选框的开发 JTree

    我一直在寻找一个 Tree 实现 其中包含复选框 其中 当您选择一个节点时 树中的所有后继节点都会被自动选择 当您取消选择一个节点时 树中其所有后继节点都会自动取消选择 当已经选择了父节点 并且从其后继之一中删除了选择时 节点颜色将发生变化
  • 如何使用play框架上传多个文件?

    我在用play framework 2 1 2 使用java我正在创建视图来上传多个文件 我的代码在这里 form action routes upload up enctype gt multipart form data
  • 在浏览器刷新中刷新检票面板

    我正在开发一个付费角色系统 一旦用户刷新浏览器 我就需要刷新该页面中可用的统计信息 统计信息应该从数据库中获取并显示 但现在它不能正常工作 因为在页面刷新中 java代码不会被调用 而是使用以前的数据加载缓存的页面 我尝试添加以下代码来修复
  • Java EE 目录结构

    我对以下教程有疑问 http www mkyong com jsf2 jsf 2 internationalization example http www mkyong com jsf2 jsf 2 internationalizatio

随机推荐

  • getIntent() 和从 savingInstanceState 获取意图有什么区别?

    大家好 我正在尝试 Android 在 2 个类之间传递意图 我意识到有 2 种传递意图的方法 第一个是在这里使用 getIntent 方法 Bundle extras getIntent getExtras mRowId extras n
  • 为什么强制转换为泛型类型会生效?

    On 重温Java http javarevisited blogspot tw 2011 09 generics java example tutorial html 代码摘录如下 class Holder
  • Tar 一个目录,但不要在存档中存储完整的绝对路径

    我在备份 shell 脚本的一部分中有以下命令 tar cjf site1 bz2 var www site1 当我列出存档的内容时 我得到 tar tf site1 bz2 var www site1 style css var www
  • Python tkinter 组合框

    当我单击组合框的名称而不使用 检查 等按钮来显示值时 我想填写我的条目 我怎样才能做到这一点 import tkinter as tk from tkinter import ttk import csv root tk Tk cb ttk
  • 当非模态时,展开 Segue 不会忽略自适应弹出框演示

    iOS 9 beta 更新 Apple 可能已针对 iOS 9 修复了此问题 如果您在 iOS 8 上解决了此问题 请确保它在 iOS 9 上也能正常工作 在故事板中 我创建了一个弹出框演示转场 以通过按钮呈现导航和视图控制器 并创建展开转
  • 动态 SQL 示例

    我最近了解了什么是动态 sql 它对我来说最有趣的功能之一是我们可以使用动态列名和表 但我无法思考现实生活中有用的例子 我唯一想到的是统计表 假设我们有一个包含名称 类型和created data 的表 然后我们想要一个表 其列中是从cre
  • 我可以在不更改系统 DPI 设置的情况下设置 Java Swing 应用程序的 DPI 分辨率吗?

    我有一个使用 Substance LookAndFeel 并以 Windows 作为目标平台的 Java 应用程序 我想增加应用程序的 DPI 设置without更改系统设置 我想这样做是因为我不想强迫用户重新启动 Windows 而且许多
  • git grep 按文件扩展名

    我知道 如果我只想在具有特定扩展名的文件上 grep 查找模式 我可以这样做 searches recursively and matches case insensitively in only javascript files for
  • 如何检查条件并将文本写入文本文件 oracle 表单

    我正在 Oracle Forms 中创建过程 其中检查验证数据并将数据插入表中 另请检查验证数据如果条件为真 则将一些文本写入文本文件 如果条件不为真 则将一些文本写入文本文件 Like Validation No 1 OK Validat
  • 生成聚合结构

    所以这里有一个问题 我想要做的是根据一组输入值生成一个数据结构 由于这是多语言提交 因此我们将输入列表视为键 值对数组 因此 还有一系列哈希 映射 字典或任何能让您满意的术语 我将在这里将所有符号保留为 JSON 希望它具有足够的通用性来翻
  • 提高 SURF 在小图像上的性能

    我在网络上遇到的每个 SURF 实现似乎都特别不擅长从小图像 例如 100x100 或更小 中提取有用数量的兴趣点 我尝试了多种方法 1 使用各种放大算法 从简单的最近邻算法到更高级的算法 基本上每个放大器 imagemagick 都提供
  • 如何更新 Haskell Map 中的项目?

    我是 Haskell 的新手 正在尝试找出一个合理的方法 写入地图的方式 为解决特定问题做准备 欧拉工程问题 我希望写一个函数来填充 带有记录的地图 但我无法让它发挥作用 let似乎创建局部变量而不是治疗smap作为一个全球性的 一定有某种
  • 使用javamail连接到hotmail?

    我想知道是否可以使用JavaMail 连接到Hotmail 我已经尝试过 但它不起作用 连接被拒绝 String host pop3 live com String username email protected cdn cgi l em
  • 自定义 QML 模块部署到 Android:缺少 QML 依赖项

    我正在开发一个包含一些特殊类型的自定义 QML 模块 我们称之为 MyModule 它用作其他应用程序项目的预编译库 即源代码对它们不可用 它通过 import MyModule 1 0 设置必要的导入路径等来使用 该模块包含基于 C 的
  • 过渡导航栏标题

    在一个名为 Luvocracy 的应用程序中 当用户在屏幕上向上滑动时 导航栏的标题会发生变化 旧标题被推高 而新标题则过渡进来 我现在没有视频 但这里有一些屏幕截图 https www dropbox com s sns0bsxkdv7p
  • 安全存储客户端敏感数据

    背景故事我在一家中小型公司工作 我们正在重新设计面向客户的会计门户 我的经理希望使用存储在最终用户计算机上的 cookie 中的信用卡信息来进行单击付款选项 我根本不喜欢这个想法 事实上我仍在努力改变他的想法 话虽这么说 我正在努力使其尽可
  • 如何在 alpine.js 应用程序中制作具有时间间隔的计时器

    使用 alpine js 2 我尝试在应用程序的页脚 为所有布局设置 中定义计时器 div div div span style background color yellow span div div div
  • 如何查看浏览器请求?

    我正在与另一位程序员合作 他最近向我发送了一个新的基于 JSON 的 API 来工作 他说我可以通过访问特定网站并查看浏览器请求来查看所有 API 调用的示例 我的问题是 如何查看我的浏览器请求 我之前曾使用 Wireshark 来分析我的
  • JAVA ANDROID - 获取文件夹的文件列表

    我想在一个文件夹中显示不同文件夹的图像GridView 但我不知道需要做什么才能获取包含可绘制文件夹内的文件名称的列表 此方法将为您提供一个包含 dir 文件夹列表以及子文件夹列表的列表 public void listf String d
  • 从调用者类停止异步 Spring 方法

    我有一个类调用 Rest Web 服务来从服务器接收文件 在传输字节时 我创建了一个异步任务 它检查与服务器的连接是否正常 以便在出现错误时允许停止连接 这个异步任务有一个我必须停止的循环 Component public class Co