1.获取前端表单提交的数据
Map<String,String[]> map = getRequest().getParameterMap();
for (String key : map.keySet()) {
System.out.println(key + ":" + Arrays.toString(map.get(key)));
}
2.查询数据库一定时间内的数据
SELECT * from login_fail where LOGIN_TIME >= STR_TO_DATE('2023-11-14', '%Y-%m-%d')
-- and LOGIN_TIME <= STR_TO_DATE('2023-11-14 23:59:59', '%Y-%m-%d %H:%i:%s')
;
SELECT * from login_fail where LOGIN_TIME >= now();
3.10分钟内登录5次限制10分钟后登录
@Controller
@Scope("prototype")
public class LoginAction extends BaseAction {
public static final String LOGIN_KEY_AES = StringUtil.nvlTrim(SystemParameter.getParamValue("loginPageEncryptKey")); //aes前端密码加密key,必须为16位
public static final String LOGIN_KEY_SM4 = StringUtil.nvlTrim(SystemParameter.getParamValue("loginMethodEncryptKey")); //sm4密码加密key
public static final String PRIVATE_KEY = StringUtil.nvlTrim(SystemParameter.getParamValue("login.private_key"));
public static final String PUBLIC_KEY = StringUtil.nvlTrim(SystemParameter.getParamValue("login.public_key"));
public static final String LIMIT_IPS = StringUtil.nvlTrim(SystemParameter.getParamValue("limitIps"));
@Autowired
private IUserService userService;
private String username;
private String password;
private String authcode = null;
private String loginPageEncrpyKey;
private String p;
private String d;
public String execute() {
try {
loginPageEncrpyKey = LOGIN_KEY_AES;
if (!isPost()) {
p = PUBLIC_KEY;
String ip = LocalThreadLocal.getRemoteIpAddress();
if(LIMIT_IPS.contains(ip)){
return view("login");
}else{
return output("禁止访问");
}
}
this.username = (this.username == null ? "" : this.username.trim());
this.password = (this.password == null ? "" : this.password);
this.authcode = (this.authcode == null ? "" : this.authcode.trim());
if ((this.username.equals("")) || (this.password.equals(""))) {
setFlashMessage("用户名、密码不能为空!");
p = PUBLIC_KEY;
return "login";
}
if(!authcode.equalsIgnoreCase(StringUtil.nvlTrim(getSession().get(AUTH_CODE_NAME)))) {
p = PUBLIC_KEY;
setFlashMessage("验证码不正确!");
return view("login");
}
User u = null;
if("true".equalsIgnoreCase(SystemParameter.getParamValue("debug"))) {
u = this.userService.login(this.username);
} else {
u = this.userService.login(this.username, MD5Util.getSM4EncryptDataByAESPass(username, password,p));
}
System.out.println(MD5Util.getSM4EncryptDataByAESPass(username, password,p));
if(u == null) {
/** 登录失败前置条件
//建一张表记录登录失败的次数
1,查当前时间与登录时间的差值在十分钟内的数据,查询到的话且次数小于5,累计次数,
未查询到的话新增
//select logintime from t (List)
/**
* if(select res = null) insert 当前用户的登录失败信息
* else{
* 遍历集合 -当前时间-登陆时间 < 5 times+1
* }if(times == 5)==>set 更新当前时间
2,如果次数等于5次,将当前数据的登录时间更新成当前时间
*/
System.out.println("用户ID"+userService.login(username).getId());
//username查userId
Integer userId = userService.login(username).getId();
List<LoginFail> loginFailList = userService.userLoginFailMes(userId);
//Date userLoginTime = loginFails.get(0).getLoginTime();
//System.out.println("userLoginTime"+userLoginTime);
LoginFail loginFail = new LoginFail();
if(loginFailList.isEmpty()){
//新增当前用户登录失败的信息
// loginFail.setId(UUID.randomUUID().toString());
loginFail.setUserId(userId);
loginFail.setLoginTime(new Date());
loginFail.setTimes(1);
userService.saveUserLoginFail(loginFail);
//-----新增
}else{
System.out.println("进入else");
Date loginTime = loginFailList.get(0).getLoginTime();
System.out.println(new Date().getTime()-loginTime.getTime());
loginFailList.get(0).setTimes(loginFailList.get(0).getTimes()+1);
if (loginFailList.get(0).getTimes() == 5){
loginFailList.get(0).setLoginTime(new Date());
}
userService.saveUserLoginFail(loginFailList.get(0));
if (loginFailList.get(0).getTimes() > 5){
setFlashMessage("此用户被禁用或正在申报中,无法登陆!");
p = PUBLIC_KEY;
return "login";
}
}
/** 后置条件
3,查当前时间与登录时间的差值在十分钟内的数据,如果累计次数大于5,提示您登录的失败次数过多,请十分钟后再登录
*/
setFlashMessage("用户名或密码错误。");
p = PUBLIC_KEY;
return "login";
}
if ((u.getState() != null) && (!"1".equals(u.getState()))) {
setFlashMessage("此用户被禁用或正在申报中,无法登陆!");
p = PUBLIC_KEY;
return "login";
}
//System.out.println("有效期限:"+u.getPASSWORD_TERM());
if(u.getPASSWORD_TERM() != null){
if(DateUtil.compareDateDay(DateUtil.dateToString(new Date(), "yyyy-MM-dd"), DateUtil.dateToString(u.getPASSWORD_TERM(), "yyyy-MM-dd")) > 90L){
setFlashMessage("此用户密码已过期!");
p = PUBLIC_KEY;
return "login";
}
}
u.setLastLoginIp(getRequest().getRemoteAddr());
u.setLastLoginTime(DateUtil.getDateString(new Date(),
"yyyy-MM-dd HH:mm:ss"));
this.userService.update(u);
u = this.userService.getByIdWithAuthInfo(u.getId());
this.session.put("currentUser", u);
return "success";
} catch (Exception e) {
e.printStackTrace();
this.logger.error(e.getMessage());
}
p = PUBLIC_KEY;
return "login";
}
/**
* 管理员登录
* @return
*/
public String sys() {
try {
loginPageEncrpyKey = LOGIN_KEY_AES;
if (!isPost()) {
p = PUBLIC_KEY;
String ip = LocalThreadLocal.getRemoteIpAddress();
if(LIMIT_IPS.contains(ip)){
return view("login_sys");
}else{
return output("禁止访问");
}
}
this.username = (this.username == null ? "" : this.username.trim());
this.password = (this.password == null ? "" : this.password);
this.authcode = (this.authcode == null ? "" : this.authcode.trim());
if ((this.username.equals("")) || (this.password.equals(""))) {
setFlashMessage("用户名、密码不能为空!");
p = PUBLIC_KEY;
return view("login_sys");
}
if(!authcode.equalsIgnoreCase(StringUtil.nvlTrim(getSession().get(AUTH_CODE_NAME)))) {
p = PUBLIC_KEY;
setFlashMessage("验证码不正确!");
return view("login_sys");
}
User u = null;
if("true".equalsIgnoreCase(SystemParameter.getParamValue("debug"))) {
u = this.userService.login(this.username);
} else {
u = this.userService.login(this.username, MD5Util.getSM4EncryptDataByAESPass(username, password,p));
}
if(u == null) {
setFlashMessage("用户名或密码错误。");
p = PUBLIC_KEY;
return view("login_sys");
}
if ((u.getState() != null) && (!"1".equals(u.getState()))) {
setFlashMessage("此用户被禁用或正在申报中,无法登陆!");
p = PUBLIC_KEY;
return view("login_sys");
}
u.setLastLoginIp(getRequest().getRemoteAddr());
u.setLastLoginTime(DateUtil.getDateString(new Date(), "yyyy-MM-dd HH:mm:ss"));
this.userService.update(u);
u = this.userService.getByIdWithAuthInfo(u.getId());
this.session.put("currentUser", u);
return "success";
} catch (Exception e) {
e.printStackTrace();
this.logger.error(e.getMessage());
}
p = PUBLIC_KEY;
return view("login_sys");
}
//----------------------------------------------getter && setter-------------------------------------------------------------
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAuthcode() {
return this.authcode;
}
public void setAuthcode(String authcode) {
this.authcode = authcode;
}
public String getLoginPageEncrpyKey() {
return loginPageEncrpyKey;
}
public void setLoginPageEncrpyKey(String loginPageEncrpyKey) {
this.loginPageEncrpyKey = loginPageEncrpyKey;
}
public String getP() {
return p;
}
public void setP(String p) {
this.p = p;
}
public String getD() {
return d;
}
public void setD(String d) {
this.d = d;
}
}
4.获取CodeType方法
public String toCollectionClue(){
codeList = icodeService.getByCatAndCodeEnable("XSLX","1");
return view("collectionClueView");
}
5.dao层获取实体类没有的字段clue_type_NAME
要加@Transient注解
public TWebsiteConsultation getCollectionClueById(String Id){
List<Object> paramsList = new ArrayList<>();
String sql = "SELECT\n" +
" t.*,\n" +
" c.`NAME` clue_type_NAME\n" +
"FROM\n" +
" t_website_consultation t \n" +
" INNER JOIN t_code c on c.CODE_CATEGORY = 'XSLX' and c.`STATUS` = '1' and t.CLUE_TYPE = c.`CODE`\n" +
"WHERE\n" +
" t.TYPE = '3' \n" +
" AND t.STATUS = '1'";
if(!StringUtil.isNvl(Id)){
sql += "and t.id = ? ";
paramsList.add(Id);
}
return CollectionUtil.firstOrNull(findBySQLQueryWithTransient(ht, sql, paramsList.toArray(), TWebsiteConsultation.class));
}
6.return view() 和return output的区别
在Struts 2框架中,`return view()`和`return output()`是用于指定一个结果视图的两种不同方式,它们具有不同的区别和作用:
1. return view()
作用:return view()用于指定一个结果视图,该视图会被渲染并返回给客户端进行展示。
区别:`view`结果类型会在配置文件(如struts.xml)中定义,并与一个具体的JSP或其他视图模板关联。在`view`结果类型中,会根据配置的视图路径和名称,找到对应的视图进行渲染和返回。
2. return output()
作用:return output()用于将一个字符串或其他类型的数据直接输出到HTTP响应中,而不经过视图渲染。
区别:output结果类型不需要配置视图,它会直接将返回的结果数据作为响应的内容发送给客户端。这种方式通常用于返回纯文本、JSON、XML等数据格式的响应,而不需要经过视图的呈现。
总结:
return view()用于指定一个结果视图,在配置文件中定义了与之相关联的JSP或其他视图模板,用于渲染并返回给客户端展示。
return output()用于直接将一个字符串或其他类型的数据作为HTTP响应的内容发送给客户端,不经过视图渲染。
选择使用哪种方式取决于你的业务需求,如果需要呈现页面视图,使用`return view()`;如果只需要返回数据,而不需要经过视图渲染,使用`return output()`。
7.查询非持久化字段映射到实体的方法
/**
* <p>
* SQL查询List,查询时可同时查出非持久化的字段
* </p>
* <pre>
* 例子:
* String sql = "select t.*,a.user_type user_type " +
* "from log_op t, t_users a " +
* "where t.user_id = a.user_id " +
* " and t.user_id = ? " +
* "order by t.oper_time desc";
* List list = findBySQLQueryWithTransient(sql, new Object[]{'admin'}, LogOp.class);
* return (List< LogOp >)list;
* </pre>
* @param fsql 查询的SQL
* @param args 参数
* @param fclazz 查询结果映射的Entity
* @return <p>查询结果List<br/>若指定了查询结果映射的Entity,则返回的是List的Entity<br/>否则返回List< Map< String, Object > >(KEY大写)</p>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected <T> List<T> findBySQLQueryWithTransient(
final HibernateTemplate ht,
final String fsql, final Object[] args, final Class<T> fclazz){
return (List)ht.execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
SQLQuery q = session.createSQLQuery(fsql);
if(fclazz != null){
//q.addEntity(clazz);
q.setResultTransformer(new LocalAliasToBeanResultTransformer(fclazz));
}else{
// q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
q.setResultTransformer(new LocalAliasToMapResultTransformer());
}
for(int i=0; args!=null&&args.length>0&&i<args.length; i++){
if(args[i] != null){
if(args[i] instanceof Long){
q.setLong(i, (Long)args[i]);
}else if(args[i] instanceof Date) {
q.setTimestamp(i, (Date)args[i]);
}else{
q.setParameter(i, args[i]);
}
}else{
q.setParameter(i, args[i]);
}
}
if(fclazz != null){
return q.list();
}else{
return toUpperCase(q.list());
}
}
});
}
8.后端获取前端的get请求的id参数
前端:
后端:
public String toCollectionClueDetail() {
String id = getRequest().getParameter("id");
if(StringUtil.isNvl(id)){ //对ID做判空处理
return view("collectionClue_detail");
}
consult = service.getCollectionClueById(id);
if(consult == null){
return view("collectionClue_detail");
}
return view("collectionClue_detail");
}
9.省市区联动原理
在页面加载的时候调用province方法。
function province(){
var pcode = $("#s_province").val();
if (pcode == "") {
$("#s_city").empty();
$("#s_county").empty();
$("#s_city").append("<option value=''>---请选择---</option>");
$("#s_county").append("<option value=''>---请选择---</option>");
return false;
}
var url= "<%=basePath%>supplier/SupplierBasicUpdate_doCityNew.do?pcode="+pcode;
dhtmlxAjax.post(url,"",function(data){
var response = data.xmlDoc.responseText;
if(response != null && response !=""){
var obj = eval("("+response+")");
$("#s_city").empty();
$.each(obj,function(key,v){
if(dfxzqh != null && dfxzqh != "" && v.code.substring(0,4) == dfxzqh.substring(0,4)){
$("#s_city").append("<option value='"+v.code+"' selected>"+v.name+"</option>");
}else{
$("#s_city").append("<option value='"+v.code+"'>"+v.name+"</option>");
}
});
city();
}
});
}
function city(){
var pcode = $("#s_city").val();
var url= "<%=basePath%>supplier/SupplierBasicUpdate_doCountyNew.do?pcode="+pcode;
dhtmlxAjax.post(url,"",function(data){
var response = data.xmlDoc.responseText;
if(response != null && response !=""){
var obj = eval("("+response+")");
$("#dfXzqh").empty();
$.each(obj,function(key,v){
if(dfxzqh != null && dfxzqh != "" && v.code == dfxzqh){
$("#dfXzqh").append("<option value='"+v.code+"' selected>"+v.name+"</option>");
}else{
$("#dfXzqh").append("<option value='"+v.code+"'>"+v.name+"</option>");
}
});
}
});
}
<td class="tab_h" >
<label style="color: red;">*</label>行政区划:</td>
<td align="left" >
省份:<select class="select_" style="width: 120px;" id="s_province" name="s_province" onchange="province();">
<s:if test="factory.dfXzqh == null || factory.dfXzqh ==''">
<option value="">---请选择---</option>
</s:if>
<s:iterator value="provinceList">
<option value="<s:property value="code"/>"
<s:if test="factory.dfXzqh != null && factory.dfXzqh !='' && code.substring(0,3)==factory.dfXzqh.substring(0,3)">selected</s:if>>
<s:property value="name" />
</option>
</s:iterator>
</select>
城市:<select class="select_" style="width:120px;" id="s_city" name="s_city" onchange="city();">
<option value="">---请选择---</option>
</select>
区县:<select class="select_" style="width:120px;" id="dfXzqh" name="factory.dfXzqh">
<option value="">---请选择---</option>
</select>
</td>
</tr>
10.查省份
provinceList = regionService.findLocationNew("640000", null, "", "1");
String jsonArry = JsonUtil.beanToJsonForGrid(provinceList);
System.out.println(jsonArry);
省市区维护在一张表里
t_code_region
11.对象转json
String jsonArry = JsonUtil.beanToJsonForGrid(provinceList);
System.out.println(jsonArry);
12.sql映射非持久化字段时,没有将查出来的值映射到实体对象中
13.给DHTMLX设置删选框
14.js字符串替换函数
var isCommonId =brandInputId.replace("Name", "Id");
$("#"+brandInputId).val(BrandName);
15.mysql case then end 语句
SELECT
t.ID,
t.SFJK,
t.SFJK_NAME,
t.PLAN_NUMBER,
t.SECTION_ID,
t.ORDERING,
t.OBJECT_NAME,
t.req_id,
(CASE
WHEN t.FLAG_JN_QZCG='1' THEN '是'
WHEN t.FLAG_JN_QZCG='0' THEN '否'
END) AS FLAG_JN_QZCG,
(CASE
WHEN t.FLAG_JN_YXCG='1' THEN '是'
WHEN t.FLAG_JN_YXCG='0' THEN '否'
END) AS FLAG_JN_YXCG,
(CASE
WHEN t.FLAG_HB_QZCG='1' THEN '是'
WHEN t.FLAG_HB_QZCG='0' THEN '否'
END) AS FLAG_HB_QZCG,
(CASE
WHEN t.FLAG_HB_YXCG='1' THEN '是'
WHEN t.FLAG_HB_YXCG='0' THEN '否'
END) AS FLAG_HB_YXCG
FROM t_plan_item t
LEFT JOIN t_plan_item_asset a ON a.PLAN_ITEM_ID=t.id AND a.status='1'
WHERE t.status ='1'
AND t.GOODS_CATEGORY_CODE LIKE 'A%'
AND t.SECTION_ID='4028841f8a77c83207'
16.常用sql
SELECT * FROM `t_plan_item`
SELECT
t.ID,
t.PLAN_NUMBER,
t.GOODS_CATEGORY_ID,
t.GOODS_CATEGORY_NAME,
t.GOODS_CATEGORY_STRING,
t.BRAND_ID,
t.MODEL,
t.GOODS_NAME,
t.PRICE,
t.AMOUNT,
t.UNIT,
t.BUDGET_DEP,
t.BUDGET_ADD,
t.BUDGET_OVER,
t.BUDGET_SPECIAL,
t.BUDGET_SELF,
t.GOODS_CATEGORY_CODE,
t.SPECIAFICATION,
t.CREATOR,
t.CREATOR_NAME,
t.CREATE_TIME,
t.MODIFIER,
t.MODIFIER_NAME,
t.MODIFY_TIME,
t.`STATUS`,
t.NOTE,
t.TOTAL,
t.GOODS_ID,
t.GOODS_SNAPSHOT_ID,
t.PLATFORM_SOURCE,
t.GOODS_CHECK_FLAG,
t.SFJK,
t.SFJK_NAME,
t.FWNR,
t.FWQX,
t.XMMC,
t.XMGK,
t.SGGQ,
t.ZL,
t.XXCS,
t.SECTION_ID,
t.ORDERING,
t.OBJECT_NAME,
t.req_id,
t.FLAG_JN_QZCG,
t.FLAG_JN_YXCG,
t.FLAG_HB_QZCG,
t.FLAG_HB_YXCG,
t.FLAG_JN_QZCG_NAME,
t.FLAG_JN_YXCG_NAME,
t.FLAG_HB_QZCG_NAME,
t.FLAG_HB_YXCG_NAME,
a.ID asset_id,
a.PLAN_NUMBER,
a.PLAN_ITEM_ID,
a.GOODS_CATEGORY_CODE,
a.ASSET_YUSCODE,
a.ASSET_GBFL,
a.ASSET_GBFL_NAME,
a.ASSET_PEIZFL,
a.ASSET_PEIZFL_NAME,
a.ASSET_PEIZLB,
a.ASSET_PEIZLB_NAME,
a.ASSET_ZICMC,
a.ASSET_PEIZSL,
a.USE_PEIZSL,
a.ASSET_ZICDJ,
a.USE_ZICDJ,
a.ASSET_ZICJSCS
FROM t_plan_item t
left join t_plan_item_asset a on a.PLAN_ITEM_ID=t.id and a.status='1'
where t.status ='1'
and t.GOODS_CATEGORY_CODE like 'A%'
and t.SECTION_ID='4028841f8a77c832018a78daa1110007'
update t_plan_item set OBJECT_NAME='测试标段' where SECTION_ID = '4028841f8a77c832018a78daa1110007'
17.JQuery判断一个字符串是否包含另一个字符串
nameNew.indexOf("flagJnhb")
indexOf()
方法返回子字符串第一次出现的索引位置,如果不存在则返回-1。通过判断返回值是否大于等于0,可以确定子字符串是否存在于nameNew
中。
18.input和select选择器
$("#form input[name^='tyZjNoticeItemLA'],select[name^='tyZjNoticeItemLA']").each(function(){
var nameNew = $(this).attr("name");
if($(this).attr("type") != "hidden" && !$(this).prop("disabled")){
if($(this).val() == null || $(this).val().trim() == ""){
if(nameNew.indexOf("surveys") == -1 && nameNew.indexOf("jnhbzsbh") == -1 && nameNew.indexOf("jnhbzsEndTime") == -1 && nameNew.indexOf("hbzsbh") == -1 && nameNew.indexOf("hbzsEndTime") == -1 ){
alert("请完善标的信息!");
$(this).focus();
resultA = false;
return false;
}
}
if(nameNew.indexOf("flagJnhb") > 0){
if($(this).val() == "1"){
var num = $(this).attr("num");
var selector = "input[name='tyZjNoticeItemLA[" + num + "].jnhbzsbh']";
var jnhbzsVal = $(selector).val();
var jnhbEndTime = $("input[name='tyZjNoticeItemLA["+num+"].jnhbzsEndTime']").val();
if(jnhbzsVal == null || jnhbzsVal == ""){
alert("请完节能产品认证证书编号的信息!");
resultA = false;
return false;
}
if(jnhbEndTime == null || jnhbEndTime == ""){
alert("请完节能产品认证证书有效截止期的信息!");
resultA = false;
return false;
}
}
}
if(nameNew.indexOf("flagHb") > 0){
if($(this).val() == "1"){
var num = $(this).attr("num");
var hbzsVal = $("input[name='tyZjNoticeItemLA["+num+"].hbzsbh']").val();
var hbEndTime = $("input[name='tyZjNoticeItemLA["+num+"].hbzsEndTime']").val();
if(hbzsVal == null || hbzsVal == ""){
alert("请完环境标志产品认证证书编号的信息!");
resultA = false;
return false;
}
if(hbEndTime == null || hbEndTime == ""){
alert("请完环境标志产品认证证书有效截止期的信息");
resultA = false;
return false;
}
}
}
}
});
19.关于属性选择器中包含【】,是否要转义的问题
$("input[name='tyZjNoticeItemLA[" + num + "].jnhbzsbh']").attr("disabled", false);
对于包含在双引号内的属性选择器,中括号[]
不需要转义。
下面这种需要加转义字符:
var budgetSelector = "#tyZjNoticeItemL"+type +"\\[" + index + "\\]\\.budget";
var amountSelector = "#tyZjNoticeItemL"+type +"\\[" + index + "\\]\\.amount";
var budgetValue = $(budgetSelector).val();
var amountValue = $(amountSelector).val();