首页 > 其他分享 >Bootstrap框架----多条记录双文本(List)添加

Bootstrap框架----多条记录双文本(List)添加

时间:2023-08-08 12:33:43浏览次数:29  
标签:function return name Bootstrap List ---- var obj data


有时候我们需要实现双文本的多条记录录入,传给后台保存成List的结构。

界面交互设计如图:

Bootstrap框架----多条记录双文本(List)添加_交互设计


可动态添加行数,每行固定两个文本录入。

我们在之前的文章中已经在SpringMVC基础框架的基础上应用了BootStrap的后台框架,在此基础上记录 多条文本录入用法。
应用bootstrap模板

基础项目源码下载地址为:
SpringMVC+Shiro+MongoDB+BootStrap基础框架

我们在基础项目中已经做好了首页index的访问。
现在就在index.jsp页面和index的路由Controller上做修改,实现 双文本的多条记录录入,传给后台保存成List用法。

jsp页面

html代码

<div class="col-md-10 col-sm-10 col-xs-12 " style="margin-top: 30px">
     <form class="form-horizontal col-sm-6" id="channel">
                <!-- 其他联系人 -->
                <div class="form-group">
                    <label for="otherContacts" class="col-sm-2 control-label">其他联系人</label>
                    <div class="col-sm-8 input-group">
                    <table id="otherContants" class="table table-striped table-bordered" cellspacing="0" style="margin-bottom: 0;">
                        <thead>
                            <tr>
                              <th width="25%" class="text-center">姓名</th>
                              <th width="*" class="text-center">电话</th>
                              <th width="20%"></th>
                            </tr>
                        </thead>
                        <tbody id="contactBody">
                        </tbody>
                    </table>
                        <script type="text/template" id="tpl_contact">
                        <tr>
                            <td><input type="text" class="form-control"  value="{name}" name="name"></td>
                            <td><input type="text" class="form-control"  value="{tel}" name="tel" maxlength="11"></td>
                            <td class="text-center">
                                <button type="button" class="btn btn-default btn-sm row-add" title="添加行"><i class="fa fa-plus fa-fw"></i></button>
                                <button type="button" class="btn btn-default btn-sm row-del" title="删除行"><i class="fa fa-minus fa-fw"></i></button>
                            </td>
                        </tr>
                        </script>
                    </div>
                </div>
                <div class="form-group">
                <div class="col-sm-6 text-right">
                <button type="button" class="btn btn-default cancel" data-dismiss="modal">放弃</button>
                <button type="button" class="btn btn-primary save" data-loading-text="Saving...">确认</button>
                </div>
                </div>
            </form>
        </div>

js代码获取数据并传输

<script type="text/javascript">  
//基础函数开始
/**
 * 基础封装函数
 */
var _fnObjectGetPropertyChainValue = function(obj, propertyChain) {
  /* 获取属性链的值 */
  if (!obj) return;
  if (!propertyChain) return obj;
  var property,
    chains = propertyChain.split('.'),
    i = 0,
    len = chains.length;
  for (;
    (property = chains[i]) && i < len - 1; i++) {
    if (!obj[property]) return;
    obj = obj[property];
  }
  return obj[property];
},
_fnObjectSetPropertyChainValue = function(obj, propertyChain, value, allowMulti) {
  /* 设置属性链的值 */
  if (!obj || !propertyChain) return;
  var property,
    chainObj = obj,
    chains = propertyChain.split('.'),
    i = 0,
    len = chains.length;
  for (;
    (property = chains[i]) && i < len - 1; i++) {
    if (!chainObj[property]) {
      chainObj[property] = {};
    }
    chainObj = chainObj[property];
  }
  // 改进版:checkbox的多选可以组合为数组
  if (!allowMulti || chainObj[property] === undefined) {
    chainObj[property] = value;
  } else {
    var pv = chainObj[property];
    if ($.isArray(pv)) {
      pv.push(value);
    } else {
      chainObj[property] = [pv, value];
    }
  }
  return obj;
};
/**
 * 格式化字符串 第一个参数为格式化模板 format('this is a {0} template!', 'format');
 * format('this is a {0.message} template!', { message: 'format'}); 等同于
 * format('this is a {message} template!', { message: 'format' });
 */
$.format = function() {
var template = arguments[0],
  templateArgs = arguments,
  stringify = function(obj) {
    if (obj == null) {
      return '';
    } else if (typeof obj === 'function') {
      return obj();
    } else if (typeof obj !== 'string') {
      return JSON.stringify ? JSON.stringify(obj) : obj;
    }
    return obj;
  };
return template.replace(/\{\w+(\.\w+)*\}/g, function(match) {
  var propChains = match.slice(1, -1).split('.');
  var index = isNaN(propChains[0]) ? 0 : +propChains.shift();
  var arg, prop;
  if (index + 1 < templateArgs.length) {
    arg = templateArgs[index + 1];
    while (prop = propChains.shift()) {
      arg = arg[prop] == null ? '' : arg[prop];
    }
    return stringify(arg);
  }
  return match;
});
};



/**
 * jQuery form 扩展获取数据
 */
$.fn.formGet = function(opts) {
  opts = $.extend({}, opts);
  var data = {},
    els = opts.formGroup ? this.find('[form-group="' + opts.formGroup + '"]') : this.find('[name]');
  if (!els || !els.length) {
    return data;
  }

  var fnSetValue = (function(emptyToNull) {
    return emptyToNull ? function(obj, propertyChain, value, allowMulti) {
      value !== '' && _fnObjectSetPropertyChainValue(obj, propertyChain, value, allowMulti)
    } : _fnObjectSetPropertyChainValue
  })(opts.emptyToNull);

  els.each(function() {
    var $this = $(this),
      type = $this.attr('type'),
      name = $this.attr('name'), // 可能为属性链
      tag = this.tagName.toLowerCase();
    if (tag == 'input') {
      if (type == 'checkbox') {
        var v = $(this).val();
        if (v == 'on' || !v) {
          fnSetValue(data, name, $(this).prop('checked'));
        } else {
          $(this).prop('checked') && fnSetValue(data, name, v, true);
        }
      } else if (type == 'radio') {
        this.checked && fnSetValue(data, name, $this.val());
      } else {
        fnSetValue(data, name, $.trim($this.val()));
      }
    } else if ('|select|textarea|'.indexOf('|' + tag + '|') > -1) {
      fnSetValue(data, name, $this.val());
    } else {
      fnSetValue(data, name, $.trim($this.text()));
    }
  });
  return data;
};


/**
 * jQuery form 扩展绑定数据
 * 
 */
$.fn.formSet = function(data, formGroup) {
var els = formGroup ? this.find('[form-group="' + formGroup + '"]') : this.find('[name]');
if (!els || !els.length) {
  return this;
}
els.each(function() {
  var $this = $(this),
    type = $this.attr('type'),
    name = $this.attr('name'),
    tag = this.tagName.toLowerCase();
  var value = _fnObjectGetPropertyChainValue(data, name);
  if (tag == 'input') {
    if (type == 'checkbox') {
      var v = $(this).val();
      if (v == 'on' || !v) {
        this.checked = value ? 'checked' : '';
      } else {
        this.checked = $.isArray(value) && value.indexOf(v) > -1 ? 'checked' : ''
      }
    } else if (type == 'radio') {
      this.checked = $this.val() == String(value) ? 'checked' : '';
    } else {
      $this.val(value);
    }
  } else if ('|select|textarea|'.indexOf('|' + tag + '|') > -1) {
    $this.val(value);
  } else {
    $this.html(value);
  }
});
return this;
};
//基础函数结束
//业务代码开始
var $contactsBody = $('#contactBody'),
contactsTpl = $('#tpl_contact').html();
// 初始化其他联系人列表
(function (contacts) {
if (!contacts) {
    contacts = [{}];
}
var buffer = [];
for (var i = 0, contact; contact = contacts[i]; i++) {
$contactsBody.append($($.format(contactsTpl)).formSet(contact));
}
})(${cf:toJSON(channel.otherContacts)});



function _getContacts() {
var contacts = [];
$contactsBody.find('tr').each(function (index, ele) {
var row = $(ele).formGet();
if(row.name || row.tel){
if(!/^(1[0-9])\d{9}$/.test(row.tel)){
    alert("请输入正确的手机号.");
    return false;
}
contacts.push({"name":row.name,"tel":row.tel });
}
});
return contacts;
}
$contactsBody.on('click', '.row-del', function () {
    var $tr = $(this).closest('tr');
    if ($tr.parent().children().length == 1) return;
    $tr.remove();
  }).on('click', '.row-add', function () {
    var $tr = $(this).closest('tr').after($.format(contactsTpl, {}));
  });
$('button.save').on('click',function(){
       debugger;
       var data = $('#channel').formGet();


    if(_getContacts().length)
       data.otherContacts = _getContacts();
       console.log(data);
       $.ajax({
       type: "POST",
       url: "/channel/save",
       contentType: "application/json",
       data: JSON.stringify(data),
       success: function (result) {
         console.log(result);
         if (!result.code) {
           $('#channel').formSet(data);
           location.href = '/'
         }else{
                  alert(result.msg);
         }
       },
       error: function (result) {
         alert("出错了,请稍后重试");
       }
     });
    });
</script>

cf是jsp自定义标签
不了解的同学可以参考
jsp自定义标签—–EL表达式中连接两个字符串

新建tags.tld文件如下:

<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">

    <description>23mofang custom JSTL 1.1 tag library</description>
    <display-name>JSTL functions</display-name>
    <tlib-version>1.1</tlib-version>
    <short-name>cf</short-name>
    <uri>com.data.web.view.function</uri>
    <function>
        <description>对象序列化为json字符串</description>
        <name>toJSON</name>
        <function-class>com.test.util.JSONUtils</function-class>
        <function-signature>java.lang.String toJSONString(java.lang.Object)</function-signature>
    </function>
</taglib>

对应的JSONUtils文件如下:

package com.test.util;

import com.alibaba.fastjson.JSON;

/**
 * JSONUtils
 * 
 */
public final class JSONUtils {

    /**
     * 
     * @param object
     * @return
     */
    public static String toJSONString(Object object) {
        return JSON.toJSONString(object);
    }

    /**
     * 
     * @param json
     * @param clazz
     * @return
     */
    public static <T> T parseJSON(String json, Class<T> clazz) {
        return JSON.parseObject(json, clazz);
    }
}

作用是把List转换为Json。

在index.jsp页面引入JSP自定义标签cf使用代码:

<%@ taglib prefix="cf" uri="com.data.web.view.function" %>

这里的prefix值与tags.tld文件中short-name的值对应,uri值与tags.tld文件中uri的值对应。

完整jsp代码如下:

<%@ include file="./include/header.jsp"%>  
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
<%@ taglib prefix="cf" uri="com.data.web.view.function" %>  
        <div id="page-wrapper">  
            <div id="page-inner">  
                <div class="row">  
                    <div class="col-md-12">  
                        <h1 class="page-header">  
              多条记录多文本录入 <small>示例</small>  
                        </h1>  
                    </div>  
                </div>  
                <!-- /. ROW  -->  
     <div class="col-md-10 col-sm-10 col-xs-12 " style="margin-top: 30px">
     <form class="form-horizontal col-sm-6" id="channel">
                <!-- 其他联系人 -->
                <div class="form-group">
                    <label for="otherContacts" class="col-sm-2 control-label">其他联系人</label>
                    <div class="col-sm-8 input-group">
                    <table id="otherContants" class="table table-striped table-bordered" cellspacing="0" style="margin-bottom: 0;">
                        <thead>
                            <tr>
                              <th width="25%" class="text-center">姓名</th>
                              <th width="*" class="text-center">电话</th>
                              <th width="20%"></th>
                            </tr>
                        </thead>
                        <tbody id="contactBody">
                        </tbody>
                    </table>
                        <script type="text/template" id="tpl_contact">
                        <tr>
                            <td><input type="text" class="form-control"  value="{name}" name="name"></td>
                            <td><input type="text" class="form-control"  value="{tel}" name="tel" maxlength="11"></td>
                            <td class="text-center">
                                <button type="button" class="btn btn-default btn-sm row-add" title="添加行"><i class="fa fa-plus fa-fw"></i></button>
                                <button type="button" class="btn btn-default btn-sm row-del" title="删除行"><i class="fa fa-minus fa-fw"></i></button>
                            </td>
                        </tr>
                        </script>
                    </div>
                </div>
                <div class="form-group">
                <div class="col-sm-6 text-right">
                <button type="button" class="btn btn-default cancel" data-dismiss="modal">放弃</button>
                <button type="button" class="btn btn-primary save" data-loading-text="Saving...">确认</button>
                </div>
                </div>
            </form>
        </div>
        <!-- /. ROW  -->   
            </div>  
            <!-- /. PAGE INNER  -->  
        </div>  
        <!-- /. PAGE WRAPPER  -->  
 <%@ include file="./include/footer.jsp"%>  
<script type="text/javascript">  
//基础函数开始
/**
 * 基础封装函数
 */
var _fnObjectGetPropertyChainValue = function(obj, propertyChain) {
  /* 获取属性链的值 */
  if (!obj) return;
  if (!propertyChain) return obj;
  var property,
    chains = propertyChain.split('.'),
    i = 0,
    len = chains.length;
  for (;
    (property = chains[i]) && i < len - 1; i++) {
    if (!obj[property]) return;
    obj = obj[property];
  }
  return obj[property];
},
_fnObjectSetPropertyChainValue = function(obj, propertyChain, value, allowMulti) {
  /* 设置属性链的值 */
  if (!obj || !propertyChain) return;
  var property,
    chainObj = obj,
    chains = propertyChain.split('.'),
    i = 0,
    len = chains.length;
  for (;
    (property = chains[i]) && i < len - 1; i++) {
    if (!chainObj[property]) {
      chainObj[property] = {};
    }
    chainObj = chainObj[property];
  }
  // 改进版:checkbox的多选可以组合为数组
  if (!allowMulti || chainObj[property] === undefined) {
    chainObj[property] = value;
  } else {
    var pv = chainObj[property];
    if ($.isArray(pv)) {
      pv.push(value);
    } else {
      chainObj[property] = [pv, value];
    }
  }
  return obj;
};
/**
 * 格式化字符串 第一个参数为格式化模板 format('this is a {0} template!', 'format');
 * format('this is a {0.message} template!', { message: 'format'}); 等同于
 * format('this is a {message} template!', { message: 'format' });
 */
$.format = function() {
var template = arguments[0],
  templateArgs = arguments,
  stringify = function(obj) {
    if (obj == null) {
      return '';
    } else if (typeof obj === 'function') {
      return obj();
    } else if (typeof obj !== 'string') {
      return JSON.stringify ? JSON.stringify(obj) : obj;
    }
    return obj;
  };
return template.replace(/\{\w+(\.\w+)*\}/g, function(match) {
  var propChains = match.slice(1, -1).split('.');
  var index = isNaN(propChains[0]) ? 0 : +propChains.shift();
  var arg, prop;
  if (index + 1 < templateArgs.length) {
    arg = templateArgs[index + 1];
    while (prop = propChains.shift()) {
      arg = arg[prop] == null ? '' : arg[prop];
    }
    return stringify(arg);
  }
  return match;
});
};



/**
 * jQuery form 扩展获取数据
 */
$.fn.formGet = function(opts) {
  opts = $.extend({}, opts);
  var data = {},
    els = opts.formGroup ? this.find('[form-group="' + opts.formGroup + '"]') : this.find('[name]');
  if (!els || !els.length) {
    return data;
  }

  var fnSetValue = (function(emptyToNull) {
    return emptyToNull ? function(obj, propertyChain, value, allowMulti) {
      value !== '' && _fnObjectSetPropertyChainValue(obj, propertyChain, value, allowMulti)
    } : _fnObjectSetPropertyChainValue
  })(opts.emptyToNull);

  els.each(function() {
    var $this = $(this),
      type = $this.attr('type'),
      name = $this.attr('name'), // 可能为属性链
      tag = this.tagName.toLowerCase();
    if (tag == 'input') {
      if (type == 'checkbox') {
        var v = $(this).val();
        if (v == 'on' || !v) {
          fnSetValue(data, name, $(this).prop('checked'));
        } else {
          $(this).prop('checked') && fnSetValue(data, name, v, true);
        }
      } else if (type == 'radio') {
        this.checked && fnSetValue(data, name, $this.val());
      } else {
        fnSetValue(data, name, $.trim($this.val()));
      }
    } else if ('|select|textarea|'.indexOf('|' + tag + '|') > -1) {
      fnSetValue(data, name, $this.val());
    } else {
      fnSetValue(data, name, $.trim($this.text()));
    }
  });
  return data;
};


/**
 * jQuery form 扩展绑定数据
 * 
 */
$.fn.formSet = function(data, formGroup) {
var els = formGroup ? this.find('[form-group="' + formGroup + '"]') : this.find('[name]');
if (!els || !els.length) {
  return this;
}
els.each(function() {
  var $this = $(this),
    type = $this.attr('type'),
    name = $this.attr('name'),
    tag = this.tagName.toLowerCase();
  var value = _fnObjectGetPropertyChainValue(data, name);
  if (tag == 'input') {
    if (type == 'checkbox') {
      var v = $(this).val();
      if (v == 'on' || !v) {
        this.checked = value ? 'checked' : '';
      } else {
        this.checked = $.isArray(value) && value.indexOf(v) > -1 ? 'checked' : ''
      }
    } else if (type == 'radio') {
      this.checked = $this.val() == String(value) ? 'checked' : '';
    } else {
      $this.val(value);
    }
  } else if ('|select|textarea|'.indexOf('|' + tag + '|') > -1) {
    $this.val(value);
  } else {
    $this.html(value);
  }
});
return this;
};
//基础函数结束
//业务代码开始
var $contactsBody = $('#contactBody'),
contactsTpl = $('#tpl_contact').html();
// 初始化其他联系人列表
(function (contacts) {
if (!contacts) {
    contacts = [{}];
}
var buffer = [];
for (var i = 0, contact; contact = contacts[i]; i++) {
$contactsBody.append($($.format(contactsTpl)).formSet(contact));
}
})(${cf:toJSON(channel.otherContacts)});



function _getContacts() {
var contacts = [];
$contactsBody.find('tr').each(function (index, ele) {
var row = $(ele).formGet();
if(row.name || row.tel){
if(!/^(1[0-9])\d{9}$/.test(row.tel)){
    alert("请输入正确的手机号.");
    return false;
}
contacts.push({"name":row.name,"tel":row.tel });
}
});
return contacts;
}
$contactsBody.on('click', '.row-del', function () {
    var $tr = $(this).closest('tr');
    if ($tr.parent().children().length == 1) return;
    $tr.remove();
  }).on('click', '.row-add', function () {
    var $tr = $(this).closest('tr').after($.format(contactsTpl, {}));
  });
$('button.save').on('click',function(){
       debugger;
       var data = $('#channel').formGet();


    if(_getContacts().length)
       data.otherContacts = _getContacts();
       console.log(data);
       $.ajax({
       type: "POST",
       url: "/channel/save",
       contentType: "application/json",
       data: JSON.stringify(data),
       success: function (result) {
         console.log(result);
         if (!result.code) {
           $('#channel').formSet(data);
           location.href = '/'
         }else{
                  alert(result.msg);
         }
       },
       error: function (result) {
         alert("出错了,请稍后重试");
       }
     });
    });
</script>  
</body>  
</html>

java代码

在jsp页面代码中,初始化赋值时使用了channel.otherContacts。Channel实体如下:

package com.test.domain.entity;

import java.util.Date;
import java.util.List;

public class Channel {
    private String id;
    private String name;// 名字
    private int category;// 类别
    private String affiliation;// 归属
    private String address;// 地址
    private List<Contacts> otherContacts;// 其他联系人
    private String remarks;// 备注
    private int status;// 状态
    private Date createTime;// 新增时间

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getCategory() {
        return category;
    }

    public void setCategory(int category) {
        this.category = category;
    }

    public String getAffiliation() {
        return affiliation;
    }

    public void setAffiliation(String affiliation) {
        this.affiliation = affiliation;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public List<Contacts> getOtherContacts() {
        return otherContacts;
    }

    public void setOtherContacts(List<Contacts> otherContacts) {
        this.otherContacts = otherContacts;
    }

    public String getRemarks() {
        return remarks;
    }

    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

}

Contacts实体如下:

package com.test.domain.entity;


public class Contacts {
    private String name;// 姓名
    private String tel;// 电话
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getTel() {
        return tel;
    }
    public void setTel(String tel) {
        this.tel = tel;
    }
}

Controller代码接收实体代码如下:

package com.test.web.controller;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.test.domain.entity.Channel;
import com.test.web.message.response.JSONResult;

/**
 * IndexController
 * 
 * 
 */
@Controller
public class IndexController {

    @Autowired
    MongoTemplate mongoTemplate;

    DateFormat fmt =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");



    @RequestMapping("/")
    public String index(Model model) throws IOException {
        return "/index";
    }

    @RequestMapping("/channel/save")
    @ResponseBody
    public JSONResult saveChannel(@RequestBody Channel channel) {
        int result=upsertChannel(channel);
        return  result>0?JSONResult.success(channel): JSONResult.error("手机号已存在,保存失败");
    }

    private int upsertChannel(Channel channel) {
        System.out.println(channel.getOtherContacts().size());
        return 1;
    }
}


标签:function,return,name,Bootstrap,List,----,var,obj,data
From: https://blog.51cto.com/u_16218512/7007131

相关文章

  • kettle案例九-----linux使用kettle
    我们之前学习的kettle操作都是在windows中进行可视化的操作,但是在使用过程中发现一些问题。比如我们的数据文件是放在linux服务器中的,如果要清洗则需要把它们下载到本地,这样需要耗费一些时间,尤其是数据文件比较大时。解决方案就是我们直接在linux服务器中运行kettle进行抽取。......
  • 常见错误
    常见错误主类名和文件名不一致......
  • LIBSVM简介及其使用方法
    LIBSVM简介及其使用方法(台湾大学林智仁(LinChih-Jen)副教授等)libsvm,林智仁libsvm官方网站:WelcometoChih-JenLin'sHomePagehttp://www.csie.ntu.edu.tw/~cjlin/http://www.csie.ntu.edu.tw/~cjlin/libsvm可以在此网站下载相关软件。selecedfrom:支持向量......
  • hadoop组件---数据仓库(五)---通过JDBC连接hive的thrift或者hiveserver2
    我们在上一篇文章中已经学习了Hive的常用命令,但是如果使用其他的语言如何跟Hive进行交互呢。Thrift简介Hive拥有HiveServer(Thrift)或者Hiveserver2组件,提供了JDBC驱动服务,使得我们可以用Java代码或者Python来连接Hive并进行一些关系型数据库的sql语句查询等操作。HiveServer或者Hi......
  • Nginx实现静态资源服务器
    我们在上一篇文章中已经分析了实现静态资源服务器的多种思路。本篇文章记录使用Nginx实现静态资源服务器的步骤。首先需要安装Nginx和了解Nginx的配置文件。CentOS系统可参考如下帖子:Nginx-------Nginx的安装和多域名配置Nginx安装好能正常运行后我们来尝试配置静态资源服务器。......
  • PPT| APS高级计划与排产解决方案 P116
    PPT共116页,由于篇幅有限,以下为部分资料.......
  • linux测试网络速度
    大家都知道,Linux界面基本都是命令行模式,但是命令行模式也可以测试网速,我们就要用这个工具:speedtest,linux上的版本是基于python开发的。1、是从githup上下载的这个工具,所以我们需要在linux上要安装git命令客户端,最简单的方法是用yum来安装,[root@localhost~]#yum-yinstallgit2、......
  • 跟风,分享一下,我常去的中文技术网站(转了)
    第一个当然是jvm虚拟机作者的博客了ITeyeUI招聘IBM.net先说一下大多数人都知道的。 第一个:http://www.iteye.com(www.iteye.com) 不解释。 第二个:(英文主站:www.infoq.com) 非常著名的架构师站点,主要面向企业架构,做JaveEE方向的同学应该经常看。 第三个:......
  • java多线程编程基础4--正确使用 Volatile 变量
    记住一点就是:对数据的操作是分三步:1.从内存从拿过来2.更改数据3.写入内存 还需要记住一点就是:我们在存储数据的时候,不一定是将数据存放在内存中的,有时放在寄存器中的。所以多线程操作的时候,共有变量A如果被一个线程操作,并且存放在寄存器中并没写入到内存中,而另一个线程操作这个......
  • 希尔顿酒店
    积分购买HiltonHonorsPurchasePoints积分攻略Hilton希尔顿买分活动100%奖励!历史最低价!【更新:活动回归!】-北美撸羊毛(usluyangmao.com)其他2023最全Hilton希尔顿酒店积分攻略(积分池+积分购买及兑换+价值+过期时间及避免方法)-Extrabux......