Filter过滤器学习使用
验证token
对外API过滤器
public class APIFilter implements Filter {private static Logger logger = LogManager.getLogger(APIFilter.class);private ICachedTokenService tokenService;public APIFilter(ICachedTokenService tokenService) {super();this.tokenService = tokenService;}@Overridepublic void init(FilterConfig arg0) throws ServletException {}@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {HttpServletRequest hreq = (HttpServletRequest) req;HttpServletResponse hres = (HttpServletResponse) resp;//设置一些Header其他信息hres.setHeader("Access-Control-Allow-Origin", hreq.getHeader("Origin"));hres.setHeader("Access-Control-Allow-Credentials", "true");hres.setHeader("Access-Control-Allow-Methods", hreq.getMethod());hres.setHeader("Access-Control-Max-Age", "86400");hres.setHeader("Access-Control-Allow-Headers", "*");//不校验权限if(hreq.getRequestURI().contains("/unauth") || hreq.getRequestURI().contains("/question")){chain.doFilter(req, resp);return;}// 如果是OPTIONS则结束请求if (HttpMethod.OPTIONS.toString().equals(hreq.getMethod())) {hres.setStatus(HttpStatus.NO_CONTENT.value());return;}try{//从请求cookie中获取access_tokenAccessTokenUser user = null;String access_token=hreq.getParameter("access_token");if(StringUtils.isBlank(access_token)){access_token= hreq.getHeader("access_token");}if(StringUtils.isBlank(access_token)){access_token=this.getCookieByCookieName("access_token", hreq);}//获取用户if(StringUtils.isNotBlank(access_token)){String token=access_token;user = ThreadLocalCache.fetchAPIData("AccessTokenUserByAccessToken:"+token+",true",() -> {ApiResultDTO<AccessTokenUser> tokenUserResp= tokenService.getAccessTokenUserByAccessToken(token, true);if(tokenUserResp.isSuccessed()) {return tokenUserResp;}else {String errorMsg = "访问令牌服务发生错误,错误码:"+tokenUserResp.getStatus()+",错误信息:"+tokenUserResp.getStatusMsg();logger.error(errorMsg);throw new RuntimeException(errorMsg);}});//判断是否存在这样的用户if(user==null) logger.error("请求地址{}根据access_token【{}】无法获取登录用户。",hreq.getRequestURI(),access_token);}if(user==null){throw new BusinessException("登录已过期,请重新登录!", ApiResultDTO.STATUS_UNAUTH);}LoginInitUtils.afterLogin(false,hreq,hres,user);chain.doFilter(req, resp);return;} catch (Exception e) {ApiResultDTO<String> apiResult=null;if(e instanceof BusinessException) {BusinessException businessException = (BusinessException) e;apiResult = ApiResultDTO.failed(businessException.getErrorCode(), businessException.getOriMsg());}else {apiResult = ApiResultDTO.failed(e.getMessage());}hres.setContentType("application/json;charset=UTF-8");hres.setHeader("Cache-Control", "no-store");hres.setHeader("Pragma", "no-cache");hres.setDateHeader("Expires", 0);hres.getWriter().write(new ObjectMapper().writeValueAsString(apiResult));hres.getWriter().flush();hres.getWriter().close();}}private String getCookieByCookieName(String cookieName,HttpServletRequest hreq) {Cookie[] cookies = hreq.getCookies();if(cookies!=null){for(Cookie cookie:cookies){if(cookieName.equalsIgnoreCase(cookie.getName())){return cookie.getValue();}}}return null;}
}
对内API过滤器
public class _APIFilter implements Filter {private Logger logger=LogManager.getLogger(this.getClass()); private ICachedTokenService tokenService;public _APIFilter(ICachedTokenService tokenService) {super();this.tokenService = tokenService;}@Overridepublic void init(FilterConfig arg0) throws ServletException {}@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {HttpServletRequest hreq = (HttpServletRequest) req;HttpServletResponse hres = (HttpServletResponse) resp;try{Utils.passOverByIp(hreq.getRemoteAddr());// logger.error("--------------------------_APIFilter["+hreq.getRequestURL()+"]开始--------------------------");AccessTokenUser user = null;String access_token=hreq.getParameter("access_token");if(StringUtils.isBlank(access_token)){access_token= hreq.getHeader("access_token");}//根据访问令牌获取用户if(StringUtils.isNotBlank(access_token)){try {String token=access_token;user = ThreadLocalCache.fetchAPIData("AccessTokenUser."+token+",true",() -> {ApiResultDTO<AccessTokenUser> tokenUserResp= tokenService.getAccessTokenUserByAccessToken(token, true);if(tokenUserResp.isSuccessed()) {return tokenUserResp;}else {String errorMsg = "访问令牌服务发生错误,错误码:"+tokenUserResp.getStatus()+",错误信息:"+tokenUserResp.getStatusMsg();logger.error(errorMsg);throw new RuntimeException(errorMsg);}});} catch (Exception e) {e.printStackTrace();user=null;}if(user==null) logger.error("--------------------------_APIFilter["+hreq.getRequestURL()+"]access_token["+access_token+"]获取用户结果"+user+"--------------------------");}//根据内部令牌获取用户if(user==null) {String inner_token=hreq.getParameter("inner_token");if(StringUtils.isBlank(inner_token)){inner_token = hreq.getHeader("inner_token");}if(StringUtils.isBlank(inner_token)) throw new RuntimeException("未找到访问令牌");String token=inner_token;user=ThreadLocalCache.fetchAPIData(null,()->{return tokenService.verifyTokenAndGetUser(token);},"验证访问令牌错误,");if(user==null) logger.error("--------------------------_APIFilter["+hreq.getRequestURL()+"]inner_token["+inner_token+"]获取用户结果"+user+"--------------------------");}LoginInitUtils.afterLogin(false,hreq,hres,user);chain.doFilter(req, resp);return;} catch (Exception e) {e.printStackTrace();ApiResultDTO<String> apiResult=ApiResultDTO.failed(e.getMessage());hres.setContentType("application/json;charset=UTF-8");hres.setHeader("Cache-Control", "no-store");hres.setHeader("Pragma", "no-cache");hres.setDateHeader("Expires", 0);hres.getWriter().write(new ObjectMapper().writeValueAsString(apiResult));hres.getWriter().flush();hres.getWriter().close();}}}
public ApiResultDTO<AccessTokenUser> verifyTokenAndGetUser(String inner_token) {Map<String,String> claims=JWTUtils.verifyTokenAndGetClaims(inner_token);AccessTokenUser user=null;if(claims.get("user")!=null) {user=JsonConverter.jsonStrToObject(claims.get("user"), AccessTokenUser.class);}return ApiResultDTO.success(user);}
//将inner_token 转化为用户信息
public static Map<String,String> verifyTokenAndGetClaims(String jwt_token) {JWT jwt=JWT.create();//jwt.setHeader(JWTHeader.TYPE, "JWT");//默认值jwt.setHeader(JWTHeader.ALGORITHM, "HS256");jwt.setSigner(JWTSignerUtil.createSigner("HS256", SECRET));try {jwt.parse(jwt_token);} catch (Exception e) {e.printStackTrace();throw new RuntimeException("校验jwt_token令牌失败");}if(!jwt.verify()) {throw new RuntimeException("无效的jwt_token");}Map<String,String> result = new HashMap<String,String>();JSONObject jo=jwt.getPayloads();if(jo==null||jo.size()==0) {return result;}for (Map.Entry<String,Object> d: jo.entrySet()) {if(d.getValue()==null) {continue;}result.put(d.getKey(), d.getValue().toString());}return result;}
配置拦截器
@Configuration
public class FiltersConfiguration {@Autowiredprivate ICachedTokenService tokenService;//前后端交互处理-拦截所有api访问请求@Beanpublic FilterRegistrationBean<APIFilter> apiFilterRegistrationBean() {FilterRegistrationBean<APIFilter> registrationBean = new FilterRegistrationBean<APIFilter>();registrationBean.setFilter(new APIFilter(tokenService));registrationBean.addUrlPatterns("/api/*");registrationBean.setOrder(5);return registrationBean;}//前后端交互处理-拦截所有_api访问请求@Beanpublic FilterRegistrationBean<_APIFilter> _apiFilterRegistrationBean() {FilterRegistrationBean<_APIFilter> registrationBean = new FilterRegistrationBean<_APIFilter>();registrationBean.setFilter(new _APIFilter(tokenService));registrationBean.addUrlPatterns("/_api/*");registrationBean.setOrder(6);return registrationBean;}
}
清除缓存
基础数据定义的一些资源变更,需要同步清除其他项目本地缓存
配置清除缓存过滤器
//处理基础数据变更后通知各系统清空本系统的基础数据的缓存@Beanpublic FilterRegistrationBean<FireSysDataChangedEventFilter> fireSysDataChangedEventFilterRegistrationBean() {FilterRegistrationBean<FireSysDataChangedEventFilter> registrationBean = new FilterRegistrationBean<FireSysDataChangedEventFilter>();registrationBean.setFilter(new FireSysDataChangedEventFilter(fireSysDataChangedEventService));registrationBean.addUrlPatterns("/api/*");registrationBean.setOrder(5);return registrationBean;}
定义过滤器
public class FireSysDataChangedEventFilter implements Filter {private Logger logger = LoggerFactory.getLogger(this.getClass());private IFireSysDataChangedEventService fireSysDataChangedEventService;public FireSysDataChangedEventFilter(IFireSysDataChangedEventService fireSysDataChangedEventService) {super();this.fireSysDataChangedEventService = fireSysDataChangedEventService;}@Overridepublic void init(FilterConfig arg0) throws ServletException {}@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {try {chain.doFilter(req, resp);fireSysDataChangedEventIfNecessary(req);}finally {SysDataChanged.reset();}}private void fireSysDataChangedEventIfNecessary(ServletRequest req) {try {if(SysDataChanged.isChanged()) {HttpServletRequest hreq = (HttpServletRequest)req;String uri = hreq.getRequestURI();logger.info("完成请求{}后,基础数据有变更,需要向其他系统发出清除缓存的消息",uri);fireSysDataChangedEventService.sysDataChanged();}}catch(Exception e) {e.printStackTrace();logger.error("fireSysDataChangedEventIfNecessary错误{}",e.getMessage());} }
}
定义清除缓存服务
public interface IFireSysDataChangedEventService {/*** 基础数据发生变更*/void sysDataChanged();}
@Service
@ConfigurationProperties(prefix="docin-sys.config",ignoreUnknownFields=true)
public class FireSysDataChangedEventService implements IFireSysDataChangedEventService {private Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprivate ISysDataVersionService sysDataVersionService;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate AsyncTaskComponent asyncTaskComponent;//这里的url是再配置文件配置的//清理缓存urlsprivate Map<String, List<String>> clearcacheurls = new HashMap<>();public void setClearcacheurls(Map<String, List<String>> clearcacheurls) {this.clearcacheurls = clearcacheurls;}@SuppressWarnings("unchecked")@Overridepublic void sysDataChanged() {long lastTimestamp = System.currentTimeMillis();//更新系统版本时间戳sysDataVersionService.updateLastTimestampOfSysData(lastTimestamp);logger.info("成功更新系统版本时间戳为{}",lastTimestamp);if(MapUtils.isEmpty(clearcacheurls)) return;for (Map.Entry<String,List<String>> e: clearcacheurls.entrySet()) {asyncTaskComponent.runTaskInThreadPool((d)->{String name=(String)d.get("name");List<String> urls=(List<String>)(d.get("urls"));for (String url : urls) {try {restTemplate.getForObject(url, String.class);logger.info("向服务["+name+"].["+url+"]发送清理缓存请求成功");} catch (Exception e2) {logger.error("向服务["+name+"].["+url+"]发送清理缓存请求失败,",e2);}}return null;}, Utils.buildMap("name",e.getKey(),"urls",e.getValue()));}}}
docin-sys.config.clearcacheurls.docin-xfxt[0]=http://localhost:8088/docin-xfxt/syscache/clear
docin-sys.config.clearcacheurls.docin-xfxt[1]=http://localhost:8088/docin-xfxt/syscache/clear
docin-sys.config.clearcacheurls.docin-sys[0]=http://localhost:8088/docin-sys/syscache/clear
docin-sys.config.clearcacheurls.docin-sys[1]=http://localhost:8088/docin-sys/syscache/clear
docin-sys.config.clearcacheurls.docin-portal[0]=http://localhost:8088/docin-portal/syscache/clear
docin-sys.config.clearcacheurls.docin-stat[0]=http://localhost:8088/docin-portal/syscache/clear
docin-sys.config.clearcacheurls.hlw-xfxt[0]=http://localhost:8089/hlw-xfxt/syscache/clear
docin-sys.config.clearcacheurls.hlw-sys[0]=http://localhost:8089/hlw-sys/syscache/clear
docin-sys.config.clearcacheurls.docin-xf-exchange[0]=http://localhost:8080/docin-xf-exchange/syscache/clear
具体清除缓存请求接口
@Api(value="公共基础请求-基础数据缓存处理",tags="公共基础请求")
@RestController
@RequestMapping(value="/syscache")
public class SysDataCacheController {@Autowiredprivate CronClearSysDataCacheJob cronClearSysDataCacheJob;@ApiOperation(value="清理基础数据缓存", httpMethod="GET")@RequestMapping(value="/clear", method=RequestMethod.GET)public ApiResultDTO<RequestMsgTempVO> clearSyscache(HttpServletRequest request){return RestAPITemplate.restapi(()->{cronClearSysDataCacheJob.refreshCache();return null;});}}
清除本地缓存
@Autowiredprivate ISysDataVersionService sysDataVersionService;//本地所获得基础数据最后更新时间戳private volatile long lastSysTimestamp = -1L;private volatile boolean refreshing=false;@Async("taskExecutor")//使用线程池 启动public void refreshCache() {logger.info("定时刷新令牌任务启动");if(this.refreshing) {logger.error("之前刷新任务还在堵塞中....");return;}try {this.refreshing = true;long lastSysTimestampOfServer = sysDataVersionService.getLastTimestampOfSysData();if(this.lastSysTimestamp!=lastSysTimestampOfServer) {this.lastSysTimestamp = lastSysTimestampOfServer;SysDataCacheAspect.clearCache();logger.warn("本地基础数据缓存已经清理,清理后本地基础数据版本为{}",lastSysTimestamp);Thread.sleep(5000);//防止攻击}else {logger.info("本地基础数据缓存的版本与基础数据服务一致,无需清理,本地基础数据版本为{}",lastSysTimestamp);}}catch (InterruptedException e) {e.printStackTrace();}finally {this.refreshing=false;}}
缓存逻辑
@Aspect //定义一个切面
@Configuration
public class SysDataCacheAspect {private static Logger logger = LogManager.getLogger(SysDataCacheAspect.class);private static final Map<String,Boolean> cacheFileNames = new ConcurrentHashMap<String, Boolean>();private static LoadingCache<String,Object> cache = null;static {// CacheLoader 初始化CacheLoader<String, Object> cacheLoader = new CacheLoader<String, Object>() {@Override// load方法的作用是在通过get方法从LoadingCache获取不到值时去加载该值并放入缓存。public Object load(String key) throws Exception {return null;}};cache = CacheBuilder.newBuilder()// 设置容量大小.maximumSize(80000)//默认一天后过期.expireAfterWrite(10, TimeUnit.DAYS).removalListener(new RemovalListener<String, Object>() {@Overridepublic void onRemoval(RemovalNotification<String, Object> notification) {if(notification.getValue()!=null && notification.getValue() instanceof CacheFile) {CacheFile cacheFile = (CacheFile)notification.getValue();removeCacheFile(cacheFile.fileName);}}})// 加载器配置.build(cacheLoader);}private String normalizedArgsStr(Object[] args){if(args==null || args.length==0) {return "";}Object[] normalizedArgs = new Object[args.length];if(args!=null) {for(int i=0;i<args.length;i++) {Object arg = args[i];if(arg instanceof AccessTokenUser) {AccessTokenUser user = (AccessTokenUser)arg;normalizedArgs[i]= user.getUserId();}else {normalizedArgs[i]=arg;}}}return JsonConverter.toJsonStr(normalizedArgs);}@Around("execution(* (@com.xysd.bizbase.annotation.SysDataCache *).*(..)) || execution(@com.xysd.bizbase.annotation.SysDataCache * *(..))")public Object process(ProceedingJoinPoint point) throws Throwable {String className = point.getSignature().getDeclaringTypeName();String methodName = point.getSignature().getName();Object[] args = point.getArgs();String key = className+"_$_"+methodName+"_$_"+(normalizedArgsStr(args));Object cached = cache.getIfPresent(key);if(methodName.endsWith("_dontCache")){return point.proceed(args);}if(cached!=null) {if(cached instanceof CacheFile) {CacheFile cachedFile = (CacheFile)cached;Object cachedData = readCachedData(cachedFile);if(cachedData==null) {//读取缓存失败return point.proceed(args);}else {return cachedData;}}else {return cached;}}else {cached = point.proceed(args);if(cached instanceof ApiResultDTO){if(((ApiResultDTO<?>) cached).getData() == null) return cached;}if(cached!=null) {try {CacheFile cachedFile = cacheToDiskIfNecessary(cached);if(cachedFile!=null) {cache.put(key, cachedFile);}else {cache.put(key, cached);}}catch(Exception e) {logger.error("缓存失败,失败信息{}",e.getMessage());e.printStackTrace();}}return cached;}}private Object readCachedData(CacheFile cachedFile) {String fileName = cachedFile.getFileName();String absolutePath = getAbsoluteCacheFilePath(fileName);File f = new File(absolutePath);InputStream in = null;ObjectInputStream oin = null;try {in = new FileInputStream(f);oin = new ObjectInputStream(in);Object cachedData = oin.readObject();return cachedData;}catch(Exception e) {logger.error("读取缓存序列化文件失败,失败信息:{}",e.getMessage());e.printStackTrace();return null;}finally {Utils.clean(in,oin);}}/*** 当value序列化后占用字节大于50K时写入磁盘进行缓存* @param value* @return*/private CacheFile cacheToDiskIfNecessary(Object value) {int cachThreadshold = 50*1024;ByteArrayOutputStream bos = null ; ObjectOutputStream oos = null;try {bos = new ByteArrayOutputStream();oos = new ObjectOutputStream(bos);oos.writeObject(value);oos.flush();byte[] byteArray = bos.toByteArray();if(byteArray!=null && byteArray.length>cachThreadshold) {return buildCacheFile(byteArray);}else {return null;}}catch(Exception e) {throw new RuntimeException(e);}finally {Utils.clean(bos,oos);}}private CacheFile buildCacheFile(byte[] byteArray) {String fileName = "syscachefile_"+Utils.getUUID("");String absolutePath = getAbsoluteCacheFilePath(fileName);File f = new File(absolutePath);OutputStream out = null;try {if(!f.getParentFile().exists()) {f.getParentFile().mkdirs();}out = new FileOutputStream(f);out.write(byteArray);out.flush();cacheFileNames.put(fileName, true);return new CacheFile(fileName);}catch(Exception e) {throw new RuntimeException(e);}finally {Utils.clean(out);}}private static String getAbsoluteCacheFilePath(String fileName) {String sysCacheBaseDir = Utils.getTmpDirRoot()+"/sysDataCache";return sysCacheBaseDir+"/"+fileName;}public static void removeCacheFile(String fileName) {if(StringUtils.isNoneBlank(fileName)) {cacheFileNames.remove(fileName);String absolutePath = getAbsoluteCacheFilePath(fileName);File f = new File(absolutePath);try {if(f.exists() && f.isFile()) {f.delete();}}catch(Exception e) {//删除失败不做任何处理e.printStackTrace();}}}/*** 清空缓存*/public static final void clearCache() {for(String fileName:cacheFileNames.keySet()) {removeCacheFile(fileName);}cacheFileNames.clear();cache.invalidateAll();}public static class CacheFile implements Serializable {private static final long serialVersionUID = -6926387004863371705L;private String fileName;public CacheFile(String fileName) {super();this.fileName = fileName;}public String getFileName() {return fileName;}}
}
拦截器
Hibernate的拦截器 监听实体变化
public class SysEntityUpdateListener extends EmptyInterceptor {/*** */private static final long serialVersionUID = -7428554904158765594L;@Overridepublic void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {super.onDelete(entity, id, state, propertyNames, types);SysDataChanged.changed();}@Overridepublic boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,String[] propertyNames, Type[] types) {SysDataChanged.changed();return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);}@Overridepublic boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {SysDataChanged.changed();return super.onSave(entity, id, state, propertyNames, types);}@Overridepublic void postFlush(Iterator entities) {super.postFlush(entities);}@Overridepublic int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,String[] propertyNames, Type[] types) {return super.findDirty(entity, id, currentState, previousState, propertyNames, types);}@Overridepublic void onCollectionRemove(Object collection, Serializable key) throws CallbackException {SysDataChanged.changed();super.onCollectionRemove(collection, key);}@Overridepublic void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {SysDataChanged.changed();super.onCollectionUpdate(collection, key);}}
记录是否要清理缓存
public class SysDataChanged {private static final ThreadLocal<Boolean> store = new ThreadLocal<Boolean>();/*** 当前线程已经更改过基础数据*/public static final void changed() {store.set(true);}/*** 重置*/public static final void reset() {store.set(false);}/*** 当前线程是否更改过基础数据* @return*/public static final boolean isChanged() {return Boolean.TRUE.equals(store.get());}}
通过SysEntityUpdateListener监听实体变化,更改SysDataChanged.store.set(true)。当用户请求后端接口时,通过FireSysDataChangedEventFilter过滤器判断SysDataChanged.store.get()==true,从而触发restTemplate.getForObject(url, String.class)请求,更新各个项目本地的基础数据缓存SysDataCacheAspect.clearCache()。
相关文章:
Filter过滤器学习使用
验证token 对外API过滤器 public class APIFilter implements Filter {private static Logger logger LogManager.getLogger(APIFilter.class);private ICachedTokenService tokenService;public APIFilter(ICachedTokenService tokenService) {super();this.tokenService …...
关于修改数据库服务器时间导致达梦数据库集群裂开
故障原因: 因为每天数据库服务器时间都不一致,想要给数据库服务器配置个NTP服务器。结果导致达梦数据库裂库。后面查看了达梦系统管理员手册了解了达梦集群的机制,知道数据库服务器时间需要先关闭数据库服务之后才可以修改数据库服务器时间。…...
自定义包的设计与实现
这是一个 CPacket 类,用于解析包含固定格式的数据。该类的成员变量包括固定包头 sHead、包长度 nLength、控制命令 sCmd、包数据 strData 和和校验 sSum。 构造函数: CPacket():默认构造函数,初始化成员变量。 CPacket(const B…...
时机成熟了
时机成熟了。 有一个老乡群,一到年底就各种人找车、车找人的消息。这些消息如果能直接爬取到一个小的网页里面去,则可以极大地便利大家做检索。如何把非结构化的内容转成结构化的 json,在以前是一个难题,但是有了 ChatGPT&#x…...

Linux 驱动开发基础知识——总线设备驱动模型(八)
个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS 🐼本文由…...

SpringBoot+BCrypt算法加密
BCrypt是一种密码哈希函数,BCrypt算法使用“盐”来加密密码,这是一种随机生成的字符串,可以在密码加密过程中使用,以确保每次加密结果都不同。盐的使用增强了安全性,因为攻击者需要花费更多的时间来破解密码。 下图为…...

更新至2023年,2002-2023年3月中国国债发行数据
更新至2023年,2002-2023年3月中国国债发行数据 1、时间:2002-2023年3月 2、指标:序号、代码、发行日期、发行总额(亿元)、期限(年)、发行价格、票面利率(发行参考利率)(%)、票面利率说明、息票品种、附息利率类型、付息频率、起息日期、付息…...

2024最新版TypeScript安装使用指南
2024最新版TypeScript安装使用指南 Installation and Development Guide to the Latest TypeScript in 2024 By JacksonML 1. 什么是TypeScript? TypeScript is JavaScript with syntax for types. – typescriptlang.org TypeScript 是 JavaScript 的一个超集,…...

国外知名的农业机器人公司
从高科技温室到云播种,农业机器人如何帮助农民填补劳动力短缺以及超市货架的短缺。 概要 “高科技农业”并不矛盾。当代农业经营更像是硅谷,而不是美国哥特式,拥有控制灌溉的应用程序、驾驶拖拉机的 GPS 系统和监控牲畜的带有 RFID 芯片的耳…...

【EI会议征稿中|ACM出版】#先投稿,先送审#第三届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2024)
#先投稿,先送审#ACM出版#第三届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2024) 2024 3rd International Conference on Cyber Security, Artificial Intelligence and Digital Economy 2024年3月8日-10日 | 中国济南 会议官网&…...

【笔试常见易错选择题01】else、表达式、二维数组、%m.ns、%m.nf、常量指针和指针常量、宏定义、传参、数组越界、位段
1. 下列main()函数执行后的结果为() int func(){ int i, j, k 0; for(i 0, j -1;j 0;i, j){ k; } return k; } int main(){cout << (func());return 0; }A. -1 B. 0 C. 1 D. 2 判断为赋值语句,j等于0 0为假不进循环 选B. 2. 下面程…...
Unity中常见的单词
前言 unity中常见的单词学习积累 一.常用的基础词。 new:新建; as:像。。一样; null:对象空值; void:函数返回空值; switch:开关; abstract:抽象的; event:事件; return:返回; class:类; …...

【仅需一步,1分钟极速开服】幻兽帕鲁保姆级教程
本教程分为两部分。一、开服教程。二、如何登录游戏(第一次接触游戏,如何玩) 一、开服教程。 1、通过 游戏服务器专属优惠页,选择以下应用模板并点击立即购买。 - 【服务器套餐配置推荐】* 1、入门配置(2~…...

Zoho Mail 2023:回顾过去,展望未来:不断进化的企业级邮箱解决方案
当我们告别又一个非凡的一年时,我们想回顾一下Zoho Mail如何融合传统与创新。我们迎来了成立15周年,这是一个由客户、合作伙伴和我们的敬业团队共同庆祝的里程碑。与我们一起回顾这段旅程,探索定义Zoho Mail历史篇章的敏捷性、精确性和创新性…...

python执行linux系统命令的三种方式
前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 1. 使用os.system 无法获取命令执行后的返回信息 import osos.system(ls)2. 使用os.popen 能够获取命令执行后的返回信息 impor…...

协会认证!百望云荣获信创工委会年度“卓越贡献成员单位”称号
当前,新一轮科技革命和产业变革正加速重塑全球经济结构,强化企业科技创新的主体地位,推动创新链、产业链、人才链深度融合,加快科技成果产业化进程至关重要。 近日,中国电子工业标准化技术协会信息技术应用创新工作委员…...

神经网络激活函数到底是什么?
激活函数 其实不是很难啦,归结一下就是大概这样几个分类,详情请参考【神经网络】大白话直观理解!_哔哩哔哩_bilibili神经网络就是干这个事的~ 如果队伍不长,一个ykxb就可以了,如果 如果 队伍太长 就加一个激活函数也…...

【智慧工业】东胜物联定位与跟踪解决方案,为方案商提供蓝牙网关、信标等物联网智能硬件设备
利用东胜物联的蓝牙网关我们的合作伙伴在德国的建筑工地成功实施了基于物联网蓝牙的员工出勤和跟踪管理解决方案,该解决方案简化了员工时间表并增强了工作流程,为经理和主管提供了更多时间来专注于项目洞察,并提高了员工的效率、绩效和生产力…...

C#中使用OpenCvSharp4库读取本地图像并显示
C#中使用OpenCvSharp4库读取本地图像并显示 OpenCvSharp4是基于.NET 的 OpenCV 包装器,OpenCV源代码是采用C和C写的,目前对于C和Python开发者相对来说比较友好,对于Python开发者而言官方提供了opencv-python使用。 首选我们使用Visual Studi…...

Stable Diffusion系列(四):提示词规则与使用
文章目录 基础规则高级规则插件使用基于相机镜头增强提示词常用提示词总结奇特提示词珍藏 基础规则 所谓提示词,也就是文生图中的文,由连贯的英语单词或句子组成。其最基础的规则是: 不同提示词之间需要用英文逗号分隔,空格和换…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...