-
项目中的多重登录检测处理
2012-10-20 16:29:39一个账户同时只能一次登录在线,当使用同一个账户二次登录的时候那么第一的登录将被失效(类似QQ挤下线) 处理基本思想: 将唯一用户ID与Session建立关联关系放在Application作用域中进行管理。 --------------...需求:
一个账户同时只能一次登录在线,当使用同一个账户二次登录的时候那么第一的登录将被失效(类似QQ挤下线)
处理基本思想:
将唯一用户ID与Session建立关联关系放在Application作用域中进行管理。
----------------------------------------------------------------------------------------------------------
关键处理类:
package com.defshare.sy.web.util; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; import org.apache.struts2.ServletActionContext; import com.defshare.foundation.global.PropertiesUtil; import com.defshare.sy.config.AuthConfig; public final class AuthenUtil { static Logger LOG = Logger.getLogger(AuthenUtil.class); /** * 多重登录检测处理 * @param loginId */ public synchronized static final void multipleLoginDetect(String loginId){ ServletContext servletContext = ServletActionContext.getServletContext(); Map<String,HttpSession> sessionMap = new HashMap<String,HttpSession>(); Object sessionMapObj = servletContext.getAttribute("LOGINED_USER_SESSION_MAP"); if (sessionMapObj!=null){ sessionMap = (Map<String,HttpSession>)sessionMapObj; } if (sessionMap.containsKey(loginId.toUpperCase())){//如果登过录就销毁以前登录的Session HttpSession session = sessionMap.get(loginId.toUpperCase()); if (session!=null && !ServletActionContext.getRequest().getSession().getId().equals(session.getId())){ try { session.invalidate(); } catch (Exception e) { LOG.info("session被重复销毁:["+e.getMessage()+"]"); } } } sessionMap.put(loginId.toUpperCase(), ServletActionContext.getRequest().getSession());//将当前session重新放入Map servletContext.setAttribute("LOGINED_USER_SESSION_MAP", sessionMap); } /** * 登出 * @param loginId */ public synchronized static final void logout(String loginId){ if(loginId==null || "".equals(loginId)) return; ServletContext servletContext = ServletActionContext.getServletContext(); Object sessionMapObj = servletContext.getAttribute("LOGINED_USER_SESSION_MAP"); if (sessionMapObj==null){ return; } Map<String,HttpSession> sessionMap = (Map<String,HttpSession>)sessionMapObj; if (sessionMap.containsKey(loginId.toUpperCase())){//如果登过录就销毁以前登录的Session HttpSession session = sessionMap.get(loginId.toUpperCase()); if (session!=null){ try { session.invalidate(); LOG.info("根据登录ID:"+loginId+"找到Session,执行销毁"); } catch (Exception e) { LOG.info("session被重复销毁:["+e.getMessage()+"]"); } } sessionMap.remove(loginId.toUpperCase()); } } public synchronized static final String getAdminName(){ return AuthConfig.adminName; } /** * 获得管理员信息 * <p> * admin,0000 * </p> * @return */ public synchronized static final String getAdminInfo(){ return AuthConfig.adminName+","+AuthConfig.adminPwd; } }
登录调用示范:/** * 诊所登录 * * @return */ public String doLogin() { SystemLog log = new SystemLog(); String zsid = super.getParam("zsid").toString(); String zsmm = super.getParam("zsmm").toString(); log.setLoginId(zsid); log.setKind("1"); log.setIp(request.getRemoteHost()); if (StringUtils.isBlank(zsid) || StringUtils.isBlank(zsmm)) { super.addValidateMsg(VALIDATE_MSG, "诊所编号密码不能为空"); log.setContent("诊所登录失败:[诊所编号密码不能为空]"); systemLogService.addLog(log); return "toLogin"; } if (zsid.equals(AuthConfig.adminName)) { super.addValidateMsg(VALIDATE_MSG, "非法的诊所ID"); log.setContent("诊所登录失败:[非法的诊所ID]"); systemLogService.addLog(log); return "toLogin"; } try { if (cliniqueService.authentication(zsid, zsmm)) { super.addAttr(IAction.LOGINED_USER, zsid, VScope.SESSION); UserUtil.setLoginedUser(zsid);// 保存线程局部变量 AuthenUtil.multipleLoginDetect(zsid); log.setContent("诊所" + zsid + ">登录>成功!"); systemLogService.addLog(log); return "login_success"; } } catch (Exception e) { super.addValidateMsg(VALIDATE_MSG, e.getMessage()); log.setContent("诊所登录异常:[" + e.getMessage() + "]"); systemLogService.addLog(log); return "toLogin"; } super.addAttr(IAction.LOGIN_MSG, "用户名密码不正确", VScope.REQ); log.setContent("诊所登录失败:[用户名密码不正确]"); systemLogService.addLog(log); return "toLogin"; }
登出调用示范:
public String logout() { if(!StringUtils.isBlank(getCurrentUser())){ SystemLog log = new SystemLog(); log.setLoginId(getCurrentUser()); log.setKind("1"); log.setIp(request.getRemoteHost()); log.setContent("诊所" + getCurrentUser() + ">注销>成功!"); AuthenUtil.logout(getCurrentUser()); systemLogService.addLog(log); return "logout_success"; }else{ return "logout_success"; } }
-
5.20x版802.1x正常,心跳包执行不到几次后802.1x收到下线报文
2020-12-08 18:59:26<div><p>5.20x版802.1x正常,心跳包执行不到十几行,浏览一个网页的时间内802.1x收到下线报文,...也一样会下线</p><p>该提问来源于开源项目:drcoms/drcom-generic</p></div> -
java中如何踢人下线?封禁某个账号后使其会话立即掉线!
2021-01-19 13:48:39封禁账号是一个比较常见的业务需求,尤其是在论坛、社区类型的项目中,当出现了违规用户时我们需要将其账号立即封禁。 常规的设计思路是:在设计用户表时增加一个状态字段,例如:status,其值为1时代表账号正常,其...需求场景
封禁账号是一个比较常见的业务需求,尤其是在论坛、社区类型的项目中,当出现了违规用户时我们需要将其账号立即封禁。
常规的设计思路是:在设计
用户表
时增加一个状态字段,例如:status
,其值为1时代表账号正常,其值为0时代表账号已被封禁。当我们需要封禁一个账号时,只需要将其账号的
status
值修改为0即可,对方再次登录系统时,我们便可以检测到status
值不为1禁止登录。这种模式虽然思路简单,但也有一个不小的问题,那就是: 如果对方一直在线不注销登录呢?
由于我们只在登录时检测
status
值,这也就代表:如果对方不主动注销账号,他的会话还是会一直存在且有效。那怎么才可以做到在封禁账号后立即生效?
你可能会想到使用拦截器,拦截用户的所有请求检测账号状态:
status=0
时禁止访问,status=1
时再对请求放行此方式虽然解决了问题,但是如果每次请求都要进行数据库查询的话,数据库表示你如此扫荡我你就没有一点心理压力吗?
那怎么办?上缓存?虽然可以缓解性能压力,但似乎总感觉没有完美解决问题。
真正的问题点在于:一个正常的系统只有0.01%的用户是需要封禁的,我们对其它99.99%用户的实时检测都是不必要的性能浪费。
在如上场景中,我们真正需要的是一个踢人下线的操作,即:我们需要在封禁某个用户后,使他的会话立即掉线,即时他重新登录也会被禁止登录
那么,怎么做到实时踢人下线呢?
笔者使用的是
sa-token
权限认证框架,这个框架封装了踢人下线操作调用非常方便,不用像其它框架一样还需要我自己再封装一层才能做到。具体代码
- 首先添加
pom.xml
框架
<!-- sa-token 权限认证, 在线文档:http://sa-token.dev33.cn/ --> <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-spring-boot-starter</artifactId> <version>1.12.1</version> </dependency>
- 在用户登录时将账号id写入会话中
@RestController @RequestMapping("user") public class UserController { @RequestMapping("doLogin") public String doLogin(String username, String password) { // 此处仅作示例模拟,真实项目需要从数据库中查询数据进行比对 if("zhang".equals(username) && "123456".equals(password)) { StpUtil.setLoginId(10001); return "登录成功"; } return "登录失败"; } }
- 将指定id的账号
// 使指定id账号的会话注销登录,对方再次访问系统时会抛出`NotLoginException`异常,场景值为-5 @RequestMapping("kickout") public String kickout(long userId) { StpUtil.logoutByLoginId(userId); return "剔出成功"; }
关键代码就在
StpUtil.logoutByLoginId(userId)
这一句,使指定id的账号注销登录 (踢人下线)如果觉得文章写得不错还请大家不要吝惜为文章点个赞,您的支持是我更新的最大动力!
最后附上项目链接:
- 官网文档:http://sa-token.dev33.cn/
- Gitee开源地址: https://gitee.com/sz6/sa-token
- GitHub开源地址: https://github.com/click33/sa-token
- 首先添加
-
Spring Cloud项目技术解决方案闪电战
2021-01-17 22:50:28项目集成了以下功能: 1、服务注册与发现 2、Eureka用户认证 3、服务续约保活(心跳机制) 4、Eureka高可用 5、Eureka健康检测 6、服务下线 7、远程调用 8、负载均衡 9、服务雪崩 10、服务降级 11、Hystrix熔断器 12... -
Websocket客户端断网,服务端心跳超时检测并断开连接
2020-09-16 23:38:36项目上想通过websocket做好友的上线下线通知功能,用户上线时客户端websocket连接服务端,调用服务端onOpen()方法,服务端通知所有好友当前用户上线;用户退出时客户端websocket断开连接,调用服务端onClose()方法,...起因
项目上想通过websocket做好友的上线下线通知功能,用户上线时客户端websocket连接服务端,调用服务端onOpen()方法,服务端通知所有好友当前用户上线;用户退出时客户端websocket断开连接,调用服务端onClose()方法,服务端通知所有好友当前用户离线。
问题
这样做会有一个很大的问题,如果客户端是关闭流量、关闭WIFI断网而不是正常退出,服务端就不会收到客户端的断连请求,因此服务端并不会触发onClose()方法,导致其好友无法收到当前用户的离线信息。
解决方案
经过网上大量资料的查找,发现绝大多数网友都采用心跳机制解决。
客户端定时向服务端发送空消息(ping),服务端启动心跳检测,超过一定时间范围没有新的消息进来就默认为客户端已断线,服务端主动执行close()方法断开连接
Netty是一个非常强大的NIO通讯框架,支持多种通讯协议,并且在网络通讯领域有许多成熟的解决方案。
因此决定采用Netty来实现websocket服务器和心跳监听机制,不必再去重复造轮子
贴代码
netty启动类
public class WSServer { public void start(int port){ EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap .group(bossGroup, workerGroup) //设置主从线程组 .channel(NioServerSocketChannel.class) //设置nio双向通道 .childHandler(new WSServerInitializer()); //子处理器,用于处理workerGroup //用于启动server,同时启动方式为同步 ChannelFuture channelFuture = bootstrap.bind(port).sync(); //监听关闭的channel,设置同步方式 channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) { new WSServer().start(8888); } }
ChannelInitializer类,负责添加各种handler,注意添加顺序
public class WSServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { //获取流水线 ChannelPipeline pipeline = ch.pipeline(); //websocket基于http协议,所以要有http编解码器 pipeline.addLast(new HttpServerCodec()); //对写大数据的支持 pipeline.addLast(new ChunkedWriteHandler()); //对httpMessage进行整合,聚合成FullHttpRequest或FullHttpResponse pipeline.addLast(new HttpObjectAggregator(1024 * 64)); //心跳检测,读超时时间设置为30s,0表示不监控 ch.pipeline().addLast(new IdleStateHandler(30, 0, 0, TimeUnit.SECONDS)); //心跳超时处理事件 ch.pipeline().addLast(new ServerHeartBeat()); //自定义handler pipeline.addLast(new WSHandler()); //websocket指定给客户端连接访问的路由:/ws pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); } }
心跳超时处理器
public class ServerHeartBeat extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) {//超时事件 System.out.println("心跳检测超时"); IdleStateEvent idleEvent = (IdleStateEvent) evt; if (idleEvent.state() == IdleState.READER_IDLE) {//读 ctx.channel().close(); //关闭通道连接 } else if (idleEvent.state() == IdleState.WRITER_IDLE) {//写 } else if (idleEvent.state() == IdleState.ALL_IDLE) {//全部 } } super.userEventTriggered(ctx, evt); } }
好友上下线通知处理器
public class WSHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { //key为channelId value为uid 存储在Map中 private static ConcurrentHashMap<String,String> uidMap = new ConcurrentHashMap<>(); @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof FullHttpRequest){ //拦截请求地址,获取地址上的uid值,并存入Map集合中 FullHttpRequest fullHttpRequest = (FullHttpRequest) msg; String uri = fullHttpRequest.uri(); String uid = uri.substring(uri.lastIndexOf("/")+1, uri.length()); uidMap.put(ctx.channel().id().toString(),uid);//把uid放入集合中存储 System.err.println(uid+"上线****************************"); //TODO 通知所有好友,已上线 // uri改为 /ws fullHttpRequest.setUri("/ws"); } super.channelRead(ctx,msg); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { //获取Uid String uid = uidMap.get(ctx.channel().id().toString()); System.err.println(uid+"断线****************************"); uidMap.remove(ctx.channel().id().toString()); //TODO 通知所有好友,已下线 } @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception { } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { } }
JS代码
window.CHAT = { socket: null, init: function () { if (window.WebSocket) { CHAT.socket = new WebSocket("ws://127.0.0.1:8888/ws/00001"); CHAT.socket.onopen = function () { console.log("连接建立成功..."); }, CHAT.socket.onclose = function () { console.log("连接关闭..."); }, CHAT.socket.onerror = function () { console.log("发生错误..."); }, CHAT.socket.onmessage = function (e) { console.log("接收到消息" + e.data); } } else { alert("浏览器不支持websocket协议..."); } }, sendMessage: function (value) { CHAT.socket.send(value); }, heartBeat: function () { setInterval(this.sendMessage(""),5000); } }; CHAT.init(); CHAT.heartBeat();
websocket连接地址example:
ws://127.0.0.1:8888/ws/{uid}
-
游泳池清刷机器人总装图_运20总装线首次曝光:无需图纸高效生产,多架大飞机同时下线...
2021-01-02 12:53:03机器人装配8月15日的国防军事早报首次曝光了运20的生产总装线,运20是我国首个200吨级军用运输机项目,从立项,研发,再到制造装配,无不代表了我国飞机制造业最先进水平。而其中的无纸化和数字化,从飞机研发伊始就...机器人装配
8月15日的国防军事早报首次曝光了运20的生产总装线,运20是我国首个200吨级军用运输机项目,从立项,研发,再到制造装配,无不代表了我国飞机制造业最先进水平。而其中的无纸化和数字化,从飞机研发伊始就体现得淋漓尽致。
机身中段
立项不久之后,总设计师系统和总制造师系统就已经确立了六大项关键技术,其中就包括模块化,数字化的生产装配和检测技术。在设计之初,就要求全面数字化,不再发放二维图纸,对制造工艺和检测提出了更高要求。虽然遭受到极大阻力,但通过科研单位的重点攻关,看到数字化设计的重大进步之后,数字化设计迅速被接受。以数字化为基础,通过技术攻关完成在线关联设计,让各大研制单位可以同步研发进度,大大节省了时间的同时,提高了研发效率。也为未来我国飞机研制提供了范例,大大提高了我国飞机研发的整体水平。
机器人预制打孔
而在制造领域,数字化为基础,各大组件的装配速度大大提高,随时装配随时检测,不必等到总装时再进行调试。而代表现代大型飞机装配技术先进水平的大十字对接技术,将原先需要几天的修配式装配缩短到45分钟。在装配过程中还大量使用了机器人,机身与机尾的装配由人工制孔转为机器人制孔,精度和速度都大大提升。而为装配和调试制作的铁鸟台,装配工序和工艺,则提高了中国飞机研制的整体水平。
创新技术的投入不可避免的需要大批科研人员和厂商的合作。在装配阶段至关重要的数字化装配技术,就是浙江大学相关团队攻克的,而采用脉动生产线,则是西飞等制造厂运用先进生产流程的体现。而大飞机的研制,带动了国有,民营,科研院校的各大精英参与其中,高效而全面的科研团队,极大推动了运20的研制进程。
卫星图片
经历众多科研人员不懈努力和辛勤劳动,国产大型运输机项目从立项到首飞仅仅用了7年时间,自2017年服役后填补了我国国产军用运输机的空白,现在的运20已经进入了量产阶段,年产量将可能超过30架。从目前爆出的车间图来看,西飞已经可以同时制造和下线3-4架运20。未来国产的预警机,加油机等将摆脱没有大型运载平台的困境。对中国来说,大飞机的战略意义不言而喻。20时代的中国航空,将会带来更多奇迹。
-
JAVA上百实例源码以及开源项目
2016-01-03 17:37:40用JAVA编写了一个小工具,用于检测当前显示器也就是显卡的显示模式,比如分辨率,色彩以及刷新频率等。 Java波浪文字制作方法及源代码 1个目标文件 摘要:Java源码,初学实例,波浪文字 Java波浪文字,一个利用... -
JAVA上百实例源码以及开源项目源代码
2018-12-11 17:07:42Java编写的显示器显示模式检测程序 2个目标文件 内容索引:JAVA源码,系统相关,系统信息检测 用JAVA编写了一个小工具,用于检测当前显示器也就是显卡的显示模式,比如分辨率,色彩以及刷新频率等。 Java波浪文字制作... -
液晶显示器尺寸对照表_湖南首块中大尺寸液晶显示屏在浏点亮
2020-11-10 00:10:19惠科金杨项目的无尘净化车间,全自动化生产线正在运作。在产品检测区域,身穿防护服的工作人员正在对不同光区的显示屏进行质量检测。张迪 摄红网时刻12月24日讯(浏阳日报记者 罗晓芳)一块液晶屏,只有通过偏贴和绑定... -
2017年终总结
2017-12-21 12:08:00特征点定位项目据说也要下线(亏我还超过了face++的竞品,说不搞就不搞了)。带两个同事,但基本无事可做,给他们分配了些可以学习到深度学习前沿技术的开发方向,基本上算是混着。四月份和UI一起搞了个GAN的项目,... -
发动机冷测试技术在汽车生产中的应用
2021-01-18 17:48:30而随着相关测试技术的不断进步以及计算机处理能力的迅速提高,目前越来越多的汽车生产厂家,开始采用具有较快节拍、较高质量检测水平、较低生产成本的发动机冷测试来进行发动机下线的高精度检测,以更好的确保产品... -
实现即时通讯之BIO编程
2021-01-11 14:54:09BIO模式下实现简单的即时通讯 需求:需要实现一个...检测到有客户端下线后,需要同步更新所有客户端的联系人信息栏。 4.群聊 任意一个客户端的消息,可以推送给当前所有客户端接收。 5.私聊 可以选择某个员工,点击 -
汽车电子中的发动机冷测试技术在汽车生产中的应用
2020-11-06 08:25:55而随着相关测试技术的不断进步以及计算机处理能力的迅速提高,目前越来越多的汽车生产厂家,开始采用具有较快节拍、较高质量检测水平、较低生产成本的发动机冷测试来进行发动机下线的高精度检测,以更好的确保产品... -
一个基于微信的接龙小程序,开箱即用-源码
2021-01-27 09:45:35由于有人在小程序上发布违规内容,小程序暂时下线。 提醒:大家在使用源码的时候要加上敏感词过滤和敏感图片过滤,微信有开放检测接口比较急的同学可以自己行加上,我这边会尽快加上。 功能说明 发起接龙 - 简单易用... -
ideal下载与基本配置
2021-01-10 23:43:05破解不太安全,还不稳定,经常会被检测下线,特别麻烦。如果用来学习,JavaSE阶段用社区版就够了,JavaEE就先试用一个月,到期换个版本下载安装。 直接解压 找到bin目录下的idea64 选择不导入项目,然后点击免 -
基于BIO模式下即时通信(三)
2021-02-01 16:51:36基于BIO模式下的即时通信,我们需要解决客户端到客户端的通信,也就是需要...检测到有客户端下线后,需要同步更新所有客户端的联系人信息栏。 4.群聊 任意一个客户端的消息,可以推送给当前所有客户端接收。 5.私聊 -
FPGA技术在汽车电子中的应用
2021-01-19 14:46:03汽车在出厂之前,从研发设计到整车下线要经过严格的检测,以确保产品的质量和各分系统工作的可靠性和安全性。随着汽车电子技术的发展,测试项目和要求也越来越多,因而测试系统的可自定义性和可扩展性越来越受关注。... -
汽车电子中的FPGA技术在汽车电子中的应用
2020-12-08 14:30:20汽车在出厂之前,从研发设计到整车下线要经过严格的检测,以确保产品的质量和各分系统工作的可靠性和安全性。随着汽车电子技术的发展,测试项目和要求也越来越多,因而测试系统的可自定义性和可扩展性越来越受关注。... -
用户同一时段不能重复登录类似QQ(MyEclipse+mysql+Ajax)
2016-09-01 10:09:26MyEclipse+mysql+Ajax工具,解决用户同一时段不能重复登录,第二次登录将会挤掉第一次登录用户,弹出消息框(你已在其他地方登录,被迫下线),我也是借鉴其他大师 然后自己整理的。基本逻辑是:用户登录时候检测... -
【最新版】wechat_devtools_1.02.2004020.dmg【亲测可用】最好的微信开发者工具
2020-04-08 18:51:49指定路径时增加检测文件大小 U 优化 下线云真机测试功能 U 优化 小程序插件的版本不正确的时候的提示 U 提升了真机调试的稳定性 F 修复 ` 组件在基础库 2.8.2 报错的问题 反馈详情 F 修复 播放临时文件时连续... -
Spring-session服务概率性session乱窜怎么解决?
2019-11-07 22:23:07目前使用前后端结合检测到session串了之后自动T下线 ps: 如果我这边表达的看不太懂,也可以看这两篇,现象是一样的 [率性的 session 乱串](https://www.iteye.com/problems/78097) [session串了,该怎么解决]... -
一文带你搞懂API网关
2020-12-28 06:45:32项目会变的非常复杂且很难维护。</li><li>后期如果需要对微服务进行重构的话,也会变的非常麻烦,需要客户端配合你一起进行改造,比如商品服务,随着业务变的越来越复杂,后期需要... -
万能后台管理模板javaweb
2016-10-23 17:32:056. 在线管理:websocket技术,实时检测在线用户列表,统计在线人数,可强制用户下线 同一用户只能在一个客户端登录 7. 系统用户:对各个基本的用户增删改查,单发、群发站内信邮件短信,导入导出excel表格,批量删除 ... -
java开源包1
2013-06-28 09:14:34往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分功能文件(包括上传和下 载),浏览远程FTP服务器上的目录和文件,创建、... -
java开源包12
2013-06-28 10:14:45往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分功能文件(包括上传和下 载),浏览远程FTP服务器上的目录和文件,创建、... -
Java资源包01
2016-08-31 09:16:25往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分功能文件(包括上传和下 载),浏览远程FTP服务器上的目录和文件,创建、... -
java开源包101
2016-07-13 10:11:08往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分功能文件(包括上传和下 载),浏览远程FTP服务器上的目录和文件,创建、...
-
Java自学第九天 练习
-
Epplus的出坑笔记
-
东南大学历年c++复试题.zip
-
PowerBI重要外部工具详解
-
5G千兆智能网关的车联网应用
-
Androidesk-release-androidesk.zip
-
Java进阶--编译时注解处理器(APT)详解
-
【leetcode】串联所有单词的子串
-
ansys electronic 19
-
马士兵老师HashMap学习笔记
-
gexin-rp-sdk-http-4.1.1.0.rar
-
协程的意义
-
应广105G雾化片驱动.rar
-
MyBatisSelf.rar
-
马士兵 mybatis学习笔记
-
request+response学习笔记
-
智能停车场云平台(附vue+SpringBoot前后端项目源码)
-
NFS 网络文件系统
-
C++ STL(十四):常用排序算法(sort、random_shuffle、merge、reverse)
-
图像分类预习知识笔记