Category: Java

Java JUnit4测试代码记录

首先使用Maven引入许要的jar包

<dependencies>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.12</version>
		<scope>test</scope>
	</dependency>
</dependencies>

JUnit4注解解释

  1. @Test : 测试方法,测试程序会运行的方法,后边可以跟参数代表不同的测试,如(expected=XXException.class) 异常测试,(timeout=xxx)超时测试
  2. @Ignore : 被忽略的测试方法
  3. @Before: 每一个测试方法之前运行
  4. @After : 每一个测试方法之后运行
  5. @BeforeClass: 所有测试开始之前运行
  6. @AfterClass: 所有测试结束之后运行

fail方法是指测试失败
assertEquals测试2个参数是否相等,具体参考相应API

Maven 安装及更换阿里云仓库

一、MAVEN下载
Maven 官方下载网址:http://maven.apache.org/download.cgi

二、下载下来之后,解压,找个路径放进去, 把bin的位置设在环境变量里,新建环境变量MAVEN_HOME
注意:MAVEN运行时,系统变量必须有 %JAVA_HOME%

variable

三、在PATH里加入maven的bin的路径

variable

四、配置完毕后,在Windows命令提示符下,输入mvn -v测试一下

maven version

五、配置Eclipse的Maven(点击Window -> Preference -> Maven -> Installation -> Add进行设置)

Eclipse Maven Rutime

六、配置Maven

Eclipse Maven User Setting

七、配置镜像仓库
setting.xml 文件内,找到mirrors节点,添加以下内容(mirror节点)

<mirrors>
	<mirror>
		<id>nexus-aliyun</id>
		<mirrorOf>central</mirrorOf>
		<name>Nexus aliyun</name>
		<url>http://maven.aliyun.com/nexus/content/groups/public</url>
	</mirror>
 
	<mirror>
		<id>sonatype</id>
		<mirrorOf>central</mirrorOf>
		<name>Sonatype Snapshots</name>
		<url>https://oss.sonatype.org/content/groups/public/</url>
	</mirror>
 
	<mirror>
		<id>repo2</id>
		<mirrorOf>central</mirrorOf>
		<name>Human Readable Name for this Mirror.</name>
		<url>http://repo2.maven.org/maven2/</url>
	</mirror>
 
	<mirror>
		<id>net-cn</id>
		<mirrorOf>central</mirrorOf>
		<name>Human Readable Name for this Mirror.</name>
		<url>http://maven.net.cn/content/groups/public/</url>
	</mirror>
 
	<mirror>
		<id>ui</id>
		<mirrorOf>central</mirrorOf>
		<name>Human Readable Name for this Mirror.</name>
	 <url>http://uk.maven.org/maven2/</url>
	</mirror>
 
	<mirror>
		<id>ibiblio</id>
		<mirrorOf>central</mirrorOf>
		<name>Human Readable Name for this Mirror.</name>
	 <url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url>
	</mirror>
 
	<mirror>
		<id>jboss-public-repository-group</id>
		<mirrorOf>central</mirrorOf>
		<name>JBoss Public Repository Group</name>
	 <url>http://repository.jboss.org/nexus/content/groups/public</url>
	</mirror>
</mirrors>

直接在pom.xml中配置仓库

<repositories>
	<repository>
		<id>sonatype-nexus-snapshots</id>
		<name>Sonatype Nexus Snapshots</name>
		<url>http://repo1.maven.org/maven2/</url>
		<releases>
			<enabled>true</enabled>
		</releases>
		<snapshots>
			<enabled>true</enabled>
		</snapshots>
	</repository>
	<repository>
		<id>sonatype</id>
		<name>Sonatype Snapshots</name>
		<url>https://oss.sonatype.org/content/groups/public</url>
		<releases>
			<enabled>true</enabled>
		</releases>
		<snapshots>
			<enabled>true</enabled>
		</snapshots>
	</repository>
</repositories>

log4j/Log4j2 配置

Event LevelLoggerConfig Level
 --TRACEDEBUGINFOWARNERRORFATALOFF
ALLYESYESYESYESYESYESNO
TRACEYESNONONONONONO
DEBUGYESYESNONONONONO
INFOYESYESYESNONONONO
WARNYESYESYESYESNONONO
ERRORYESYESYESYESYESNONO
FATALYESYESYESYESYESYESNO
OFFNONONONONONONO
package main;
 
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
 
public class Main  {
    public static void main(String args[]){
        Logger Log = LogManager.getLogger(Main.class.getName());
        Log.info("this is the info");
        Log.warn("this is the warn info");
        Log.error("this is the error info");
        Log.fatal("this is the fatal info");
        Log.trace("enter Main.test()");
        //new Main().test();
        Log.trace("exit Main.test()");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
 
<configuration debug="off" status="INFO"> <!-- 这个status是控制系统信息的输出级别 -->
	<Properties>
		<Property name="path">D:/logs</Property>
	</Properties>
 
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">	<!-- 将日志信息从控制台输出 -->
			<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" />
			<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %class{36}.%M()/%L - %msg%xEx%n" />
		</Console>
 
		<File name="debug" fileName="${path}/debug.log" append="true">	<!-- 将日志信息写入日志文件 -->
			<Filters>
				<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
				<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" />
				<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
			</Filters>
			<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %class{36}.%M()/%L - %msg%xEx%n" />
		</File>
 
		<RollingFile name="RollingFile" fileName="${path}/log.log" filePattern="${path}/log-%d{yyyy-MM-dd}_%i.log">
			<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %class{36}.%M()/%L - %msg%xEx%n" />
			<SizeBasedTriggeringPolicy size="50MB" />
		</RollingFile>
	</Appenders>
 
	<Loggers>
		<Root level="trace">
			<AppenderRef ref="Console" />   <!-- 仅有上述的Appenders配置还不够,这里还不能少,少了就不会在控制台输出 -->
			<AppenderRef ref="RollingFile" />   
			<AppenderRef ref="debug" />  <!-- 仅有上述的Appenders配置还不够,这里还不能少,少了就不会写入文件,但会创建文件 -->
		</Root>
	</Loggers>
 
</configuration>
log4j.rootLogger=debug,stdout,error

# set the output lever
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.Encoding=UTF-8
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout.ConversionPattern=[%p] - [%d{yyyy-MM-dd HH:mm:ss}] %F %m%n

# %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] %m%n

# set the Spring lever
log4j.category.org.springframework.beans.factory = DEBUG

### put the log to the file
log4j.appender.debug=org.apache.log4j.RollingFileAppender
log4j.appender.debug.File=../logs/debug.log
log4j.appender.debug.MaxFileSize = 10MB
log4j.appender.debug.Threshold = DEBUG
log4j.appender.debug.Encoding=UTF-8
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=[%p] - [%d{yyyy-MM-dd HH:mm:ss}] %F %m%n

### put the log to the file
log4j.appender.error=org.apache.log4j.RollingFileAppender
log4j.appender.error.File=../logs/error.log
log4j.appender.error.MaxFileSize = 10MB
log4j.appender.error.Threshold = ERROR
log4j.appender.error.Encoding=UTF-8
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=[%p] - [%d{yyyy-MM-dd HH:mm:ss}] %F %m%n

### output the sql
log4j.logger.com.pay.dao=DEBUG

### druid sql ###
log4j.logger.druid.sql=warn,stdout
log4j.logger.druid.sql.DataSource=warn,stdout
log4j.logger.druid.sql.Connection=warn,stdout
log4j.logger.druid.sql.Statement=warn,stdout
log4j.logger.druid.sql.ResultSet=warn,stdout

bootstrap table 服务端搜索/分页/异步刷新

最近项目中用到了很多的Table,在jsp中构建的话太过繁琐,不宜与后续dom的操作。所以特意研究了一下Bootstrap Table这个插件!!

Java Json包 https://github.com/FasterXML/jackson

插件地址:Bootstrap Table

使用该插件需要Jquery与Bootstrap支持

Html部分

<!DOCTYPE html>
<html lang="en">
 
<head>
	<meta charset="UTF-8">
	<title>Deomo</title>
	<link rel="stylesheet" href="/assets/css/bootstrap.min.css" />
	<link rel="stylesheet" href="/assets/css/bootstrap-table.min.css">
</head>
 
<body>
	<!--查询窗体-->
	<div class="widget-content">
		<form method="post" class="form-horizontal" id="eventqueryform">
			<input type="text" class="span3" name="eventName" placeholder="事件名称"> <input type="text" class="span2" name="status" placeholder="灾情状态"> 
			<input type="text" class="span3" name="location" placeholder="发现位置">
			<div data-date="" class="input-append date datepicker" data-date-format="yyyy-mm-dd">
				<input type="text" class="span10" name="startdate" placeholder="起始日期"> <span class="add-on"><i class="icon-th"></i></span>
			</div>
			<div data-date="" class="input-append date datepicker" data-date-format="yyyy-mm-dd">
				<input type="text" class="span10" name="enddate" placeholder="结束日期"> <span class="add-on"><i class="icon-th"></i></span>
			</div>
			<input type="button" class="btn btn-default span1" id="eventquery" value="查询">
		</form>
	</div>
 
	<div class="widget-content">
		<!--工具条-->
		<div id="toolbar">
			<button class="btn btn-success btn-xs" data-toggle="modal" data-target="#add">添加事件</button>
		</div>
		<table id="eventTable"></table>
	</div>
 
	<script src="/assets/js/jquery.min.js"></script>
	<script src="/assets/js/bootstrap.min.js"></script>
	<script src="/assets/js/bootstrap-table.min.js"></script>
	<script src="/assets/js/bootstrap-table-zh-CN.min.js"></script>
	<script src="/assets/js/event.js"></script>
 
</body>
 
</html>

JS部分

$(document).ready(function() {
	// 初始化表格
	initTable();
});

// 表格初始化
function initTable() {
	$('#eventTable').bootstrapTable({
		method: 'post', // 向服务器请求方式
		contentType: "application/x-www-form-urlencoded", // 如果是post必须定义
		url: '/program/event/findbyitem', // 请求url
		cache: false, // 是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
		striped: true, // 隔行变色
		dataType: "json", // 数据类型
		pagination: true, // 是否启用分页
		showPaginationSwitch: false, // 是否显示 数据条数选择框
		pageSize: 5, // 每页的记录行数(*)
		pageNumber: 1, // table初始化时显示的页数
		search: false, // 不显示 搜索框
		sidePagination: 'server', // 服务端分页
		classes: 'table table-bordered', // Class样式

		// showRefresh : true, // 显示刷新按钮

		silent: true, // 必须设置刷新事件

		toolbar: '#toolbar', // 工具栏ID
		toolbarAlign: 'right', // 工具栏对齐方式

		queryParams: queryParams, // 请求参数,这个关系到后续用到的异步刷新

		columns: [{
			field: 'eventName',
			title: '事件名称',
			align: 'center'
		}, {
			field: 'date',
			title: '日期',
			align: 'center'
		}, {
			field: 'location',
			title: '发生位置',
			align: 'center'
		}, {
			field: 'mesures',
			title: '防治方案',
			align: 'center'
		}, {
			field: 'status',
			title: '灾情状态',
			align: 'center'
		}, {
			field: 'id',
			title: '操作',
			align: 'center',
			width: '280px',
			formatter: function(value, row, index) {
				var view = '查看 ';
				var update = '修改 ';
				var review = '申请专家会审 ';

				// console.log(JSON.stringify(row));

				if (row.status === '已得到控制') {
					return view + update
				} else {
					return view + update + review;
				}

			}
		}],
	});
}

// 分页查询参数,是以键值对的形式设置的
function queryParams(params) {
	return {
		eventName: $('#eventqueryform input[name=\'eventName\']').val(), // 请求时向服务端传递的参数
		status: $('#eventqueryform input[name=\'status\']').val(), // 请求时向服务端传递的参数
		location: $('#eventqueryform input[name=\'location\']').val(), // 请求时向服务端传递的参数
		startdate: $('#eventqueryform input[name=\'startdate\']').val(), // 请求时向服务端传递的参数
		enddate: $('#eventqueryform input[name=\'enddate\']').val(), // 请求时向服务端传递的参数

		limit: params.limit, // 每页显示数量
		offset: params.offset, // SQL语句偏移量
	}
}

// 搜索按钮触发事件
$(function() {
	$("#eventquery").click(function() {
		$('#eventTable').bootstrapTable(('refresh')); // 很重要的一步,刷新url!
		// console.log("/program/area/findbyItem?offset="+0+"&"+$("#areaform").serialize())
		$('#eventqueryform input[name=\'eventName\']').val('')
		$('#eventqueryform input[name=\'status\']').val('')
		$('#eventqueryform input[name=\'location\']').val('')
		$('#eventqueryform input[name=\'startdate\']').val('')
		$('#eventqueryform input[name=\'enddate\']').val('')
	});
});

表单验证(这里是应用项目中的)

Read more

建行在线支付开发 ——服务端验签

package util.payment;
 
import java.io.IOException;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
 
import CCBSign.RSASig;
import domain.PayInfor;
import service.IPayInfoService;
import service.impl.PayInfoServiceImpl;
 
/**
 * 缴费处理 服务器端
 * 
 * @author jalena
 */
@WebServlet(urlPatterns = "/confirm/service")
public class PaymentServiceServlet extends HttpServlet {
 
	private static final long serialVersionUID = 578565845005319427L;
	private static RSASig rsaSig = new RSASig();
	private IPayInfoService service = new PayInfoServiceImpl();
	private Logger logger = LogManager.getLogger(this.getClass().getName());
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
	private PayInfor payInfor = null;
 
	static {
		// 设置验签程序公钥
		rsaSig.setPublicKey("银行提供的公钥");
	}
 
	public PaymentServiceServlet() {
		super();
	}
 
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doPost(request, response);
	}
 
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
		// 以下为建行返回字串
		String posid = request.getParameter("POSID"); // 商户柜台代码
		String branchid = request.getParameter("BRANCHID"); // 分行代码
		String orderid = request.getParameter("ORDERID"); // 定单号
		String payment = request.getParameter("PAYMENT"); // 付款金额
		String curcode = request.getParameter("CURCODE"); // 币种
		String remark1 = request.getParameter("REMARK1"); // 备注一
		String remark2 = request.getParameter("REMARK2"); // 备注二
		String success = request.getParameter("SUCCESS");	 // 成功标志 成功-Y,失败-N
		String type = request.getParameter("TYPE"); 		// 接口类型 1- 防钓鱼接口
		String referer = request.getParameter("REFERER"); // Referer信息
		String clientip = request.getParameter("CLIENTIP"); // 客户端IP
		String accdate = request.getParameter("ACCDATE"); // 系统记账日期 20160801
		String sign = request.getParameter("SIGN"); // 数字签名
		String acc_type = request.getParameter("ACC_TYPE"); // 账户类型 仅服务器通知中有此字段,页面通知无此字段
		// String usrmsg = request.getParameter("USRMSG"); // 支付账户信息 暂不返回内容
 
		// POSID=000000000&BRANCHID=110000000&ORDERID=19991101234&PAYMENT=500.00&CURCODE=01&REMARK1=&REMARK2=&ACC_TYPE=12&SUCCESS=Y&TYPE=1&REFERER=http://www.ccb.com/index.jsp&CLIENTIP=172.0.0.1&ACCDATE=20100907
 
		String src = "POSID=" + posid + "&BRANCHID=" + branchid + "&ORDERID=" + orderid + "&PAYMENT=" + payment + "&CURCODE=" + curcode + "&REMARK1=" + remark1 + "&REMARK2=" + remark2 + "&ACC_TYPE=" + acc_type
				+ "&SUCCESS=" + success + "&TYPE=" + type + "&REFERER=" + referer + "&CLIENTIP=" + clientip + "&ACCDATE=" + accdate;
 
		// 验签
		boolean signResulet = rsaSig.verifySigature(sign, src);
 
		// 时间格式转换
		java.util.Date date = null;
 
		try {
			if (accdate != null && !accdate.isEmpty()) {
				date = sdf.parse(accdate);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
 
		if (signResulet) {
 
			payInfor = service.findBySerialNumber(orderid);
 
			// 修改数据库
			if (success.equals("Y") || payment.equals(String.valueOf(payInfor.getTotalPayable())) || orderid.equals(payInfor.getSerialNumber())) {
				service.update(orderid, new Date(date.getTime()), Double.parseDouble(payment));
			}
		} else {
			logger.warn("非法请求:" + orderid);
		}
 
	}
 
}

验签DEMO

/**
 * 接下来是一些成功的签名验证  
 */
//1 
strSrc="POSID=000000000&BRANCHID=330000000&ORDERID=2004010061&PAYMENT=0.01&CURCODE=01&REMARK1=&REMARK2=&SUCCESS=N"; 
strSign="5bf88c409a13963286904e8954a4d825108f9b5bb60a8c8e5cfc05355fe4e247c777b521c7d68b8d51968285d51d1a0da0c5bd55e19268949a20dd7bd14f17422e41f3e6f7446d2136e10e796abc8b8a6f752bed5091374551d84d02f185aa3f9b516ac77ca319b06a8269389de6d7f677c619bfc0c89ccbcb125ae6dd7cc646"; 
strPubKey="30819c300d06092a864886f70d010101050003818a003081860281807d1e98e9c10625239ad9116488accf18a95125c83f5ac52f055be47614087b1bc55f1d475ddb0516b6339f7c2a8fd4def86519087cc6ecd8ea4657a5cef26d84890d00772d216e95d0aba1ea9fd39fb02202c82b71333b104e715da5de65be4cf5b83e3c0ba459777fe83a39485f145fccc94b471981348db5beab735c5889f1020111"; 
rsa.setPublicKey(strPubKey); 
if( rsa.verifySigature( strSign,strSrc) ){ 
		System.out.println("Sign OK"); 
} 
else{ 
		System.out.println("Sign failed"); 
} 
 
//2 
strSrc="POSID=000000000&BRANCHID=110000000&ORDERID=20041031&PAYMENT=0.01&CURCODE=01&REMARK1=ccb&REMARK2=test&SUCCESS=Y"; 
strSign="43680d00f5097caae18b7af3fc936cc79feb621fb166e25affbb52721e2c5c1e656f030dff46e6f0298ef82cf2fd10b6cef34fb2aa270716c30708aeb1abf0520418449614562e891cd5aede8f83b1dd65f76cc81ad5aabfd4aba409da3523ef8e82a7d19055dbb6d9241171893bf282bf64f239677ecd84abbe55fd855f48f3"; 
strPubKey="30819f300d06092a864886f70d010101050003818d0030818902818100b466e3a0fa097b57a1bc63c1fd5d97d4ef8d270d538a5aee3d1061f579f02a19cf1543701d94d81f46ce56adb84dca440a7e8f5af40538bb7a88efaf9991ead0fabc63d48fd1f12de658229e30e38ccbd9a631ec9c2d95b8590ea1a01d0931221e062544023a1ed2eb7050853fe56bf8cfd0f18243192d38855a36a87badba790203010001"; 
rsa.setPublicKey(strPubKey); 
if( rsa.verifySigature( strSign,strSrc) ){ 
		System.out.println("Sign OK"); 
} 
else{ 
		System.out.println("Sign failed"); 
} 
 
//3 
strSrc="POSID=000000000&BRANCHID=110000000&ORDERID=20041031&PAYMENT=0.01&CURCODE=01&REMARK1=ccb&REMARK2=test&SUCCESS=Y"; 
strSign="3183a60f887937846008f4ecfea725af5d65ecaefebea828459193343df7d0943f0fa9e44a298cc9a8e335bece72f8bfce8da3975e21fe4ce4d6c96894d5428e05e896b7da03f7519551b8a09bf1286ea48975b3cd49978eefbb628cc98f4f064feb898518dfb783acdd25eb6f5507fc00c16d1ae69d801a8cb970c4b7e0959b"; 
strPubKey="30819f300d06092a864886f70d010101050003818d0030818902818100d0e57a2ebbc82801980de2ad7101c67dc137432bb6ced45882b8d41cbfec7519ae8bf18b2584ae460d7d437aec069ec907935e4b39c72a6291e43a6a88c3405565357dc23c46b7072e6e50b1da4cd9cfdec616cb6ad43f0b013040307973d63b889e78fdd1389714adec663acefe5c974e513a063ba9acb96f590139b0fc571b0203010001"; 
rsa.setPublicKey(strPubKey); 
if( rsa.verifySigature( strSign,strSrc) ){ 
		System.out.println("Sign OK"); 
} 
else{ 
		System.out.println("Sign failed"); 
} 
 
/**
 * 接下来是一些错误的验签 
 */
//1 
strSrc="POSID=000000000&BRANCHID=330000000&ORDERID=120040915091516271800047&PAYMENT=0.01&CURCODE=01&REMARK1=&REMARK2=&SUCCESS=Y"; 
strSign="2732e323aa1d4f460bed516a79944001fbad2c93bbdb0d22c71066f4a69528c8699da27c13893bfcefea14dabb6f3cfa93e1414e8782124c99ffc8b059aad5f7f543993f28d262147b5206aea8d2b72aa34a256a4a5bb9c90c9aa8d2897eae90b581e7e6091fcfbb7f4885711b75b95ba7982f7519dc166e20d8b8294e4af2ad"; 
strPubKey="30819c300d06092a864886f70d010101050003818a003081860281807e4caba7c0ff9f593bb03ac8e64fcc76ebdf728b3b54493c3f62c7c94e8663d8505da39b08b00df4320c5a49d54c7774044fcc42937a0fb6a3706f724f872fe5f998cc48eb20875902b4b935e14df77b7aeb9224a5cf2db765b20fe56d8f4d5a9e03ab7943a41a179f8240e5311b3957971921fe9ccb9c24c828e99f91cc33f1020111"; 
rsa.setPublicKey(strPubKey); 
if( rsa.verifySigature( strSign,strSrc) ){ 
		System.out.println("Sign OK"); 
} 
else{ 
		System.out.println("Sign failed"); 
}

java读写Properties属性文件

Java中有个比较重要的类Properties(Java.util.Properties),主要用于读取Java的配置文件,各种语言都有自己所支持的配置文件,配置文件中很多变量是经常改变的,这样做也是为了方便用户,让用户能够脱离程序本身去修改相关的变量设置。像Python支持的配置文件是.ini文件,同样,它也有自己读取配置文件的类ConfigParse,方便程序员或用户通过该类的方法来修改.ini配置文件。在Java中,其配置文件常为.properties文件,格式为文本文件,文件的内容的格式是“键=值”的格式,文本注释信息可以用"#"来注释。

它提供了几个主要的方法:

  1. getProperty ( String key),用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到 key 所对应的 value。
  2. load ( InputStream inStream),从输入流中读取属性列表(键和元素对)。通过对指定的文件(比如说上面的 test.properties 文件)进行装载来获取该文件中的所有键 - 值对。以供 getProperty ( String key) 来搜索。
  3. setProperty ( String key, String value) ,调用 Hashtable 的方法 put 。他通过调用基类的put方法来设置 键 - 值对。
  4. store ( OutputStream out, String comments),以适合使用 load 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。与 load 方法相反,该方法将键 - 值对写入到指定的文件中去。
  5. clear (),清除所有装载的 键 - 值对。该方法在基类中提供。
package clibrary;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropertiesUtil {
	private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);

	/**
	 * 读取配置文件某属性
	 */
	public String readValue(String filePath, String key) {
		Properties props = new Properties();

		if (!filePath.startsWith("/")) {
			filePath = "/" + filePath;
		}

		try {
			InputStream inputStream = this.getClass().getResourceAsStream(filePath);
			props.load(inputStream);
		} catch (NullPointerException e) {
			logger.warn("文件不存在!");
		} catch (IOException e) {
			logger.warn(e.getMessage() + "文件流错误");
		}

		return props.getProperty(key);

	}

	/**
	 * 打印配置文件全部内容(filePath,配置文件名,如果有路径,props/test.properties)
	 */
	public void readProperties(String filePath) {
		Properties props = new Properties();
		try {
			// 注意路径以 / 开始,没有则处理
			if (!filePath.startsWith("/"))
				filePath = "/" + filePath;
			InputStream in = this.getClass().getResourceAsStream(filePath);
			props.load(in);

			props.forEach((key, value) -> logger.debug("Key = {}, Value = {}", key, value));

		} catch (Exception e) {
			logger.error(e.getMessage());
		}
	}

	/**
	 * 将值写入配置文件
	 */
	public void writeProperties(String fileName, String parameterName, String parameterValue) {
		if (!fileName.startsWith("/"))
			fileName = "/" + fileName;
		FileOutputStream outputStream = null;
		Properties pps = new Properties();

		try {
			pps.load(this.getClass().getResourceAsStream(fileName));

			pps.setProperty(parameterName, parameterValue);
			outputStream = new FileOutputStream("src/main/resources/jdbc.properties");
			pps.store(outputStream, null);
		} catch (IOException e) {
			logger.warn(e.getMessage());
		} finally {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					e.getMessage();
				}
			}
		}
	}
}

测试类

package clibrary;

import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.time.LocalTime;

import static org.junit.Assert.*;

public class PropertiesUtilTest {

	private Logger logger = LoggerFactory.getLogger(getClass());
	PropertiesUtil propertiesUtil = null;

	@Before
	public void init(){
		propertiesUtil = new PropertiesUtil();
	}

	@Test
	public void testReadValue(){
		String minIdle = propertiesUtil.readValue("jdbc.properties", "minIdle");
		assertEquals("5",minIdle);
		logger.debug(minIdle);
	}

	@Test
	public void testReadProperties(){
		propertiesUtil.readProperties("jdbc.properties");
	}

	@Test
	public void testWriteProperties(){
		propertiesUtil.writeProperties("jdbc.properties","Jalena","19");
	}

	@Test
	public void showTime(){
		logger.debug(LocalTime.now().toString());
		logger.debug(LocalDateTime.now().toString());
	}

}

Archives