`
fantasy
  • 浏览: 507064 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论
收藏列表
标题 标签 来源
HTML TABLE 添加删除一行
<table id="courtExecuteTable">
	<tr>
		<th style="text-align:center">涉诉人</th>
		<th style="text-align:center">涉诉日期</th>
		<th style="text-align:center">标的金额</th>
		<th style="text-align:center">案件状态</th>
		<th style="text-align:center">操作</th>
	</tr>
	<tr>
		<td style="text-align:center">1</td>
		<td style="text-align:center">2</td>
		<td style="text-align:center">3</td>
		<td style="text-align:center">4</td>
		<td style="text-align:center">
			<a style="color:#06f;" href="javascript:deleteCourtExecute(1)">delete</a>
		</td>
	</tr>
</table>

<script>

addRow();

function addRow()
{
	 var courtExecuteTable= document.getElementById("courtExecuteTable");
	 var romNum = courtExecuteTable.rows.length; 
	 var insertTr = courtExecuteTable.insertRow(romNum);
	 var insertTd=insertTr.insertCell(0);
	 insertTd.style.textAlign="center";
	 insertTd.innerHTML=0;
	 
	 insertTd=insertTr.insertCell(1);
	 insertTd.style.textAlign="center";
	 insertTd.innerHTML=0;
	 
	 insertTd=insertTr.insertCell(2);
	 insertTd.style.textAlign="center";
	 insertTd.innerHTML=0;
	 
	 insertTd=insertTr.insertCell(3);
	 insertTd.style.textAlign="center";
	 insertTd.innerHTML=0;
	 
	 insertTd=insertTr.insertCell(4);
	 insertTd.style.textAlign="center";
	 insertTd.innerHTML='<a style="color:#06f;" href="javascript:deleteCourtExecute('+romNum+')">删除</a>';
}

function deleteCourtExecute(currRowIndex)
{
	document.getElementById("courtExecuteTable").deleteRow(currRowIndex);
}

</script>
CheckFieldUtil
import java.lang.reflect.Field;

import com.alifi.poseidon.common.anno.CheckField;
import com.alifi.poseidon.common.anno.ChineseDescription;

/**
 * 验证工具类
 * 
 * @author tengfei.fangtf
 * 
 */
public class CheckFieldUtil {

	/**
	 * 检查某个对象字段的状态
	 * 
	 * @param obj
	 *            输入一个对象的实例
	 * 
	 * @throws RuntimeException
	 *             提示那个字段超长
	 */
	public static void check(Object obj) {
		check(obj, "");
	}

	public static void check(Object obj, String pre) {
		if (obj == null) {
			return;
		}
		if (pre == null) {
			pre = "";
		}
		Field[] declaredFields = obj.getClass().getDeclaredFields();
		for (Field field : declaredFields) {
			if (!field.isAnnotationPresent(CheckField.class)) {
				continue;
			}
			field.setAccessible(true);
			Object value = null;
			try {
				value = field.get(obj);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (value == null || value.toString().length() == 0) {
				continue;
			}
			CheckField columnAnnotation = field.getAnnotation(CheckField.class);
			ChineseDescription descAnnotation = field
					.getAnnotation(ChineseDescription.class);
			int maxLength = columnAnnotation.maxLength();
			if (value.toString().length() > maxLength) {
				String name = descAnnotation != null ? descAnnotation
						.description() : field.getName();
				String msg = pre + name + "超过最大长度" + maxLength + ",值 = "
						+ value;
				throw new RuntimeException(msg);
			}
		}
	}

	public static void main(String[] args) {
		CheckFieldUtil.check(new Test("ftf"), "公司");
	}

	public static class Test {

		@CheckField(maxLength = 2)
		@ChineseDescription(description = "姓名")
		private String name;

		public Test(String name) {
			this.name = name;
		}

	}

}
POI的ExcelUtil
import java.math.BigDecimal;
import java.util.Date;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Sheet;

/**
 * Excel工具类
 * 
 * @author xinjing
 * @author tengfei.fangtf
 * 
 */
public class ExcelUtil {

	/**
	 * 获取单元格中的简单类型,不包括公式
	 * 
	 * @param cell
	 * @return
	 */
	public static Object getCellData(Cell cell) {
		if (cell == null) {
			return null;
		}
		switch (cell.getCellType()) {
		case Cell.CELL_TYPE_STRING:
			return cell.getRichStringCellValue().getString();
		case Cell.CELL_TYPE_NUMERIC:
			if (DateUtil.isCellDateFormatted(cell)) {
				return cell.getDateCellValue();
			} else {
				return cell.getNumericCellValue();
			}
		case Cell.CELL_TYPE_BOOLEAN:
			return cell.getBooleanCellValue();
		case Cell.CELL_TYPE_BLANK:
			return null;
		default:
			return null;
		}
	}

	public static String getString(Sheet sheet, int rowNum, int cellNum) {
		Cell cell = sheet.getRow(rowNum).getCell(cellNum);
		if (cell == null) {
			return null;
		}
		Object cellData = getCellData(cell);
		return cellData != null ? cellData.toString() : null;
	}

	public static BigDecimal getBigDecimal(Sheet sheet, int rowNum, int cellNum) {
		Cell cell = sheet.getRow(rowNum).getCell(cellNum);
		if (cell != null && cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
			double value = cell.getNumericCellValue();
			return new BigDecimal(value);
		}

		if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
			return null;
		}
		// 提示的rowNum和cellNum都要加1
		rowNum += 1;
		cellNum += 1;
		throw new RuntimeException("sheet名是‘" + sheet.getSheetName() + "’的第"
				+ rowNum + "行" + cellNum + "列,不是数字型");
	}

	public static Double getDouble(Sheet sheet, int rowNum, int cellNum) {
		BigDecimal d = getBigDecimal(sheet, rowNum, cellNum);
		return d != null ? d.doubleValue() : null;
	}

	public static Date getDate(Sheet sheet, int rowNum, int cellNum) {
		Cell cell = sheet.getRow(rowNum).getCell(cellNum);
		if (cell == null) {
			return null;
		}
		if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
			return cell.getDateCellValue();
		}

		if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
			return null;
		}
		
		// 提示的rowNum和cellNum都要加1
		rowNum += 1;
		cellNum += 1;
		throw new RuntimeException("sheet名是‘" + sheet.getSheetName() + "’的第"
				+ rowNum + "行" + cellNum + "列,不是日期型");
	}
}
log4j配置-淘宝
<logger name="com.munion" additivity="false">
        <level value="$logger_level"/>
        <appender-ref ref="munionAppender"/>
  </logger>


	<appender name="munionWdcAppender" class="com.common.logging.spi.log4j.DailyRollingFileAppender">
        <param name="file" value="$loggingRoot/munion-wdc.log"/>
        <param name="append" value="true"/>
        <param name="encoding" value="GBK"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d  %p %C{1}.%M(%L) | %m%n"/>
        </layout>
    </appender>
log_paser
echo "[Munion]Ready  Parser apk active Log....";

BASE_HOME=$(cd "$(dirname "$0")"; pwd)

HADOOP_CONF_DIR=$BASE_HOME/hadoop_conf
JAVA_HOME=/usr/java/default

echo $HADOOP_CONF_DIR;

export JAVA_HOME
export HADOOP_CONF_DIR

mkdir -p  result
mkdir -p  log

APP_ACTIVE_LOG_NAME="apk_activation_log_";

APP_ACTIVE_SQL_NAME=$BASE_HOME"/result/sql_apk_activation";
APP_ACTIVE_ERROR_NAME=$BASE_HOME"/log/error_apk_activation_log_";

DATE_TIME_Ymd=`date -d yesterday '+%Y%m%d'`;

if [ $# -lt 1 ]; then
    NOW_DATE_TIME_Ymd=$DATE_TIME_Ymd;
else
    NOW_DATE_TIME_Ymd=$1;
fi

echo "[Munion]get "$NOW_DATE_TIME_Ymd" log from yunti....";

echo "[Munion]Starting Parser apk active Log....";

APP_RESULT_SQL_PATH=$APP_ACTIVE_SQL_NAME$NOW_DATE_TIME_Ymd;

awk -v RESULT_SQL_PATH=$APP_RESULT_SQL_PATH \
    -v RESULT_ERROR_PATH=$APP_ACTIVE_ERROR_NAME$NOW_DATE_TIME_Ymd -F'\001' '{

	if($2)
	{
	    split($2,commonInfo,"\002");
	}
	clickTime = commonInfo[1];
        
	if($4)
	{
	    split($4,deviceInfo,"\002");	
    }			
       
	 
	pid = deviceInfo[1];
	appId = deviceInfo[2];
	deviceId = deviceInfo[15];
	clientDeviceId=commonInfo[4];
        credibility=100;
	endTime=strftime("%Y-%m-%d", clickTime+365*24*60*60);
	type=0;
	source=0;
	logDate=strftime("%Y%m%d", clickTime);
	
	suc="false";
	if(pid)
	{	
		split(pid,pidArray,"_");
		memberId=pidArray[2];
		adzoneId=pidArray[4];
		if(memberId && adzoneId)
		{		
		    suc="true";
		}
	}


	if(suc=="true" && pid && pid!="mm_0_0_0" && appId && deviceId && clientDeviceId)
         {
		print "[Munion]export active sql,pid="pid",deviceId="deviceId;   

		 sql="INSERT INTO munion_app_pid(PID,APP_ID,DEVICE_ID,GMT_CREATE,GMT_MODIFIED,credibility,END_TIME,TYPE,CLIENT_DEVICE_ID, SOURCE,ACTIVE_TIME,LOG_DATE,MEMBER_ID,ADZONE_ID) VALUES(\047%s\047,\047%s\047,\047%s\047,now(),now(),%s,\047%s\047,%s,\047%s\047,%s,%s,%s,%s,%s)\n";			
	
		printf(sql,pid,appId,deviceId,credibility,endTime,type,clientDeviceId,source,clickTime,logDate,memberId,adzoneId) > RESULT_SQL_PATH;

	}else{
		print "[Munion]error in  export active sql,pid="pid",deviceId="deviceId",clientDeviceId="clientDeviceId;		
		print($0) > RESULT_ERROR_PATH;

	}
}' $APP_ACTIVE_LOG_NAME$NOW_DATE_TIME_Ymd;
echo "[Munion]apk active Parser End..." ;

echo "[Munion]Rsync result File..."$APP_RESULT_SQL_PATH; 
rsync -auzi $APP_RESULT_SQL_PATH admin@v15808:/home/admin/munion_app_active_sql
echo "[Munion]Rsync result File Finish..";
	


Jtester 单元测试利器之Jtester
import mockit.NonStrict;

import org.jtester.testng.JTester;
import org.jtester.unitils.jmockit.MockedBean;
import org.testng.annotations.Test;
import org.unitils.spring.annotation.SpringApplicationContext;
import org.unitils.spring.annotation.SpringBean;

/**
 * Jtester测试例子,按照注释顺序学习
 * 
 * @author tengfei.fangtf
 */
@SpringApplicationContext( { "applicationContext.xml" })
// 1.@SpringApplicationContext:加载Spring 配置文件,所有测试相关的bean都在这个容器中;
public class BusinessTestCase extends JTester// 2.JTester:要使用JTester
// 提供的功能,需要继承此基类;
{

	@SpringBean("businessService")
	// 3.@SpringBean:从容器中取出指定id 的bean 并注入到测试类中
	private AppInternalService businessService;

	@MockedBean
	@NonStrict
	// 4.@Mocked @MockedBean:mock 出一个对象,并将该对象与Spring 容器结合,实现Autowired;
	private OneHessianServiceClient hessianClient;

	@Test(groups = { "FirstTestGroup" })
	// 5.@Test;TestNG 的注解;指明此方法为一个TestCase;
	public void testBusinessNormal() {
		new Expectations() {// 6.设置mock 对象的期望返回值
			{
				hessianClient.hessianServiceInvorke(anyString);
				result = "HH";// 那么执行这个方法,永远都返回HH
			}
		};

		String returnResult = businessService
				.bussinessService("Sample Business!");
		System.out.println("\n ---> " + returnResult);// 输出HH
		want.string(returnResult).notNull();// want:JTester 框架提供的强大的断言;
	}

}
用HSSF操作EXCEL
public class SummaryHSSF {

	public static void main(String[] args) throws IOException {
		//创建Workbook对象(这一个对象代表着对应的一个Excel文件)
                     //HSSFWorkbook表示以xls为后缀名的文件
		Workbook wb = new HSSFWorkbook();
		//获得CreationHelper对象,这个应该是一个帮助类
		CreationHelper helper = wb.getCreationHelper();
		//创建Sheet并给名字(表示Excel的一个Sheet)
		Sheet sheet1 = wb.createSheet("HSSF_Sheet_1");		
		Sheet sheet2 = wb.createSheet("HSSF_Sheet_2");
		//Row表示一行Cell表示一列
		Row row = null;
		Cell cell = null;
		for(int i=0;i<60;i=i+2){
			//获得这个sheet的第i行
			row = sheet1.createRow(i);
			//设置行长度自动			
			//row.setHeight((short)500);
			row.setHeightInPoints(20);
			//row.setZeroHeight(true);
			for(int j=0;j<25;j++){		
				//设置每个sheet每一行的宽度,自动,根据需求自行确定
				sheet1.autoSizeColumn(j+1, true);
				//创建一个基本的样式
				CellStyle cellStyle = SummaryHSSF.createStyleCell(wb);
				//获得这一行的每j列
				cell = row.createCell(j);
				if(j==0){
					//设置文字在单元格里面的位置
					cellStyle = SummaryHSSF.setCellStyleAlignment(cellStyle, CellStyle.ALIGN_CENTER, CellStyle.VERTICAL_CENTER);
					//先创建字体样式,并把这个样式加到单元格的字体里面
					cellStyle.setFont(createFonts(wb));
					//把这个样式加到单元格里面
					cell.setCellStyle(cellStyle);					
					//给单元格设值
					cell.setCellValue(true);
				}else if(j==1){
					//设置文字在单元格里面的位置
					cellStyle = SummaryHSSF.setCellStyleAlignment(cellStyle, CellStyle.ALIGN_CENTER, CellStyle.VERTICAL_CENTER);
					//设置这个样式的格式(Format)
					cellStyle = SummaryHSSF.setCellFormat(helper,cellStyle, "#,##0.0000");					
					//先创建字体样式,并把这个样式加到单元格的字体里面
					cellStyle.setFont(createFonts(wb));
					//把这个样式加到单元格里面
					cell.setCellStyle(cellStyle);
					//给单元格设值
					cell.setCellValue(new Double(2008.2008));
				}else if(j==2){
					cellStyle = SummaryHSSF.setCellStyleAlignment(cellStyle, CellStyle.ALIGN_CENTER, CellStyle.VERTICAL_CENTER);					
					cellStyle.setFont(createFonts(wb));
					cell.setCellStyle(cellStyle);
					cell.setCellValue(helper.createRichTextString("RichString"+i+j));					
				}else if(j==3){
					cellStyle = SummaryHSSF.setCellStyleAlignment(cellStyle, CellStyle.ALIGN_CENTER, CellStyle.VERTICAL_CENTER);
					cellStyle = SummaryHSSF.setCellFormat(helper,cellStyle, "MM-yyyy-dd");
					cell.setCellStyle(cellStyle);
					cell.setCellValue(new Date());
				}else if(j==24){
					cellStyle = SummaryHSSF.setCellStyleAlignment(cellStyle, CellStyle.ALIGN_CENTER, CellStyle.VERTICAL_CENTER);
					cellStyle.setFont(createFonts(wb));
					//设置公式
					cell.setCellFormula("SUM(E"+(i+1)+":X"+(i+1)+")");					
				}else{					
					cellStyle = SummaryHSSF.setCellStyleAlignment(cellStyle, CellStyle.ALIGN_CENTER, CellStyle.VERTICAL_CENTER);
					cellStyle = SummaryHSSF.setFillBackgroundColors(cellStyle,IndexedColors.ORANGE.getIndex(),IndexedColors.ORANGE.getIndex(),CellStyle.SOLID_FOREGROUND);
					cell.setCellStyle(cellStyle);
					cell.setCellValue(1);
				}
			}
		}
		//输出
		OutputStream os = new FileOutputStream(new File("c://SummaryHSSF.xls"));
		wb.write(os);
		os.close();		
	}
	/**
	 * 边框
	 * @param wb
	 * @return
	 */
	public static CellStyle createStyleCell(Workbook wb){
		CellStyle cellStyle = wb.createCellStyle();
		//设置一个单元格边框颜色
		cellStyle.setBorderBottom(CellStyle.BORDER_THIN);
		cellStyle.setBorderTop(CellStyle.BORDER_THIN);
		cellStyle.setBorderLeft(CellStyle.BORDER_THIN);
		cellStyle.setBorderRight(CellStyle.BORDER_THIN);
		//设置一个单元格边框颜色
		cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
		cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
		cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
		cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());		
		return cellStyle;
	}
	/**
	 * 设置文字在单元格里面的位置
	 * CellStyle.ALIGN_CENTER
	 * CellStyle.VERTICAL_CENTER
	 * @param cellStyle
	 * @param halign
	 * @param valign
	 * @return
	 */
	public static CellStyle setCellStyleAlignment(CellStyle cellStyle,short halign,short valign){
		//设置上下
		cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
		//设置左右
		cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
		return cellStyle;
	}
	/**
	 * 格式化单元格
	 * 如#,##0.00,m/d/yy去HSSFDataFormat或XSSFDataFormat里面找
	 * @param cellStyle
	 * @param fmt
	 * @return
	 */
	public static CellStyle setCellFormat(CreationHelper helper,CellStyle cellStyle,String fmt){
		//还可以用其它方法创建format
		cellStyle.setDataFormat(helper.createDataFormat().getFormat(fmt));
		return cellStyle;
	}
	/**
	 * 前景和背景填充的着色
	 * @param cellStyle
	 * @param bg IndexedColors.ORANGE.getIndex();
	 * @param fg IndexedColors.ORANGE.getIndex();
	 * @param fp CellStyle.SOLID_FOREGROUND
	 * @return
	 */
	public static CellStyle setFillBackgroundColors(CellStyle cellStyle,short bg,short fg,short fp){
		//cellStyle.setFillBackgroundColor(bg);
		cellStyle.setFillForegroundColor(fg);
		cellStyle.setFillPattern(fp);
		return cellStyle;
	}
	/**
	 * 设置字体
	 * @param wb
	 * @return
	 */
	public static Font createFonts(Workbook wb){
		//创建Font对象
		Font font = wb.createFont();
		//设置字体
		font.setFontName("黑体");
		//着色
		font.setColor(HSSFColor.BLUE.index);
		//斜体
		font.setItalic(true);
		//字体大小
		font.setFontHeight((short)300);
		return font;
	}
}
用HSSF读Excel
 private boolean checkPromotion(PromotionVO promotion){
    	//检查时间
    	if(promotion.getGmtStart() == null && promotion.getGmtEnd() == null || promotion.getGmtStart().after(promotion.getGmtEnd())){
    		msg.append("结束时间必须大于开始时间");
    		return false ;
    	}
    	LuckydrawMemberDO[] memberArray = promotion.getLuckydrawMembers() ;
    	if(ArrayUtils.isEmpty(memberArray)){
    		msg.append("会员名单不能为空");
    		return false ;
    	}
    	Map<String,Boolean> checkMemberMap = new HashMap<String,Boolean>() ;
    	for(LuckydrawMemberDO member : memberArray){
    		if(checkMemberMap.containsKey(member.getMemberId())){
    			msg.append("会员 [" + member.getMemberId() + "] 出现多次。");
    			return false ;
    		}
    		checkMemberMap.put(member.getMemberId(), Boolean.TRUE) ;
    	}
    	
    	return true ;
    }
    
    private void addLuckdrawMember(PromotionVO promotion) {
        if (!"INTERNAL_DATABASE".equalsIgnoreCase(promotion.getMemberSource())) {
            return;
        }
        FileItem memberFile = promotion.getMemberFile();
        if (memberFile != null) {
            try {
                HSSFWorkbook wbs = new HSSFWorkbook(memberFile.getInputStream());
                List<LuckydrawMemberDO> memberList = new ArrayList<LuckydrawMemberDO>() ;
                for(int i=0 ;i<2 ;i++){ //读取2个sheet
                	HSSFSheet childSheet = wbs.getSheetAt(i);
                	if(childSheet == null){
                		continue ;
                	}
                	//验证第一行是否符合要求
                    checkHeader(childSheet);
                    
                    addLuckdrawMember(childSheet, promotion , memberList);
                }
                //检查会员
               
                promotion.setLuckydrawMembers(memberList.toArray(new LuckydrawMemberDO[memberList.size()]));
                
            } catch (Exception e) {
                msg.append("上传的抽奖会员文件出现错误。");
                log.error("上传的抽奖会员文件出现错误。", e);
            }
        }
    }

    private void checkHeader(HSSFSheet childSheet) {
        HSSFRow fristRow = childSheet.getRow(0);
        HSSFCell memberCell = fristRow.getCell((short) 0);
        HSSFCell countCell = fristRow.getCell((short) 1);
        String memberCellValue = memberCell.getRichStringCellValue().getString();
        String countCellValue = countCell.getRichStringCellValue().getString();
        if (!"memberId".equalsIgnoreCase(memberCellValue) || !"count".equalsIgnoreCase(countCellValue)) {
            msg.append("上传的抽奖会员文件第一行必须有memberId和count列");
        }
    }

    private void addLuckdrawMember(HSSFSheet childSheet, PromotionVO promotionVO , List<LuckydrawMemberDO> memberList) {
        HSSFCell memberCell;
        HSSFCell countCell;
        //添加抽奖会员数据,从第二行开始
        for (int j = 1; j < childSheet.getLastRowNum(); j++) {
            HSSFRow row = childSheet.getRow(j);
            if (null == row) {
                continue;
            }
            memberCell = row.getCell((short) 0);
            countCell = row.getCell((short) 1);
            int canDrawCount = 1;
            String memberId = null;
            try {
                memberId = memberCell.getRichStringCellValue().getString();
                if (countCell != null) {
                    double count = countCell.getNumericCellValue();
                    canDrawCount = Double.valueOf(count).intValue();
                }
            } catch (Throwable e) {
                msg.append("上传的抽奖会员文件第" + (j+1) + "行出现错误。");
                break;
            }

            if (memberId != null || canDrawCount != 0) {
                LuckydrawMemberDO member = new LuckydrawMemberDO();
                member.setCanDrawCount(canDrawCount);
                member.setMemberId(memberId);
                memberList.add(member);
            }
        }
        
    }
RSA 算法 RSA算法Java实现
package com.hexun.blog.dongliwei.utils;
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.io.*;
import java.math.BigInteger;

/**
 * RSA 工具类。提供加密,解密,生成密钥对等方法。
 * 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。
 * RSA加密原理概述  
 * RSA的安全性依赖于大数的分解,公钥和私钥都是两个大素数(大于100的十进制位)的函数。  
 * 据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积  
 * ===================================================================  
 * (该算法的安全性未得到理论的证明)  
 * ===================================================================  
 * 密钥的产生:  
 * 1.选择两个大素数 p,q ,计算 n=p*q;  
 * 2.随机选择加密密钥 e ,要求 e 和 (p-1)*(q-1)互质  
 * 3.利用 Euclid 算法计算解密密钥 d , 使其满足 e*d = 1(mod(p-1)*(q-1)) (其中 n,d 也要互质)  
 * 4:至此得出公钥为 (n,e) 私钥为 (n,d)  
 * ===================================================================  
 * 加解密方法:  
 * 1.首先将要加密的信息 m(二进制表示) 分成等长的数据块 m1,m2,...,mi 块长 s(尽可能大) ,其中 2^s<n  
 * 2:对应的密文是: ci = mi^e(mod n)  
 * 3:解密时作如下计算: mi = ci^d(mod n)  
 * ===================================================================  
 * RSA速度  
 * 由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论 是软件还是硬件实现。  
 * 速度一直是RSA的缺陷。一般来说只用于少量数据 加密。 
 *文件名:RSAUtil.java<br>
 *@author 董利伟<br>
 *版本:<br>
 *描述:<br>
 *创建时间:2008-9-23 下午09:58:16<br>
 *文件描述:<br>
 *修改者:<br>
 *修改日期:<br>
 *修改描述:<br>
 */
public class RSAUtil {

	//密钥对
	private KeyPair keyPair = null;
	
	/**
	 * 初始化密钥对
	 */
	public RSAUtil(){
		try {
			this.keyPair = this.generateKeyPair();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	* 生成密钥对
	* @return KeyPair
	* @throws Exception
	*/
	private KeyPair generateKeyPair() throws Exception {
		try {
			KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());
			//这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
			final int KEY_SIZE = 1024;
			keyPairGen.initialize(KEY_SIZE, new SecureRandom());
			KeyPair keyPair = keyPairGen.genKeyPair();
			return keyPair;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	
	}

	/**
	* 生成公钥
	* @param modulus
	* @param publicExponent
	* @return RSAPublicKey
	* @throws Exception
	*/
	private RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws Exception {
	
		KeyFactory keyFac = null;
		try {
			keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
		} catch (NoSuchAlgorithmException ex) {
		throw new Exception(ex.getMessage());
		}
		RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));
		try {
			return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
		} catch (InvalidKeySpecException ex) {
			throw new Exception(ex.getMessage());
		}
	
	}

	/**
	* 生成私钥
	* @param modulus
	* @param privateExponent
	* @return RSAPrivateKey
	* @throws Exception
	*/
	private RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws Exception {
		KeyFactory keyFac = null;
		try {
			keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
		} catch (NoSuchAlgorithmException ex) {
			throw new Exception(ex.getMessage());
		}
		RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));
		try {
			return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
		} catch (InvalidKeySpecException ex) {
			throw new Exception(ex.getMessage());
		}
	}

	/**
	* 加密
	* @param key 加密的密钥
	* @param data 待加密的明文数据
	* @return 加密后的数据
	* @throws Exception
	*/
	public byte[] encrypt(Key key, byte[] data) throws Exception {
		try {
			Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
			cipher.init(Cipher.ENCRYPT_MODE, key);
			//获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;
			//因此共有2个加密块,第一个127 byte第二个为1个byte
			int blockSize = cipher.getBlockSize();
			int outputSize = cipher.getOutputSize(data.length);//获得加密块加密后块大小
			int leavedSize = data.length % blockSize;
			int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
			byte[] raw = new byte[outputSize * blocksSize];
			int i = 0;
			while (data.length - i * blockSize > 0) {
				if (data.length - i * blockSize > blockSize)
				cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
				else
				cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
				//这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中
				//,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。
				i++;
			}
			return raw;
		} catch (Exception e) {
		throw new Exception(e.getMessage());
		}
	}

	/**
	* 解密
	* @param key 解密的密钥
	* @param raw 已经加密的数据
	* @return 解密后的明文
	* @throws Exception
	*/
	public byte[] decrypt(Key key, byte[] raw) throws Exception {
		try {
			Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
			cipher.init(cipher.DECRYPT_MODE, key);
			int blockSize = cipher.getBlockSize();
			ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
			int j = 0;
			while (raw.length - j * blockSize > 0) {
				bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
				j++;
			}
			return bout.toByteArray();
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}
	
	/**
	 * 返回公钥
	 * @return
	 * @throws Exception 
	 */
	public RSAPublicKey getRSAPublicKey() throws Exception{
		
		//获取公钥
		RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
		//获取公钥系数(字节数组形式)
		byte[] pubModBytes = pubKey.getModulus().toByteArray();
		//返回公钥公用指数(字节数组形式)
		byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
		//生成公钥
		RSAPublicKey recoveryPubKey = this.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
		return recoveryPubKey;
	}
	
	/**
	 * 获取私钥
	 * @return
	 * @throws Exception 
	 */
	public RSAPrivateKey getRSAPrivateKey() throws Exception{
		
		//获取私钥
		RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();
		//返回私钥系数(字节数组形式)
		byte[] priModBytes = priKey.getModulus().toByteArray();
		//返回私钥专用指数(字节数组形式)
		byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
		//生成私钥
		RSAPrivateKey recoveryPriKey = this.generateRSAPrivateKey(priModBytes,priPriExpBytes);
		return recoveryPriKey;
	}
	
	
	/**
	* 测试
	* @param args
	* @throws Exception
	*/
	public static void main(String[] args) throws Exception {
		
		RSAUtil rsa = new RSAUtil();
		String str = "董利伟";
		RSAPublicKey pubKey = rsa.getRSAPublicKey();
		RSAPrivateKey priKey = rsa.getRSAPrivateKey();
		System.out.println("加密后==" + new String(rsa.encrypt(pubKey,str.getBytes())));
		System.out.println("解密后==" + new String(rsa.decrypt(priKey, rsa.encrypt(pubKey,str.getBytes()))));
	}
}
CookieUtil
/**
 * Create on 2012-7-10 下午5:08:49 by tengfei.fangtf
 * 
 * Copyright 1999-2100 taobao.com Corporation Limited.
 * 
 * All rights reserved.
 */
package com.taobao.wireless.trade.util;

import javax.servlet.http.Cookie;

/**
 * 操作Cookie工具类
 * 
 * @author tengfei.fangtf
 */
public class CookieUtil {

    public static final String M_TTID_COOKIE = "m_t"; //无线广告存的TTID

    /**
     * 获取cookie的值
     * 
     * @param cookies 所有cookie
     * @param cookieName cookie的名称
     * @param defaultValue 获取不到时采用的默认值
     * @return
     */
    public static final String getCookieValue(Cookie[] cookies, String cookieName, String defaultValue) {
        for (Cookie cookie : cookies) {
            if (cookieName.equals(cookie.getName())) {
                return (cookie.getValue());
            }
        }
        return (defaultValue);
    }

    /**
     * 获取无线广告存的TTID
     * 
     * @param cookies
     * @return
     */
    public static final String getTTIdCookie(Cookie[] cookies) {
        return getCookieValue(cookies, M_TTID_COOKIE, null);
    }

}
linux命令
strace 命令是一种强大的工具,它能够显示所有由用户空间程序发出的系统调用。
lsof 打开open file

vi 编辑文本
:wq 保存并退出
/查找


安装JDK1.6 
1:先把jdk-6u13-linux-i586.bin文件上传到linux下。 
2:sh jdk-6u13-linux-i586.bin //安装 jdk 

修改Tomcat的JDK 
分别修改catalina.sh ,setclasspath.sh文件里的$JAVA_HOME和$JRE_HOME 

启动Tomcat 
chmod 755 *.sh  给所有的sh设置权限 
nohup ./start.sh > /dev/null &  无输出启动 tomcat 

关闭Tomcat 
kill -9 端口号 

其他操作: 
jdk/bin/jps      查看java进程 
useradd testuser 创建用户testuser 
passwd testuser 给已创建的用户testuser设置密码 
usermod -d opt fangtengfei 修改用户默认目录 
chown fangtengfei /opt/scm 修改目录拥有者 
rm -f -R scm 删除目录 
ps aux | grep java  查看所有java进程。 
tail -1000 XX文件    查看文件多少行 
more XX文件           查看文件 
tail -fn XX文件        跟踪文件 
touch [FileName]   创建文件。
du -sh 查看目录容量
jps -l
host文件在/etc/hosts
切换到root用户:su
退出root用户:exit;
Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成提供与实现了Linux与Windows之间的文件共享与打印
查看smb服务:/etc/init.d/smb status
启动smb服务:/etc/init.d/smb start
查看端口:netstat -nlp 
Apache启动: ./bin/apachectl start
ps -ef 查看所有进程

ln -s /home/alisoft/project/tala/tala/target/tala/ tala.war 将指定的文件夹映射到tala.war

将文件复制到其他机器
scp eq/logs/jboss_stdout.log alisoft@10.20.147.186:/home/alisoft/ 
文件 scp 10.20.147.178:/home/alisoft/project/eq/maven.properties . 
目录 scp -r 10.20.147.234:/home/alisoft/project/tala/ .
应用程序启动构建关闭脚本
#!/bin/sh
cd `dirname $0`/..
BASE=`pwd`
echo $BASE

svn up
mvn clean install -Dmaven.test.skip
cd bin
sh start.sh

cd ../target
java -jar yuna-1.0-SNAPSHOT.jar &

kill -9 $(ps -ef|grep yuna-1.0-SNAPSHOT.jar|gawk '$0 !~/grep/ {print $2}' |tr -s '\n' ' ')
一张Base64编码的图片
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
UUID工具类
import java.util.UUID;

public class UUIDUtil {

	private static final String MIDDLE_LINE = "-";


	private static char X36S[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
			.toCharArray();


	private static short LEN = 20;


	public static String random36() {
		return UUID.randomUUID().toString().toUpperCase();
	}


	public static String random32() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}


	public static String random20() {
		char chs[] = new char[LEN];

	
		long v = (System.currentTimeMillis() - 936748800000L) >> 1; // 1999-9-9

		for (int i = 7; i > 0; i--) {
			chs[i] = X36S[(int) (v % 36)];
			v = v / 36;
		}
		chs[0] = X36S[(int) (v % 26) + 10];


		UUID u = UUID.randomUUID();
		v = u.getLeastSignificantBits() ^ u.getMostSignificantBits();
		if (v < 0) {
			v = -v;
		}

		for (int i = 8; i < LEN; i++) {
			chs[i] = X36S[(int) (v % 36)];
			v = v / 36;
		}

		return new String(chs).toUpperCase();
	}

}
单例JS
var Singleton = {
    attribute1: true;
    attribute2: 10
    
    method1: function() {
    },
    method2: function() {
    }
};
得到今天的周数
var curDayOfWeek=curDate.getDay();
var curOperWeek=Math.ceil((curDate.getDate()-curDayOfWeek-1)/7)+1;
关闭层,当天不显示
//banner关闭后,当天不显示
	function initMkBanner()
	{
		var mkBanner=document.getElementById("mk_banner");
		var mkBannerCloseBtn=document.getElementById("mk_banner_cls");
		if(mkBanner)
		{
			//现在的天数
			var nowDay=parseInt(new Date()/(1000*3600*24));
			//banner关闭时的天数
			var closeDay = xui.util.Cookie.read("mkBannerCloseDay");
			var canDisplay=!closeDay || (nowDay-closeDay>=1);
			if(canDisplay)
			{
				mkBanner.style.display="block";
			}
			
			mkBannerCloseBtn.onclick=function()
			{
				xui.util.Cookie.write("mkBannerCloseDay",nowDay);
				mkBanner.style.display="none";
			};
		}
	}
log4j配置
log4j.rootLogger=ERROR,stdout,file,D,MAIL
log4j.category.org.yuna=DEBUG

log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern =  %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=logs/yuna.log
log4j.appender.file.Append = true
log4j.appender.file.Threshold = DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/error.log 
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=ERROR
log4j.appender.MAIL.BufferSize=1
log4j.appender.MAIL.SMTPUsername=main_shorttime@yahoo.cn
log4j.appender.MAIL.SMTPPassword=alibaba
log4j.appender.MAIL.SMTPHost=smtp.mail.yahoo.com.cn
log4j.appender.MAIL.Subject=Yuna Has Error
log4j.appender.MAIL.SMTPDebug=false
log4j.appender.MAIL.LocationInfo=true
log4j.appender.MAIL.SendOnClose=true
log4j.appender.MAIL.From=main_shorttime@yahoo.cn
log4j.appender.MAIL.To=tengfei.fangtf@alibaba-inc.com,steven.lin@alibaba-inc.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

DES
import java.security.Key;
import java.security.Security;

import javax.crypto.Cipher;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DES {
	private static String strDefaultKey = "strDefaultKey ";

	private Cipher encryptCipher = null;

	private Cipher decryptCipher = null;
	private static final Log log = LogFactory.getLog(DES.class);

	/**
	 * 将byte数组转换为表示16进制值的字符串, 如:byte[]{8,18}转换为:0813, 和public static byte[]
	 * hexStr2ByteArr(String strIn) 互为可逆的转换过程
	 * 
	 * @param arrB
	 *            需要转换的byte数组
	 * @return 转换后的字符串 	
	 * @throws Exception
	 *             本方法不处理任何异常,所有异常全部抛出
	 */
	public static String byteArr2HexStr(byte[] arrB) {
		int iLen = arrB.length;
		// 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
		StringBuffer sb = new StringBuffer(iLen * 2);
		for (int i = 0; i < iLen; i++) {
			int intTmp = arrB[i];
			// 把负数转换为正数
			while (intTmp < 0) {
				intTmp = intTmp + 256;
			}
			// 小于0F的数需要在前面补0
			if (intTmp < 16) {
				sb.append('0');
			}
			sb.append(Integer.toString(intTmp, 16));
		}
		return sb.toString();
	}

	/**
	 * 将表示16进制值的字符串转换为byte数组, 和public static String byteArr2HexStr(byte[] arrB)
	 * 互为可逆的转换过程
	 * 
	 * @param strIn
	 *            需要转换的字符串
	 * @return 转换后的byte数组
	 * @throws Exception
	 *             本方法不处理任何异常,所有异常全部抛出
	 */
	public static byte[] hexStr2ByteArr(String strIn) throws Exception {
		byte[] arrB = strIn.getBytes();
		int iLen = arrB.length;

		// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
		byte[] arrOut = new byte[iLen / 2];
		for (int i = 0; i < iLen; i = i + 2) {
			String strTmp = new String(arrB, i, 2);
			arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
		}
		return arrOut;
	}

	/**
	 * 默认构造方法,使用默认密钥
	 * 
	 * @throws Exception
	 */
	public DES() {
		this(strDefaultKey);
	}

	/**
	 * 指定密钥构造方法
	 * 
	 * @param strKey
	 *            指定的密钥
	 * @throws Exception
	 */
	public DES(String strKey) {
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		Key key;
		try {
			key = getKey(strKey.getBytes());

			encryptCipher = Cipher.getInstance("DES");
			encryptCipher.init(Cipher.ENCRYPT_MODE, key);

			decryptCipher = Cipher.getInstance("DES");
			decryptCipher.init(Cipher.DECRYPT_MODE, key);
		} catch (Exception e) {
		    log.error(e.getMessage(),e);
		}
	}

	/**
	 * 加密字节数组
	 * 
	 * @param arrB
	 *            需加密的字节数组
	 * @return 加密后的字节数组
	 * @throws Exception
	 */
	public byte[] encrypt(byte[] arrB) throws Exception {
		return encryptCipher.doFinal(arrB);
	}

	/**
	 * 加密字符串
	 * 
	 * @param strIn
	 *            需加密的字符串
	 * @return 加密后的字符串
	 * @throws Exception
	 */
	public String encrypt(String strIn) throws Exception {
		return byteArr2HexStr(encrypt(strIn.getBytes()));
	}

	/**
	 * 解密字节数组
	 * 
	 * @param arrB
	 *            需解密的字节数组
	 * @return 解密后的字节数组
	 * @throws Exception
	 */
	public byte[] decrypt(byte[] arrB) throws Exception {
		return decryptCipher.doFinal(arrB);
	}

	/**
	 * 解密字符串
	 * 
	 * @param strIn
	 *            需解密的字符串
	 * @return 解密后的字符串
	 * @throws Exception
	 */
	public String decrypt(String strIn) throws Exception {
		return new String(decrypt(hexStr2ByteArr(strIn)));
	}

	/**
	 * 从指定字符串生成密钥,密钥所需的字节数组长度为8位 不足8位时后面补0,超出8位只取前8位
	 * 
	 * @param arrBTmp
	 *            构成该字符串的字节数组
	 * @return 生成的密钥
	 * @throws java.lang.Exception
	 */
	private Key getKey(byte[] arrBTmp) throws Exception {
		// 创建一个空的8位字节数组(默认值为0)
		byte[] arrB = new byte[8];

		// 将原始字节数组转换为8位
		for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
			arrB[i] = arrBTmp[i];
		}

		// 生成密钥
		Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");

		return key;
	}

	public static void main(String[] args) {
		DES des = new DES("cc");// 自定义密钥
		long cur = System.currentTimeMillis();
		String test = "Hellow Word搜地方!";
		System.out.println("加密前的字符:" + test);
		try {
			System.out.println("加密后的字符:" + des.encrypt(test));
			System.out.println("解密后的字符:" + des.decrypt(des.encrypt(test)));
		} catch (Exception e) {
		    log.error(e.getMessage(),e);
		}
		
		System.out.println(System.currentTimeMillis() - cur);

	}
}
文件解压
/**
 * 文件解压
 * 
 * @author tengfei.fangtf
 */
public class GZipFile {

    public static void main(String[] args) {
        try {
            //得到类路径下的文件
            String name = Thread.currentThread().getContextClassLoader().getResource("Hello.zip").getFile();
            //创建一个到输入到内存的流
            FileInputStream fis = new FileInputStream(name);
            //创建一个到输入到内存的Zip流
            ZipInputStream zin = new ZipInputStream(fis);
            ZipEntry ze = null;
            int b = 0;
            //在内存里遍历压缩流里的每一个文件
            while ((ze = zin.getNextEntry()) != null) {
                //创建一个输出流,输出到文件
                FileOutputStream fout = new FileOutputStream(ze.getName());
                //输出到文件
                while ((b = zin.read()) != -1) {
                    fout.write(b);
                }
                zin.closeEntry();
                fout.flush();
                fout.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
数据分割
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Test {

	public static void main(String[] args) {
		Set<Integer> memberIdList = new HashSet<Integer>();
		Set<Integer> check = new HashSet<Integer>();
		for (int i = 0; i < 10000; i++) {
			memberIdList.add(i);
		}

		Integer[] memberIds = memberIdList.toArray(new Integer[memberIdList
				.size()]);
		int j = 0;
		List<Object[]> splitData = splitData(memberIds, 2001);
		for (Object[] objects : splitData) {
			for (int i = 0; i < objects.length; i++) {
				check.add((Integer) objects[i]);
				j++;
			}
		}

		System.out.println("多少块:" + splitData.size() + "笔数:" + j + "check:"
				+ check.size());

	}

	/**
	 * 切分数据
	 * 
	 * <pre>
	 * 数据量比较大的时候,将数据切分为每笔splitNum个数据进行处理
	 * </pre>
	 * 
	 * 
	 * @param data
	 *            想要切分的数据
	 * @param splitNum
	 *            每组多少笔
	 * @return 存放切分完的数据
	 */
	private static List<Object[]> splitData(Object[] data, int splitNum) {
		if (data == null) {
			return null;
		}
		List<Object[]> result = new ArrayList<Object[]>();
		int startIndex = 0;
		for (int i = 0; i < data.length; i++) {
			if ((i + 1) % splitNum == 0) {
				result.add(Arrays.copyOfRange(data, startIndex, ++i));
				startIndex = i;
			}
		}

		if (data.length % splitNum != 0) {
			result.add(Arrays.copyOfRange(data, startIndex, data.length));
		}

		return result;
	}

}
Global site tag (gtag.js) - Google Analytics