进度条实现与后端进行交互,实时更新进度条(JAVA web项目实现)

实现思路

网页进度条更新有两种方式

1、轮询请求服务端、返回进度

2、服务端实时推送进度数据给客户端

        轮询方式的实现方法,服务端在执行的过程中将进度数据保存再session中,客户端调用的时候从session中取出来,然后更新进度条的数据,从而改变进度条。

        服务端实时推送,客户端请求执行任务的时候连接到websocket,服务端在执行的过程中将进度数据通过websocket的方式实时推送到客户端,客户端拿到数据后改变进度条

轮询请求方式

后端实现代码

    /**
	 * 任务执行方法(在实际应用中要改成自己的逻辑代码)
	*Title: execute
	*author:liuxuli
	*Description: 
	  * @param request
	  * @return
	 */
	@RequestMapping(value = "execute")
	public String execute(HttpServletRequest request) {
		
		for (int i = 0; i <= 100; i++) {
			//for循环只是个例子,在实际业务中百分比要进行实际的计算,这里的i就当是百分比
			//将进度值存储到session中
			request.getSession().setAttribute("processvalue", i);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		return "success";
	}
	/**
	 * 获取session中的进度值
	*Title: getprocess
	*author:liuxuli
	*Description: 
	  * @param request
	  * @return
	 */
	@RequestMapping(value = "getprocess")
	public Object getprocess(HttpServletRequest request) {
		//从session将执行进度值取出来并返回给用户
		return request.getSession().getAttribute("processvalue");
	}

网页端使用layui的进度条进行实现

<div class="layui-form-item">
	  	<div class="layui-input-block">
		  <div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="executeprogress" style="width: 80%;">
		  	<div id="percentdiv" class="layui-progress-bar layui-bg-green" lay-percent="0%"></div>
		  </div>
	  	</div>
	  </div>
<div class="layui-form-item">
	    <div class="layui-input-block">
	      <button class="layui-btn" lay-submit="" id="submitbtn" lay-filter="demo1">执行</button>
	    </div>
	  </div>
 
        var element;
	  	layui.use('element', function(){
		  element = layui.element;
		});
        //定义定时器
        var timer;
        //开始执行任务
        $('#submitbtn').click(function(){
	  		//进度条设置为百分之0
	  		element.progress('executeprogress', '0%');
            //轮询获取进度条数据
            getProcessvalue();
	  		//请求后台
	  		$.post('${pageContext.request.contextPath }/excute',function(data){
                //执行完成进度条设置为百分之百
	  			element.progress('executeprogress', '100%');
                //关闭定时器
                clearInterval(timer);
			});
	  	});
        //轮询请求进度数据
	  	function getProcessvalue(){
	  		//1秒请求一次进度条的数据
	  		timer = setInterval(function () {
	  			$.post('${pageContext.request.contextPath }/getprocess',function(data){
	  				//更新进度条
	  				element.progress('executeprogress', data+'%');
				});
	  		}, 1000);
	  	}

 

实时推送方式

1、创建websocket

/**
 * 创建websocketsession类,SessionConfigurator是降httpsession放入到websocket的用户属性中,
 * 如果使用springwebsocket就不需要这些配置了,因为spring的websocket框架已经配置好了
  * Title: TestWebsocket
  * Description: 
  * @author liuxuli
  * @date 2020年6月29日
 */
@ServerEndpoint(value = "/testwebsocket",configurator = SessionConfigurator.class)
public class TestWebsocket {

	/**
	 * 存储所有在线的用户(观察者模式)
	 */
	private static Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();
	/**
	 * 当用户连接到websocket,将该用户进行记录
	*Title: onopen
	*author:liuxuli
	*Description: 
	  * @param session
	  * @param config
	 */
	@OnOpen
	public void onopen(Session session,EndpointConfig config) {
		HttpSession httpsession = (HttpSession) session.getUserProperties().get(HttpSession.class.getName());
		System.out.println("连接成功");
		sessions.put(httpsession.getId(), session);
	}
	/**
	 * 当用户退出连接后,将该用户进行删除
	*Title: onClose
	*author:liuxuli
	*Description: 
	  * @param session
	 */
	@OnClose
	public void onClose(Session session) {
		HttpSession httpsession = (HttpSession) session.getUserProperties().get(HttpSession.class.getName());
		System.out.println("连接关闭");
		sessions.remove(httpsession.getId());
	}
	@OnError
	public void OnError(Throwable error,Session session) {
		System.out.println("错误");
		error.printStackTrace();
	}
	/**
	 * 向指定的用户发送消息
	*Title: sendMessage
	*author:liuxuli
	*Description: 
	  * @param httpsession 必须使用这个参数,如果不使用此参数来区分接收的用户,既浪费服务器资源,还能使所有的用户都能收到消息
	  * @param text	发送的消息
	 */
	public static void sendMessage(HttpSession httpsession,String text) {
		Session session = sessions.get(httpsession.getId());
		if (text != null && text.length() > 0) {
			session.getAsyncRemote().sendText(text);
		}
		
	}
}

SessionConfigurator类代码:

/**
 * 用来获取客户端的sessionid 从而绑定到websocket
  * Title: SessionConfigurator
  * Description: 
  * @author liuxuli
  * @date 2020年6月29日
 */
public class SessionConfigurator extends Configurator{

	@Override
	public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
		//获取到客户端的session
		HttpSession session = (HttpSession) request.getHttpSession();
		//将session当如到websocket的用户属性中
		sec.getUserProperties().put(HttpSession.class.getName(), session);
		super.modifyHandshake(sec, request, response);
	}
}

 

        //初始化layui,进度条依赖element
	    var element;
	  	layui.use('element', function(){
		  element = layui.element;
		});
	  	//执行任务
	  	$('#submitbtn').click(function(){
	  		//将进度条设置为05
	  		element.progress('executeprogress', '0%');
	  		//连接到websocket
	  		connect();
	  		//请求服务端进行执行任务
	  		$.post('${pageContext.request.contextPath }/excute.do',function(data){
	  			//服务端返回,任务执行完毕,关闭连接
	  			close();
			});
	  	});
	  	var ws;
	  	//连接到websocket
	  	function connect(){
	  		if ("WebSocket" in window) {
               ws = new WebSocket("${websocketserver}/testwebsocket");
                
               ws.onopen = function() {
            	   console.log("连接成功");
               };
                
               ws.onmessage = function (evt) { 
					//接收服务端的推送信息,改变进度条
                   element.progress('executeprogress', evt.data+'%');
               };
               ws.onclose = function() { 
                  // 关闭 websocket
                  console.log("连接已关闭..."); 
               };
            }
            
            else{
               // 浏览器不支持 WebSocket
               alert("您的浏览器不支持 WebSocket!");
            }
	  	}
	  	//关闭websocket
	  	function close(){
	  		ws.close();
	  	}

服务端的执行方法

    /**
	 * 任务执行方法(在实际应用中要改成自己的逻辑代码)
	*Title: execute
	*author:liuxuli
	*Description: 
	  * @param request
	  * @return
	 */
	@RequestMapping(value = "execute")
	public String execute(HttpServletRequest request) {
		
		for (int i = 0; i <= 100; i++) {
			//for循环只是个例子,在实际业务中百分比要进行实际的计算,这里的i就当是百分比
			//推送给用户
			TestWebsocket.sendMessage(request.getSession(), String.valueOf(i));
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		return "success";
	}

 

 

  • 25
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 要实现实时进度条,可以使用 WebSocket 技术将后端发送的进度信息实时推送到前端页面。下面是一个简单的示例: 前端使用 Vue.js 实现: 1. 在 Vue.js 组件中引入 `websocket` 库: ```javascript import { WebSocket } from 'websocket'; export default { data() { return { progress: 0, // 进度条值 }; }, mounted() { // 连接 WebSocket const ws = new WebSocket('ws://localhost:8080/progress'); // 监听消息事件 ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.hasOwnProperty('progress')) { // 更新进度条值 this.progress = data.progress; } }; }, }; ``` 2. 在页面中使用 `el-progress` 组件显示进度条: ```html <el-progress :percentage="progress"></el-progress> ``` 后端使用 Spring Boot 实现: 1. 添加 `spring-boot-starter-websocket` 依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建 WebSocket 配置类: ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(progressHandler(), "/progress").setAllowedOrigins("*"); } @Bean public WebSocketHandler progressHandler() { return new ProgressHandler(); } } ``` 3. 创建 WebSocket 处理器类: ```java public class ProgressHandler extends TextWebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 连接建立后发送进度信息 for (int i = 1; i <= 100; i++) { session.sendMessage(new TextMessage("{\"progress\": " + i + "}")); Thread.sleep(1000); } } } ``` 4. 在控制器中返回页面: ```java @Controller public class ProgressController { @GetMapping("/") public String index() { return "index"; } } ``` 这样就可以实现一个简单的实时进度条了。当后端发送进度信息时,前端会实时更新进度条的值。 ### 回答2: Vue和Spring Boot结合,可以实现实时进度条的功能。 在前端使用Vue框架,可以通过Vue的数据双向绑定特性和组件化的思想,实现实时进度条更新和展示。可以使用Vue的组件库,如Element UI或Ant Design Vue等,提供现成的进度条组件,通过绑定相关数据和事件,实现实时更新进度。 然后,在后端使用Spring Boot框架,可以编写相应的接口和逻辑,处理前端的请求,获取进度信息,并返回给前端。可以使用Spring MVC或Spring WebFlux等组件,处理前后端之间的通信。 前端通过Vue发送请求到后端,获取进度信息,并将其实时展示在页面上的进度条中。可以通过定时轮询、长轮询、WebSocket或Server-Sent Events等技术,实现实时的进度更新。 在后端中,可以使用异步任务或线程池等技术,处理一些比较耗时的操作,如文件上传、数据处理等。在处理的过程中,可以通过监听进度、记录已完成的任务数量或进度百分比等方式,获取进度信息,并将其返回给前端。 总结起来,通过Vue和Spring Boot的配合,可以实现实时进度条的功能。前端通过Vue的数据双向绑定和组件化思想,展示实时进度条后端通过Spring Boot提供接口和逻辑处理,获取进度信息并返回给前端。可以使用定时轮询、长轮询、WebSocket或Server-Sent Events等技术,实现实时的进度更新。在后端处理耗时操作时,通过监听进度、记录已完成的任务数量或进度百分比等方式,获取进度信息。 ### 回答3: Vue和Spring Boot在实现实时进度条时可以采取以下步骤: 1. 在Vue中,创建一个进度条组件,可以使用第三方库如Vuetify、Element UI等来实现进度条组件需要有一个进度值的属性,用于控制进度条的显示。 2. 在Vue中,使用Axios或Fetch等库向后端发送请求。请求可以是一个长时间运行的任务,比如上传文件或者后台处理数据。 3. 在后端的Spring Boot中,处理接收到的请求。可以使用Spring Boot提供的多线程或者异步任务来处理这些长时间运行的任务。 4. 在后端处理任务的过程中,根据任务的实际进度,将进度值发送给Vue前端。 5. 在Vue前端,接收到后端发送过来的进度值,更新进度条组件的进度值属性。 6. 随着任务的进行进度条组件会实时显示任务的进度,直到任务完成。 这种实时进度条实现方式可以提升用户体验,让用户能够清楚地了解到任务的进展情况。同时,使用Vue和Spring Boot可以使前后端开发分离,提高开发效率和代码的可维护性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员老牛了laoliu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值