-
ThinkPHP防止重复提交表单的方法实例分析
2020-12-17 21:13:57本文实例总结分析了ThinkPHP防止重复提交表单的方法。分享给大家供大家参考,具体如下: 为什么会有表单重复的坑 在开发中,如果一个新增或修改的表单,在后台完成数据库操作后我们设定的不是跳转到其他页面,还是... -
仅提交表单一次的实现方法
2015-07-01 13:44:26选用一个普通按钮,而不是提交按钮,用户点击按钮后,将其禁用。 将以下代码: 替换成:选用一个普通按钮,而不是提交按钮,用户点击按钮后,将其禁用。
将以下代码:
<input type="submit" value="Submit"/>
替换成:<input type="button" value="Submit" οnclick="this.disabled=true; this.form.submit()"/>
-
java 后台控制重复提交表单
2020-11-10 22:47:12发展到现在,基本上的javaweb应用都是前后端分离,在提交表单的时候,容易遇到网络延时或者是闪屏快速点击多次的情况,然后造成多个纪录的插入,这并不是我们想要的结果,鄙人有以下方法可以不同程度的防止重复提交...发展到现在,基本上的javaweb应用都是前后端分离,在提交表单的时候,容易遇到网络延时或者是闪屏快速点击多次的情况,然后造成多个纪录的插入,这并不是我们想要的结果,鄙人有以下方法可以不同程度的防止重复提交:
1、前段控制,前端控制可以说是很多人的选择,因为简单,不需要考虑太多的其他因素,保障不会重复表单提交就好:比如:提交后把提交按钮设置为不可点击(disabled),或者设置子一个boolearn类型的值,依据值判断能否再次提交,再者可以使用promise
实现同步操作
2、后台校验:每一次操作者前,判断是否存在该数据(唯一值判断),如果存在则删除,反之新增
3、spring AOP 面向切面编程,过程:编写一个注解类(把注解卸载你调用的接口类方法上),和一个切面(切面切得就是这个注解类),切面的操作就是,设置指令(token+method:这个值必须保证唯一性)
上代码:
/** * @Author hhl * ToDo 防止重复提交注解类 * @Date 2020/11/10 0010 18:39 * @Version 1.0 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface NoRepeatSubmit { /** * 设置请求锁定时间 * * @return */ int lockTime() default 10; }
/** * @Author hhl * @Date 2020/11/10 0010 18:43 * @Version 1.0 */ @Service public class RedisLock { @Autowired private RedisUtil redisUtil; /** * 该加锁方法仅针对单实例 Redis 可实现分布式加锁 * 对于 Redis 集群则无法使用 * * 支持重复,线程安全 * * @param lockKey 加锁键 * @param clientId 加锁客户端唯一标识(采用UUID) * @param seconds 锁过期时间 * @return */ public boolean tryLock(String lockKey, String clientId, long seconds) { Object isExits = redisUtil.get(lockKey); if (Objects.isNull(isExits)) { redisUtil.set(lockKey, clientId, seconds); return true; } else { return false; } } /** * 与 tryLock 相对应,用作释放锁 * * @param lockKey * @param clientId * @return */ public boolean releaseLock(String lockKey, String clientId) { if (StringUtils.isNotBlank(lockKey) && StringUtils.isNotBlank(clientId) ) { redisUtil.remove(lockKey); return true; } else { return false; } } }
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.*; import org.springframework.data.redis.support.atomic.RedisAtomicLong; import org.springframework.stereotype.Component; import java.io.Serializable; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; @Component public class RedisUtil { @Autowired private RedisTemplate redisTemplate; /** * 写入缓存 * @param key * @param value * @return */ public boolean set(final String key, Object value) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); operations.set(key, value); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 写入缓存设置时效时间 * @param key * @param value * @return */ public boolean set(final String key, Object value, Long expireTime) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); operations.set(key, value); redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 批量删除对应的value * @param keys */ public void remove(final String... keys) { for (String key : keys) { remove(key); } } /** * 批量删除key * @param pattern */ public void removePattern(final String pattern) { Set<Serializable> keys = redisTemplate.keys(pattern); if (keys.size() > 0) redisTemplate.delete(keys); } /** * 删除对应的value * @param key */ public void remove(final String key) { if (exists(key)) { redisTemplate.delete(key); } } /** * 判断缓存中是否有对应的value * @param key * @return */ public boolean exists(final String key) { return redisTemplate.hasKey(key); } /** * 读取缓存 * @param key * @return */ public Object get(final String key) { Object result = null; ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); result = operations.get(key); return result; } /** * 获取缓存的过期时间 */ public long getExpire(final String key){ return redisTemplate.getExpire(key); } /** * 哈希 添加 * @param key * @param hashKey * @param value */ public void hmSet(String key, Object hashKey, Object value){ HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); hash.put(key,hashKey,value); } /** * 哈希 添加 设置时效时间 * @param key * @param hashKey * @param value * @param expireTime */ public void hmSet(String key, Object hashKey, Object value, Long expireTime){ HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); hash.put(key,hashKey,value) ; redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); } /** * 哈希获取数据 * @param key * @param hashKey * @return */ public Object hmGet(String key, Object hashKey){ HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); return hash.get(key,hashKey); } /** * 列表添加 * @param k * @param v */ public void lPush(String k,Object v){ ListOperations<String, Object> list = redisTemplate.opsForList(); list.rightPush(k,v); } /** * 列表获取 * @param k * @param l * @param l1 * @return */ public List<Object> lRange(String k, long l, long l1){ ListOperations<String, Object> list = redisTemplate.opsForList(); return list.range(k,l,l1); } /** * 集合添加 * @param key * @param value */ public void add(String key,Object value){ SetOperations<String, Object> set = redisTemplate.opsForSet(); set.add(key,value); } /** * 集合获取 * @param key * @return */ public Set<Object> setMembers(String key){ SetOperations<String, Object> set = redisTemplate.opsForSet(); return set.members(key); } /** * 有序集合添加 * @param key * @param value * @param scoure */ public void zAdd(String key,Object value,double scoure){ ZSetOperations<String, Object> zset = redisTemplate.opsForZSet(); zset.add(key,value,scoure); } /** * 有序集合获取 * @param key * @param scoure * @param scoure1 * @return */ public Set<Object> rangeByScore(String key,double scoure,double scoure1){ ZSetOperations<String, Object> zset = redisTemplate.opsForZSet(); return zset.rangeByScore(key, scoure, scoure1); } /** * @Description: 获取自增长值 * @param key key * @return */ public Long getIncr(String key) { RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); Long increment = entityIdCounter.getAndIncrement(); entityIdCounter.expire(60*30, TimeUnit.SECONDS); return increment; } public Long getIncr(String key, long timeOut) { RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); Long increment = entityIdCounter.getAndIncrement(); entityIdCounter.expire(timeOut, TimeUnit.SECONDS); return increment; } public Long getIncr(String key, long timeOut, TimeUnit timeUnit) { RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); Long increment = entityIdCounter.getAndIncrement(); entityIdCounter.expire(timeOut, timeUnit); return increment; } /** * @Description: 初始化自增长值 * @param key key * @param value 当前值 */ public void setIncr(String key, int value) { RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); counter.set(value); counter.expire(60*30, TimeUnit.SECONDS); } public void setIncr(String key, int value, long timeOut) { RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); counter.set(value); counter.expire(timeOut, TimeUnit.SECONDS); } }
package com.zhirui.lmwy.project.norepeat; import com.zhirui.core.model.ResultModel; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import javax.servlet.http.HttpServletRequest; import java.util.UUID; /** * @Author hhl * @Date 2020/11/10 0010 18:41 * @Version 1.0 */ @Aspect @Component public class AspectSubmit { private static final Logger LOGGER = LoggerFactory.getLogger(AspectSubmit.class); @Autowired private RedisLock redisLock; @Pointcut("@annotation(noRepeatSubmit)") public void pointCut(NoRepeatSubmit noRepeatSubmit) { } @Around("pointCut(noRepeatSubmit)") public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable { int lockSeconds = noRepeatSubmit.lockTime(); HttpServletRequest request = RequestUtils.getRequest(); Assert.notNull(request, "request can not null"); // 此处可以用token或者JSessionId String token = request.getHeader("Authorization"); String path = request.getServletPath(); String key = getKey(token, path); String clientId = getClientId(); boolean isSuccess = redisLock.tryLock(key, clientId, lockSeconds); LOGGER.info("tryLock key = [{}], clientId = [{}]", key, clientId); if (isSuccess) { LOGGER.info("tryLock success, key = [{}], clientId = [{}]", key, clientId); // 获取锁成功 Object result; try { // 执行进程 result = pjp.proceed(); } finally { // 解锁 redisLock.releaseLock(key, clientId); LOGGER.info("releaseLock success, key = [{}], clientId = [{}]", key, clientId); } return result; } else { // 获取锁失败,认为是重复提交的请求 LOGGER.info("tryLock fail, key = [{}]", key + "重复请求,请稍后再试"); return new ResultModel(true, "1", "重复请求,请稍后再试", null); } } private String getKey(String token, String path) { return token + path; } private String getClientId() { return UUID.randomUUID().toString(); } }
@RestController @RequestMapping("/test") @Slf4j @Api(tags = "重复提交测试-api") public class TestController { @Autowired private ProjectBuildService projectBuildService; @GetMapping("/norepeat") @NoRepeatSubmit(lockTime = 20000) public ResultModel norepeat() { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } return new ResultModel(true, ResultModel.CODE_SUCCESS, "查询成功"); } }
总结:三者可取其一,也可以1和3结合(推荐)
-
一个页面上多个form表单的用json数据格式提交到后台
2019-08-21 15:49:02在项目开发中遇到多个表单需要提交到后台,而且其中包含一些table数据,所以最后经过查询资料总结出以下方法:(我用的前端框架是layui其他的思想应该是一样的) 在看代码之前先说一下我的思路,因为代码写的也不是...在项目开发中遇到多个表单需要提交到后台,而且其中包含一些table数据,所以最后经过查询资料总结出以下方法:(我用的前端框架是layui其他的思想应该是一样的)
在看代码之前先说一下我的思路,因为代码写的也不是很详细,
首先我们可以通过$("#countForm").serializeArray()得到序列化的form表单上的数据,但是这个数据不是标准后台可以接收的数据,所以需要通过我下面的那种手段给转换成标椎格式,就这样将页面上的每一个表单都转换成标准格式,然后将这些标准格式合并组合成为一个大的标准的json串,然后后台声明一个结构和这个json串一样的对象来接受这个json串,最后就实现了多个表单使用json数据格式传送数据,实际如果没有那些特殊的数据(table表数据、复选框数据等)直接用$("#countForm").serialize()...." var PolicyMainString=countFormData+'&'+numberFormData+'&'+writeFormData+'&'+sureFormData;"
这种方式就可以拼接成字符串传输到后台,但是没办法,需求就是这样的,为了实现功能只能麻烦一点,但是这种方式真的很实用,也通过这个项目学习到了更多解决问题的方法
以下是js代码var countFormData = $("#countForm").serializeArray(); var numberFormData = $("#numberForm").serializeArray(); var writeFormData = $("#writeForm").serializeArray(); var sureFormData = $("#sureForm").serializeArray(); //获取table数据 var tr = $("#tableTest tr"); // 获取table中每一行内容 var result = []; // 数组 for (var i = 0; i < tr.length; i++) {// 遍历表格中每一行的内容 var tds = $(tr[i]).find("td"); if (tds.length > 0) { result.push({ "affiliatedcompanyname" : $(tds[0]).find("input").val(), "companyaddress" : $(tds[1]).find("input").val(), "contact" : $(tds[2]).find("input").val(), "phone" : $(tds[3]).find("input").val() }) } } //************************以下的代码主要是讲序列化的json数据转换为标准格式的json数据串********************************** //获取countFormData表单数据 var countObj={};//给obj分配内存 for(var i =0;i<countFormData .length;i++){ countObj[countFormData [i].name]=countFormData [i]['value']; } //获取countFormData表单中的附加险种 var coveragecodeObj={}; var coveragecodelist = $("[name='coveragecode']:checked"), coveragecode = ''; $.each(coveragecodelist,function (i,v){ coveragecode += i > 0 ? ","+v.value : v.value; coveragecodeObj={coveragecode}; }); //获取numberFormData表单数据 var numberObj={};//给obj分配内存 for(var i =0;i<numberFormData .length;i++){ numberObj[numberFormData [i].name]=numberFormData [i]['value']; } //获取writeFormData表单数据 var writeObj={};//给obj分配内存 for(var i =0;i<writeFormData .length;i++){ writeObj[writeFormData [i].name]=writeFormData [i]['value']; } //获取sureFormData表单数据 var sureObj={};//给obj分配内存 for(var i =0;i<sureFormData .length;i++){ sureObj[sureFormData [i].name]=sureFormData [i]['value']; } //******************************************************************************************************************* var jsonData = { // json数据 "businessList" : result, "countFormData": countObj, "numberFormData":numberObj, "writeFormData":writeObj, "sureFormData":sureObj, "coveragecodelist":coveragecodeObj } $.ajax({ type:"post", url:contextPath+'policy/InsertPolicyMain', contentType : "application/json;charset=UTF-8", data:JSON.stringify(jsonData), dataType:'JSON', success:function(data){ if(true == data.status){ parent.layer.alert(data.promptMsg); } } });
后台需要使用一个大的对象来接收这各json数据串(需要注意的是各个对象的名字需要和json串中的一样(小写的那个),不然接收不到)
import java.io.Serializable; import java.util.List; public class JsonData implements Serializable{ private CoverageCodeList coveragecodelist; private CountFormData countFormData; private NumberFormData numberFormData; private WriteFormData writeFormData; private SureFormData sureFormData; private List<Business> businessList; //实现get和set方法 //实现toString方法 }
由于代码真的篇幅太大了,所以没有全部粘贴,只列出了一个大概,所以有问题的兄弟们多留言,看到一定第一时间回复,
-
使用jquery ajax判断用户名是否存在后,如果做表单提交?
2017-02-27 10:30:17在使用返回值做判断也都是正常的,**但是在表单提交的时候**,无法正常的return,执行if的顺序也很奇怪 代码: ```javascript //检查用户名:不能为空,且不能重复 function checkUsername() { var username = ... -
struts2防止表单重复提交问题
2009-07-03 15:06:00首先介意大家能用AJAX提交就从项目开始用AJAX的方法提交。当然我现在介绍的不是用AJAX方法,我就是用的普通struts2方法,现在看来非常简单,由以下几步组成:一:在将要提交页面上加它的作用是在每次生成页面生成一...现在想起来这个问题还是挺恶心的,为了不让大家再有同样的痛苦,故写成BLOG来分享。
首先介意大家能用AJAX提交就从项目开始用AJAX的方法提交。
当然我现在介绍的不是用AJAX方法,我就是用的普通struts2方法,现在看来非常简单,由以下几步组成:
一:在将要提交页面上加
<s:token />
它的作用是在每次生成页面生成一个唯一的信息令牌,也就是默认的拦截器能识别出来的;
二:在struts.xml中加:
<interceptors>
<interceptor name="authority" class="com.aircom.zzy.interceptor.AuthorityInterceptor"></interceptor>
<interceptor-stack name="mydefault">
<interceptor-ref name="token">
<param name="includeMethods">roleAdd,roleUpd,moduleAdd,moduleUpd,add,upd</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="mydefault"></default-interceptor-ref>其中红色部分就是我要拦截的方法,当然是新增与修改了。把它这样写就不用每个都配置一次了。
<action name="roleAdd" class="com.aircom.zzy.action.RoleAction" method="roleAdd">
<result name="success" type="chain">roleList</result>
<result name="invalid.token">/webadmin/pages/result.jsp?opt=roleList</result>
</action>这是对每一个方法的配置,有的人写了一个重复提交的页面来作为唯一跳转,但我认为那是不友好的,所以我用了一个页面中转,我的页面新增完了就到了列表页面,因此刷新时我还让它跳回列表页面,下面是我的中转页面result.jsp:
<%@ page language="java" pageEncoding="utf-8"%>
<%
String opt = request.getParameter("opt") + ".action";
%>
<script type="text/javascript">
window.location.href = '<%=opt%>';
</script>大家看见了吧,简单吧!这们定义方法拦截,不用在每个页面上都加<token />,只在需要的地方写需要的代码,大大减轻了我们的工作量和代码的复杂度,个人认为是可取的,如果大家有什么好的意见,可以贴出来,共同学习。
-
表单设计的思考
2021-02-21 01:01:07本文就web表单设计,总结了以下的一些方法:首先,告知用户为什么要填写表单,他能获得什么,让用户看到把信息给你的好处。举个例子,GitHub在其注册表单的右侧清晰的告诉你注册使用它会得到的帮助:除了告诉用户填... -
HTML5 表单元素
2020-12-13 19:11:57注意:不是所有的浏览器都支持HTML5 新的表单元素,但是你可以在使用它们,即使浏览器不支持表单属性,仍然可以显示为常规的表单元素。 HTML5 元素 元素规定输入域的选项列表。 属性规定 form 或 input 域应该拥有... -
JAVA异步文件上传,当浏览器不兼容IE10以下的解决方案
2019-12-06 19:16:00然后换了个方法用form表单提交 提交的上去 但是不是异步的, 不知道怎么在请求之后, 做异步处理. 最后的解决方案是这样的. 还是表单提交, 用的这个好像是jquery封装的ajax <form id="form"> ... -
Nginx HTTP:413 Request Entity Too Large解决方法
2021-01-10 22:42:35概述 今天遇到一个问题,在PHP程序中上传图片出现了以下错误:...post_max_size = 8M (表单提交的最大限制,此项不是限制上传单个文件的大小,而是针对整个表单提交的数据进行限制。) upload_max_filesize = 2M (上 -
PHP学习笔记——索引博文
2014-04-09 10:51:26特别之处 ...PHP学习笔记有以下特点。 【1】由设备提交表单,而不是浏览器。一般的PHP博文中总是会提到表单,PHP表单提交的方法有两种一种是POST,一种是GET,然后通过HTML脚本写个输入框便可以在浏览器中实验了。但是P -
FormData对象——发送数据的利器
2017-11-17 21:40:00FormData是H5的新API,用来在提交表单的时候传送表单数据的,当然并不是只有提交表单的时候可以用,其它地方也可以用,比如一些和后台的通讯,发送数据,也可以使用FormData来进行数据的传输。 FormData通过new ... -
asp网页跳转的注意事项
2015-01-11 13:18:16asp常见的网页跳转有以下几种方法: 1. 这是最简单常用的链接跳转,这里就不多说 2. 这是表单中的点击按钮跳转的方法,此处... 这是通过提交表单来跳转的方法,表单中的信息也会随之传过去 用以上三种方法 -
springMVC中的@ModelAttribute注解
2020-12-30 19:58:50springMVC小总结 ...当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。 这句话的理解:比如说数据库中有一个user表,表中有三个字段(name,age,birthday),并且有一条 n -
基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)
2011-03-12 10:44:33更好交流,在信息时代人们通过个人空间沟通也用来但不能在自己的博客主页面中提交评论和留言。。这样在本系统中就可以为博友提供更多的个人色彩。在管理页面中添加和删除友情连接。这样博友可以在自己空间中快速定位... -
MyEclipse控制台中文乱码解决
2014-08-21 15:29:45乱码问题在项目中会经常见到,今天我也遇到一个,不是表单提交乱码,也不是页面乱码,而是MyEclipse控制台乱码,虽然不影响程序,但还是会影响到debug和开发。 于是上网找了些资料 关键词:MyEclipse 控制台乱码 ... -
ASP.NET的网页代码模型及生命周期
2009-07-28 14:22:11Cookie在客户端用户保存网站的少量的用户信息,服务器可以通过编程的方法获取用户信息,Cookie信息和页面请求通常一起发送到服务器,服务器对客户端传递过来的Cookie信息做处理。通常Cookie保存用户的登录状态、... -
数据库系统基础:高级篇(第5版)(讲述数据库系统原理的经典教材)--详细书签版
2013-04-05 14:33:1112.5 其他数据挖掘问题的方法 248 12.5.1 序列模式的发现 248 12.5.2 时间序列中模式的发现 248 12.5.3 回归 249 12.5.4 神经网络 249 12.5.5 遗传算法 249 12.6 数据挖掘的应用 250 ... -
事务处理原理 第2版
2012-12-30 10:49:38本书介绍事务处理,旨在满足广大读者的需要,包括以下读者。 ·有兴趣构建事务处理应用程序的应用程序编程人员。 ·管理用于事务处理的数据库系统的数据库管理员。 ·设计要部署在事务处理系统上的应用... -
ExtAspNet_v2.3.2_dll
2010-09-29 14:37:08-修正IE7下不能以下划线作为CSS中类名的前缀的BUG(feedback:Steve.Wei)。 -添加定时器控件Timer,用来定时发起AJAX请求。 +2009-09-06 v2.1.0 -Button的Pressed属性值能够正确的反映客户端的变化。 -优化... -
easyui页面显示,就是在主页面显示另一个页面,那个页面没有完整的显示出来,但是在地址栏上输入那个页面的...
2020-03-04 21:53:27//表单二中图片的回显,不是用append方法,是因为每次点击修改就会加一个图片,故只用文本显示方法html $("#sp1").html("<img src='images/"+result.url+"'width='80px'/>") //点击保存时,实现修改... -
ExtAspNet v2.2.1 (2009-4-1) 值得一看
2010-04-01 09:41:27-修正IE7下不能以下划线作为CSS中类名的前缀的BUG(feedback:Steve.Wei)。 -添加定时器控件Timer,用来定时发起AJAX请求。 +2009-09-06 v2.1.0 -Button的Pressed属性值能够正确的反映客户端的变化。 -优化... -
Spring面试题
2015-05-06 07:19:39-(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中; -(3)根据配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate()方法; -(4)如果... -
正则表达式
2014-12-03 14:51:39JavaScript的RegExp对象和String对象定义了使用正则表达式来执行强大的模式匹配和文本检索与替换函数的方法. 在JavaScript中,正则表达式是由一个RegExp对象表示的.当然,可以使用一个RegExp()构造函数来创建RegExp... -
设计的算法都是自己编写的,可能存在不是最优算法的情况。 二、设计正文 1 需求分析 建立一个用户可以自由交易的平台,通过ajax实现局部刷新,实现网站更具人性化,具有更良好的互动。以下是总体需求 1.1 通过...
-
2019年3月/4月迭代计划
2021-01-06 15:51:06#1615</li><li>[x] 附件下载标签完善 #1826</li><li>[x] 提交表单插件——字段管理导入导出 #466</li><li>[x] 提交表单插件——新增日期格式及时间格式 #466</li><li>[x] 删除栏目时栏目下的内容应该进入回收站... -
这个能力是在1.1.3开始增加的,也是本次升级的一个亮点,增加拼装URL的方法,比如服务器是RESTFUL风格的API,请求用户信息时可能是这样一个URL: http://api.nohttp.net/rest/<userid>/userinfo 这里的<...
-
缓存使用点我:对需要加入缓存的方法上添加@Cacheable(value="cache_name")注解即可,同时需要在对应的方法上加上更新或删除缓存注解@CacheEvict(value = "cache_name", allEntries = true);也可以使用redisTemplate...
-
ABB机器人CCLink 配置.pdf
-
sql的fuzz.txt
-
新浪微博app登陆软件
-
Map集合
-
springmvc拦截器原理
-
C_json解析库,让数据传输更简单
-
牛牛量化策略交易
-
springboot之启动原理解析及源码阅读
-
Python启蒙到架构师的核心技术精讲课程
-
MMM 集群部署实现 MySQL 高可用和读写分离
-
doxia-core-1.0-alpha-9.2y.jar
-
【Python-随到随学】 FLask第一周
-
聊天室工程实践.docx
-
迪文DGUS屏开发指南 v44.pdf
-
找完数
-
NFS 实现高可用(DRBD + heartbeat)
-
3.定时器中断延时.rar
-
基于Flink+Hudi构建企业亿级云上实时数据湖教程(PC、移动、小
-
2020-12-02版的带桌面树莓派系统镜像
-
city-picker.rar