服务器接收端
/**
*
*/
package org.liufei.net.file;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.dom4j.DocumentException;
import org.liufei.net.ServerConfig;
import org.liufei.util.FileDesHandler;
import org.liufei.util.entity.FileDes;
/**
* @author 刘飞
*
*/
public class FileReceiveHandler extends IoHandlerAdapter {
private static final Logger logger = Logger.getLogger(FileReceiveHandler.class) ;
private ServerConfig config = ServerConfig.getInstance() ;
private FileChannel fileChannel = null;
/**
*
*/
public FileReceiveHandler() {
}
private void initFileChannel() throws DocumentException, IOException {
String time = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss").format(GregorianCalendar.getInstance().getTime()) ;
File file = new File(
config.directory(),
FileDesHandler.query(FileDes.FILE_DES_ID).getFileName()) ;
if(!file.exists()) {
file.createNewFile() ;
}
else {
file = new File(
config.directory(),
time + "_" +
FileDesHandler.query(FileDes.FILE_DES_ID).getFileName()) ;
}
fileChannel = new FileOutputStream(file).getChannel() ;
}
private void closeFileChannel() {
if(fileChannel != null) {
try {
if(fileChannel.isOpen()) {
FileLock fileLock = fileChannel.lock() ;
if(fileLock != null) {
fileLock.release() ;
}
fileChannel.close() ;
fileChannel = null ;
}
} catch (IOException e) {
logger.error("文件解锁异常。", e) ;
throw new RuntimeException("文件解锁异常。", e) ;
}
}
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#exceptionCaught(org.apache
* .mina.core.session.IoSession, java.lang.Throwable)
*/
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
closeFileChannel() ;
session.close(true) ;
logger.error("file upload error .", cause) ;
FileDesHandler.close() ;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#messageReceived(org.apache
* .mina.core.session.IoSession, java.lang.Object)
*/
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
if(fileChannel == null){
try {
initFileChannel() ;
} catch (DocumentException e) {
logger.error("reading xml config error.", e) ;
} catch (IOException e) {
logger.error("init FileChannel error.", e) ;
}
}
logger.debug("Message From IP >>> " + session.getRemoteAddress().toString() + " <<<") ;
IoBuffer ib = (IoBuffer) message;
logger.debug("\n\t\tDATA >>> " + message.toString() + "\n\t\tDATA SIZE >>> " + ib.capacity() + "\n") ;
fileChannel.write(ib.buf());
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#messageSent(org.apache.
* mina.core.session.IoSession, java.lang.Object)
*/
@Override
public void messageSent(IoSession session, Object message) throws Exception {
super.messageSent(session, message);
logger.debug("super.messageSent(IoSession session, Object message)\n\t\t >>> " + session.getRemoteAddress().toString() + " <<<") ;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#sessionClosed(org.apache
* .mina.core.session.IoSession)
*/
@Override
public void sessionClosed(IoSession session) throws Exception {
super.sessionClosed(session);
logger.debug("super.sessionClosed(IoSession session)\n\t\t >>> " + session.getRemoteAddress().toString() + " <<<") ;
FileDesHandler.close() ;
closeFileChannel() ;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#sessionCreated(org.apache
* .mina.core.session.IoSession)
*/
@Override
public void sessionCreated(IoSession session) throws Exception {
super.sessionCreated(session);
logger.debug("super.sessionCreated(IoSession session)\n\t\t >>> " + session.getRemoteAddress().toString() + " <<<") ;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#sessionIdle(org.apache.
* mina.core.session.IoSession, org.apache.mina.core.session.IdleStatus)
*/
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
super.sessionIdle(session, status);
logger.debug("super.sessionIdle(IoSession session, IdleStatus status)\n\t\t >>> " + session.getRemoteAddress().toString() + " <<<") ;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#sessionOpened(org.apache
* .mina.core.session.IoSession)
*/
@Override
public void sessionOpened(IoSession session) throws Exception {
super.sessionOpened(session);
logger.debug("super.sessionOpened(IoSession session)\n\t\t >>> " + session.getRemoteAddress().toString() + " <<<") ;
}
}
package org.liufei.net.file;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.log4j.Logger;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.liufei.net.ServerConfig;
public class FileServer {
private static final Logger logger = Logger.getLogger(FileServer.class) ;
private ServerConfig config = ServerConfig.getInstance() ;
public SocketAcceptor server() {
int port = config.port() ;
try {
SocketAcceptor socketAcceptor = new NioSocketAcceptor();
socketAcceptor.getFilterChain();
socketAcceptor.setHandler(new FileReceiveHandler());
socketAcceptor.bind(new InetSocketAddress(port));
logger.debug("start NET FILE SERVER success !\n\t\t HTTP PORT >>> " + port + "\n") ;
return socketAcceptor ;
} catch (IOException e) {
logger.error("start NET FILE SERVER error !\n\t\t HTTP PORT >>> " + port + "\n", e) ;
throw new RuntimeException("start NET FILE SERVER error !\n\t\t HTTP PORT >>> " + port + "\n", e) ;
}
}
}
客户端
package org.liufei.net.file;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
/**
*
* @author 刘飞
*
*/
public class FileSenderHandler extends IoHandlerAdapter {
/**
*
*/
public FileSenderHandler() {
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#exceptionCaught(org.apache
* .mina.core.session.IoSession, java.lang.Throwable)
*/
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
super.exceptionCaught(session, cause);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#messageReceived(org.apache
* .mina.core.session.IoSession, java.lang.Object)
*/
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
super.messageReceived(session, message);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#messageSent(org.apache.
* mina.core.session.IoSession, java.lang.Object)
*/
@Override
public void messageSent(IoSession session, Object message) throws Exception {
super.messageSent(session, message);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#sessionClosed(org.apache
* .mina.core.session.IoSession)
*/
@Override
public void sessionClosed(IoSession session) throws Exception {
super.sessionClosed(session);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#sessionCreated(org.apache
* .mina.core.session.IoSession)
*/
@Override
public void sessionCreated(IoSession session) throws Exception {
super.sessionCreated(session);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#sessionIdle(org.apache.
* mina.core.session.IoSession, org.apache.mina.core.session.IdleStatus)
*/
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
super.sessionIdle(session, status);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.core.service.IoHandlerAdapter#sessionOpened(org.apache
* .mina.core.session.IoSession)
*/
@Override
public void sessionOpened(IoSession session) throws Exception {
super.sessionOpened(session);
}
}
package org.liufei.net.file;
import java.io.File;
import java.io.FileInputStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import org.apache.log4j.Logger;
import org.apache.mina.core.RuntimeIoException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.liufei.net.ClientConfig;
import org.liufei.net.util.FileDesHandler;
import org.liufei.net.util.JavaZip;
import org.liufei.net.util.entity.FileDes;
public class FileClient {
private static final int CAPACITY = 2048 * 1000;
private static final Logger logger = Logger.getLogger(FileClient.class) ;
private ClientConfig config = ClientConfig.getInstance() ;
private String host = "172.16.0.11";
private int port = 8888;
public static void main(String[] args) {
logger.debug("please run new FileClient().upload(String/File)") ;
System.out.println("please run new FileClient().upload(String/File)");
}
/**
* 只能一次上传一个文件
* @param path
* @return
*/
public boolean upload(String path) {
return upload(new File(path)) ;
}
/**
* 只能一次上传一个文件
* @param file
* @return
*/
public boolean upload(File file) {
if(file.isFile() && !file.isDirectory()) {
return netFileUpload(file, FileDes.UNZIP_NO) ;
}
else if(file.isDirectory()){
File zipFile = new File(file.getAbsolutePath() + ".zip");
try {
JavaZip.zip(file, zipFile);
return netFileUpload(zipFile, FileDes.UNZIP_YES) ;
} catch (Exception e) {
logger.error("传输目录文件时压缩传输异常.", e) ;
throw new RuntimeException("传输目录文件时压缩传输异常.", e) ;
}
}
else {
return false ;
}
}
/**
* File f = new File("D:\\MyBatis 3 User Guide Simplified Chinese.pdf");
*
* @param file
* @return
*/
private boolean netFileUpload(final File file, final int unZip_mark) {
boolean flag = false ;
host = config.host();
port = config.port();
NioSocketConnector connector = null ;
ConnectFuture connectFuture = null ;
IoSession session = null;
try {
connector = new NioSocketConnector();
connector.getFilterChain();
connector.setHandler(new FileSenderHandler());
connectFuture = connector.connect(new InetSocketAddress(host, port));
logger.debug("connect to host >>> " + host + " <<< success.") ;
for (;;) {
try {
ConnectFuture future = connector.connect(new InetSocketAddress(host, port));
future.awaitUninterruptibly();
session = future.getSession();
logger.debug("connect to host >>> " + host + " <<< success.") ;
break;
} catch (RuntimeIoException e) {
logger.error("connect to host >>> " + host + " <<< error.", e) ;
close(
connector, e,
connectFuture, e,
session, e
) ;
Thread.sleep(5000);
}
}
FileInputStream in = new FileInputStream(file);
FileChannel fileChannel = in.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(CAPACITY);
logger.debug("begin upload file >>> " + file.getAbsolutePath() + " <<<") ;
FileDes fileDes = FileDesHandler.query(FileDes.FILE_DES_ID) ;
String filePath = file.getAbsolutePath().replace(File.separatorChar, '/') ;
if(fileDes == null) {
fileDes = new FileDes() ;
fileDes.setSource(filePath) ;
fileDes.setUnZip(unZip_mark) ;
fileDes.setId(FileDes.FILE_DES_ID) ;
fileDes.setFileName(file.getName()) ;
fileDes.setFileLength(file.length()) ;
fileDes.setMark(FileDes.MARK_START) ;
fileDes.setStatus(FileDes.STATUS_ERROR) ;
fileDes.setEnd(FileDes.END_NO) ;
FileDesHandler.insert(fileDes) ;
}
else {
fileDes.setSource(filePath) ;
fileDes.setUnZip(unZip_mark) ;
fileDes.setFileName(file.getName()) ;
fileDes.setFileLength(file.length()) ;
fileDes.setMark(FileDes.MARK_START) ;
fileDes.setStatus(FileDes.STATUS_ERROR) ;
fileDes.setEnd(FileDes.END_NO) ;
FileDesHandler.update(fileDes) ;
}
while (true) {
/**
* 不间断发送会导致buffer异常
*/
Thread.sleep(1000);
byteBuffer.clear();
int i = fileChannel.read(byteBuffer);
if (i == -1) {
flag = true ;
logger.debug("upload file >>> " + file.getAbsolutePath() + " <<< success .") ;
fileDes.setFileName(file.getName()) ;
fileDes.setFileLength(file.length()) ;
fileDes.setSource(filePath) ;
fileDes.setUnZip(unZip_mark) ;
fileDes.setMark(FileDes.MARK_START) ;
fileDes.setStatus(FileDes.STATUS_SUCESS) ;
fileDes.setEnd(FileDes.END_YES) ;
FileDesHandler.update(fileDes) ;
FileDesHandler.close() ;
close(
connector, null,
connectFuture, null,
session, null
) ;
if(unZip_mark == FileDes.UNZIP_YES) {
logger.debug("delete zip file : " + file.getAbsolutePath()) ;
file.delete() ;
}
break;
}
IoBuffer io_buffer_apache = IoBuffer.wrap(byteBuffer);
byteBuffer.flip();
Thread.sleep(1000);
session.write(io_buffer_apache);
Thread.sleep(1000);
}
close(
connector, null,
connectFuture, null,
session, null
) ;
session.close(true);
} catch (Throwable e) {
close(
connector, e,
connectFuture, e,
session, e
) ;
FileDesHandler.close() ;
throw new RuntimeException("NET FILE SERVER UPLOAD FILE [" + file + "] [host:" + host + ", port:" + port + "] error >>>", e) ;
}
return flag ;
}
private void close(
NioSocketConnector connector,
Throwable e1,
ConnectFuture connectFuture,
Throwable e2,
IoSession session,
Throwable e3
) {
if(connector != null) {
if(connector.isActive()) {
connector.dispose(true) ;
}
if(!connector.isDisposed()) {
connector.dispose(true) ;
}
if(e1 != null)
logger.error("NIO Socket Connector [host:" + host + ", port:" + port + "] Dispose >>>", e1) ;
else
logger.debug("NIO Socket Connector [host:" + host + ", port:" + port + "] Dispose >>>") ;
connector = null ;
}
if(connectFuture != null) {
if(connectFuture.isConnected()) {
connectFuture.cancel() ;
}
if(!connectFuture.isCanceled()) {
connectFuture.cancel() ;
}
connectFuture = null ;
if(e2 != null)
logger.error("Connect Future [host:" + host + ", port:" + port + "] Cancel >>>", e2) ;
else
logger.debug("Connect Future [host:" + host + ", port:" + port + "] Cancel >>>") ;
}
if(session != null) {
if(session.isConnected()) {
session.close(true) ;
}
session = null;
if(e3 != null)
logger.error("IoSession [host:" + host + ", port:" + port + "] closing >>>", e3) ;
else
logger.debug("IoSession [host:" + host + ", port:" + port + "] closing >>>") ;
}
}
}
服务器
package org.liufei.net;
import org.apache.log4j.Logger;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.liufei.net.file.FileServer;
import org.liufei.net.ui.ServerManager;
public class Server {
private static final Server server = new Server() ;
private ServerConfig config = ServerConfig.getInstance() ;
private SocketAcceptor socketAcceptor = null ;
/**
* net file server
*/
private Server() {
}
public static Server getInstance() {
return server ;
}
/**
* 启动一个服务并返回当前服务实例
* @return
*/
public void start(){
try {
socketAcceptor = new FileServer().server() ;
if(socketAcceptor != null) {
START_FLAG.set(START_SUCCESS) ;
logger.debug("start NET FILE SERVER SUCCESS.") ;
}
else {
START_FLAG.set(START_ERROR) ;
logger.debug("start NET FILE SERVER ERROR.") ;
}
} catch (Exception e) {
START_FLAG.set(START_ERROR) ;
logger.error("start error message.", e) ;
ServerManager manager = ServerManager.getInstance() ;
manager.setEnabledTrue() ;
}
}
public void shutdown() {
if(config == null) {
config = ServerConfig.getInstance() ;
}
if(socketAcceptor != null) {
try {
if(socketAcceptor.isActive()) {
socketAcceptor.unbind() ;
}
if(!socketAcceptor.isDisposed()) {
socketAcceptor.dispose(true);
}
socketAcceptor = null ;
logger.debug("\r\nNET FILE SERVER shut down on host [ " + config.host() + " ], port [ " + config.port() + " ] .\r\n") ;
} catch (Exception e) {
logger.error("shut down error message.", e) ;
}
}
}
/**
* 是否已启动成功
* @return
*/
public boolean isStarted() {
Integer start_flag = START_FLAG.get() ;
if(start_flag == START_SUCCESS)
return true ;
else if(start_flag == START_ERROR)
return false ;
else
return false ;
}
private static final Logger logger = Logger.getLogger(Server.class) ;
private static final ThreadLocal<Integer> START_FLAG = new ThreadLocal<Integer>() ;
/**
* 启动成功
*/
public static final Integer START_SUCCESS = 1 ;
/**
* 启动失败
*/
public static final Integer START_ERROR = 0 ;
}
package org.liufei.net;
import java.io.File;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.liufei.net.ui.ServerManager;
import org.liufei.net.util.AddJavaLibraryPath;
import org.liufei.net.util.FileCopyUtils;
import org.liufei.net.util.RegeditTool;
/**
*
* @author 刘飞
*
*/
public class ServerRunner {
private static final Logger logger = Logger.getLogger(ServerRunner.class) ;
public static void main(String[] args) {
try {
if(ServerConfig.getInstance().regeditAuto()) {
setAutoStart() ;
logger.debug("set auto start success.") ;
}
} catch (Exception e) {
logger.debug("set auto start error.") ;
logger.error("set auto atart error message.", e) ;
}
logger.debug("show net file server manager.") ;
ServerManager.showNetFileServer(true) ;
logger.debug("show net file server manager end.") ;
}
public static void setAutoStart() throws DocumentException, IOException {
if(ServerConfig.getInstance().isCopyDLL())
FileCopyUtils.copy(new File("lib/ICE_JNIRegistry.dll"), new File(ServerConfig.getInstance().copyDLLDest())) ;
String JAVA_LIBRARY_PATH = System.getProperty("java.library.path") ;
printLibrary("JAVA_LIBRARY_PATH", JAVA_LIBRARY_PATH) ;
String ADD_DLL_PATH = new File("lib/ICE_JNIRegistry.dll").getAbsolutePath() + File.pathSeparator + JAVA_LIBRARY_PATH ;
System.setProperty("java.library.path", ADD_DLL_PATH) ;
AddJavaLibraryPath.addDir(new File("lib").getAbsolutePath()) ;
printLibrary("After Add DLL LIB JAVA_LIBRARY_PATH", System.getProperty("java.library.path")) ;
loadLibrary() ;
RegeditTool.regeditNetFileServer() ;
}
private static void loadLibrary() {
try {
System.loadLibrary( "ICE_JNIRegistry" );
}
catch ( UnsatisfiedLinkError e )
{
System.err.println
( "ERROR You have not installed the DLL named '"
+ "ICE_JNIRegistry.DLL'.\n\t" + e.getMessage() );
}
catch ( SecurityException e )
{
System.err.println
( "ERROR You do not have permission to load the DLL named '"
+ "ICE_JNIRegistry.DLL'.\n\t" + e.getMessage() );
}
}
public static String printLibrary(String message, String java_library_path) {
String java_library_path_temp = java_library_path ;
StringBuffer buffer = new StringBuffer() ;
String[] libs = java_library_path_temp.split(File.pathSeparator) ;
for (String lib : libs) {
buffer.append(lib + "\n") ;
}
logger.debug("\n" + message + "(number = " + libs.length + ") : \n" + buffer.toString()) ;
return buffer.toString() ;
}
}
工具
package org.liufei.net.util;
import java.io.IOException;
import java.lang.reflect.Field;
/**
* 动态加载增加java.library.path属性
*
* @author 刘飞
*
*/
public class AddJavaLibraryPath {
/**
* 通过反射实现动态增加java.library.path 本方法和jvm加联,用到了ClassLoader里的usr_paths。
*
* @param s
* @throws IOException
*/
public static void addDir(String s) throws IOException {
try {
Field field = ClassLoader.class.getDeclaredField("usr_paths");
field.setAccessible(true);
String[] paths = (String[]) field.get(null);
for (int i = 0; i < paths.length; i++) {
if (s.equals(paths[i])) {
return;
}
}
String[] tmp = new String[paths.length + 1];
System.arraycopy(paths, 0, tmp, 0, paths.length);
tmp[paths.length] = s;
field.set(null, tmp);
} catch (IllegalAccessException e) {
throw new IOException(
"Failed to get permissions to set library path");
} catch (NoSuchFieldException e) {
throw new IOException(
"Failed to get field handle to set library path");
}
}
}
package org.liufei.net.util;
import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.liufei.net.ServerConfig;
import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.NoSuchValueException;
import com.ice.jni.registry.RegStringValue;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
/**
* java 操作注册表
*
* @author 刘飞
*/
public class RegeditTool {
private static final Logger logger = Logger.getLogger(RegeditTool.class);
/**
* 把信息存储到注册表HKEY_LOCAL_MACHINE下的某个节点的某一变量中,有则修改,无则创建
*
* @param folder
* @param subKeyNode
* @param subKeyName
* @param subKeyValue
* @return
*/
public static boolean setValue(String folder, String subKeyNode,
String subKeyName, String subKeyValue) {
try {
RegistryKey software = Registry.HKEY_LOCAL_MACHINE
.openSubKey(folder);
RegistryKey subKey = software.createSubKey(subKeyNode, "");
subKey
.setValue(new RegStringValue(subKey, subKeyName,
subKeyValue));
subKey.closeKey();
return true;
} catch (NoSuchKeyException e) {
logger.error("No Such Key.", e);
} catch (NoSuchValueException e) {
logger.error("No Such Value.", e);
} catch (RegistryException e) {
logger.error("Registry Error.", e);
}
return false;
}
/**
* 删除注册表中某节点下的某个变量
*
* @param folder
* @param subKeyNode
* @param subKeyName
* @return
*/
public static boolean deleteValue(String folder, String subKeyNode,
String subKeyName) {
try {
RegistryKey software = Registry.HKEY_LOCAL_MACHINE
.openSubKey(folder);
RegistryKey subKey = software.createSubKey(subKeyNode, "");
subKey.deleteValue(subKeyName);
subKey.closeKey();
return true;
} catch (NoSuchKeyException e) {
logger.error("No Such Key.", e);
} catch (NoSuchValueException e) {
logger.error("No Such Value.", e);
} catch (RegistryException e) {
logger.error("Registry Error.", e);
}
return false;
}
/**
* 删除注册表中某节点下的某节点
*
* @param folder
* @param subKeyNode
* @return
*/
public static boolean deleteSubKey(String folder, String subKeyNode) {
try {
RegistryKey software = Registry.HKEY_LOCAL_MACHINE
.openSubKey(folder);
software.deleteSubKey(subKeyNode);
software.closeKey();
return true;
} catch (NoSuchKeyException e) {
logger.error("No Such Key.", e);
} catch (NoSuchValueException e) {
logger.error("No Such Value.", e);
} catch (RegistryException e) {
logger.error("Registry Error.", e);
}
return false;
}
/**
* 打开注册表项并读出相应的变量名的值
*
* @param folder
* @param subKeyNode
* @param subKeyName
* @return
*/
public static String getValue(String folder, String subKeyNode,
String subKeyName) {
String value = "";
try {
RegistryKey software = Registry.HKEY_LOCAL_MACHINE
.openSubKey(folder);
RegistryKey subKey = software.openSubKey(subKeyNode);
value = subKey.getStringValue(subKeyName);
subKey.closeKey();
} catch (NoSuchKeyException e) {
logger.error("No Such Key.", e);
} catch (NoSuchValueException e) {
logger.error("No Such Value.", e);
} catch (RegistryException e) {
logger.error("Registry Error.", e);
}
return value;
}
public static void regeditNetFileServer() throws DocumentException {
setValue(
"SOFTWARE",
"Microsoft\\Windows\\CurrentVersion\\Run",
ServerConfig.getInstance().regeditKey(),
ServerConfig.getInstance().regeditValue()
);
}
}
package org.liufei.util.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.log4j.Logger;
/**
* JDBC事物工具。
*
* @author 刘飞
*
*/
public abstract class JdbcTransaction<T> {
private Logger logger = Logger.getLogger(JdbcTransaction.class);
private Connection conn;
private boolean isCloseConnection = false;
/**
* 自动控制的事物块。
*
* @param conn
* 数据库连接
* @param isCloseConnection
* 完成事物以后是否关闭连接, 默认为false不关闭。
*/
public JdbcTransaction(Connection conn, boolean isCloseConnection) {
super();
this.conn = conn;
this.isCloseConnection = isCloseConnection;
}
public final T doInTransaction() throws SQLException {
T result = null;
boolean autoCommit = false;
if (this.conn != null) {
try {
/**
* 保存Connection原始属性
*/
autoCommit = this.conn.getAutoCommit();
/**
* 在本代码快里设置Connection非自动提交
*/
if (this.conn.getAutoCommit()) {
this.conn.setAutoCommit(false);
}
/**
* 执行事务代码块
*/
result = this.doInTransaction(this.conn);
/**
* 提交事务
*/
this.conn.commit();
/**
* 恢复Connection的原始属性, 以免对其他代码造成影响。
*/
this.conn.setAutoCommit(autoCommit);
} catch (SQLException e) {
logger.error("事物代码块异常 ", e);
try {
this.conn.rollback();
} catch (SQLException e1) {
logger.error("事物回滚时异常 ", e);
throw new SQLException("事物回滚时异常 : "
+ e1.getLocalizedMessage());
}
throw new SQLException("事物代码块异常 : " + e.getLocalizedMessage());
} finally {
try {
this.conn.setAutoCommit(autoCommit);
} catch (SQLException e) {
logger.error("恢复Connection自动提交属性异常 ", e);
throw new SQLException("恢复Connection自动提交属性异常 : \n"
+ e.getLocalizedMessage());
}
if (this.isCloseConnection) {
try {
this.conn.close();
this.conn = null;
} catch (SQLException e) {
logger.error("数据库连接关闭时 ", e);
throw new SQLException("数据库连接关闭时 : "
+ e.getLocalizedMessage());
}
}
}
}
return result;
}
protected abstract T doInTransaction(Connection conn) throws SQLException;
}
package org.liufei.util.jdbc;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
/**
* jdbc操作工具。
*
* @author 刘飞
*
*/
public class JdbcUtil {
private static final Logger logger = Logger.getLogger(JdbcUtil.class);
/**
* 用于执行对数据库的查询。
*
* @param conn
* @param sql
* @return
* @throws SQLException
*/
public static ResultSet executeQuery(Connection conn, String sql)
throws SQLException {
if (conn != null && sql != null) {
if(isSupportsResultSet_TYPE_SCROLL_INSENSITIVE_CONCUR_READ_ONLY(conn) && isSupportsResultSetType_TYPE_SCROLL_INSENSITIVE(conn)) {
return conn.prepareStatement(sql,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY).executeQuery();
}
else {
return conn.prepareStatement(sql).executeQuery();
}
} else {
logger.error("数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].") ;
throw new SQLException(
"数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].");
}
}
/**
*
* @param <T>
* @param conn
* @param callback
* @param isCloseConnection
* 完成事物以后是否关闭连接。
* @return
* @throws SQLException
*/
public static <T> T executeSQL(final Connection conn, final ConnectionCallback<T> callback, boolean isCloseConnection) throws SQLException {
return (T) new JdbcTransaction<T>(conn, isCloseConnection){
@Override
public T doInTransaction(Connection conn) throws SQLException {
return callback.doInSql(conn);
}}
.doInTransaction();
}
/**
* 用于执行对数据库的修改更新和删除。
*
* @param conn
* @param sql
* @param isCloseConnection
* 完成事物以后是否关闭连接。
* @return
* @throws SQLException
*/
public static int executeSQLDML(Connection conn, final String sql,
boolean isCloseConnection) throws SQLException {
if (conn != null && sql != null) {
JdbcTransaction<Integer> jdbcTransaction = new JdbcTransaction<Integer>(
conn, isCloseConnection) {
@Override
public Integer doInTransaction(Connection conn)
throws SQLException {
int result = 0 ;
if(isSupportsResultSet_TYPE_SCROLL_INSENSITIVE_CONCUR_UPDATABLE(conn) && isSupportsResultSetType_TYPE_SCROLL_INSENSITIVE(conn)) {
/**
* 执行数据库更新
*/
result = conn.prepareStatement(sql,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE).executeUpdate();
}
else {
/**
* 执行数据库更新
*/
result = conn.prepareStatement(sql).executeUpdate();
}
return result;
}
};
return jdbcTransaction.doInTransaction();
} else {
logger.error("数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].") ;
throw new SQLException(
"数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].");
}
}
/**
* PreparedStatement 执行批处理。
*
* @param conn
* @param batchSql
* 批量更新SQL
* @param parameters
* 二维参数列表, 用于注入SQL中
* @param times
* 每多少条执行一次更新
* @param isCloseConnection
* 完成事物以后是否关闭连接。
* @return 返回此批处理共影响的数据条数。
* @throws SQLException
*/
public static int executePreparedStatementSQLBatch(Connection conn,
final String batchSql, final Object[][] parameters,
final int times, final boolean isCloseConnection) throws SQLException {
if (conn != null && batchSql != null) {
if (batchSql.length() > 0) {
if(isSupportsBatchUpdates(conn)) {
JdbcTransaction<Integer> jdbcTransaction = new JdbcTransaction<Integer>(
conn, isCloseConnection) {
@Override
public Integer doInTransaction(Connection conn)
throws SQLException {
int result = 0;
/**
* 执行批量操作
*/
PreparedStatement pstmt = conn
.prepareStatement(batchSql);
int i = 1;
for (Object[] params : parameters) {
int j = 1;
for (Object param : params) {
pstmt.setObject(j, param);
j++;
}
if (i % times == 0) {
int[] rs = pstmt.executeBatch();
for (int k : rs) {
result += k;
}
}
i++;
}
release(null, pstmt, null, false) ;
return result;
}
};
return jdbcTransaction.doInTransaction();
}
else {
throw new RuntimeException("this database does not supports batch updates.") ;
}
} else {
return 0;
}
} else {
logger.error("数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].") ;
throw new SQLException(
"数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].");
}
}
/**
* Statement执行批处理。
*
* @param conn
* @param batchSql
* @param isCloseConnection
* 完成事物以后是否关闭连接。
* @return 返回此批处理共影响的数据条数。
* @throws SQLException
*/
public static int executeStatementSQLBatch(Connection conn,
final String[] batchSql, final int times, final boolean isCloseConnection)
throws SQLException {
if (conn != null && batchSql != null) {
if (batchSql.length > 0) {
if(isSupportsBatchUpdates(conn)) {
JdbcTransaction<Integer> jdbcTransaction = new JdbcTransaction<Integer>(
conn, isCloseConnection) {
@Override
public Integer doInTransaction(Connection conn)
throws SQLException {
int rs = 0;
/**
* 执行批量操作
*/
Statement stmt = conn.createStatement();
int k = 0 ;
for (String sql : batchSql) {
if (sql.trim().length() > 0) {
stmt.addBatch(sql);
}
if(k % times == 0) {
int[] result = stmt.executeBatch();
for (int i : result) {
rs += i;
}
}
}
release(null, stmt, null, false) ;
return rs;
}
};
return jdbcTransaction.doInTransaction();
}
else {
throw new RuntimeException("this database does not supports batch updates.") ;
}
} else {
return 0;
}
} else {
logger.error("数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].") ;
throw new SQLException(
"数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].");
}
}
/**
* 设置只读模式
* @param connection
* @param readOnly
* @throws SQLException
*/
public static void setReadOnly(Connection connection, boolean readOnly) throws SQLException {
connection.setReadOnly(readOnly) ;
}
/**
* 释放数据库资源。
*
* @param rs
* @param stmt
* @param conn
* @param isCloseConnection
* 是否关闭数据库连接。
* @throws SQLException
*/
public static void release(ResultSet rs, Statement stmt, Connection conn,
boolean isCloseConnection) throws SQLException {
if (rs != null) {
rs.close();
rs = null;
}
if (stmt != null) {
stmt.close();
stmt = null;
}
if (conn != null) {
if (!conn.isClosed() && !conn.getAutoCommit()) {
conn.rollback();
}
if (isCloseConnection) {
conn.close();
conn = null;
}
}
}
/**
*
* @param connection
* @param autoCommit
* @throws SQLException
*/
public static void setAutoCommit(Connection connection, boolean autoCommit) throws SQLException {
connection.setAutoCommit(autoCommit);
}
/**
* 是否支持ResultSet.TYPE_SCROLL_INSENSITIVE
* @param connection
* @return
* @throws SQLException
*/
public static boolean isSupportsResultSetType_TYPE_SCROLL_INSENSITIVE(Connection connection) throws SQLException {
return connection.getMetaData().supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE) ;
}
/**
* 是否支持ResultSet.CONCUR_READ_ONLY
* @param connection
* @return
* @throws SQLException
*/
public static boolean isSupportsResultSet_TYPE_SCROLL_INSENSITIVE_CONCUR_READ_ONLY(Connection connection) throws SQLException {
return connection.getMetaData().supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY) ;
}
/**
* 是否支持ResultSet.CONCUR_UPDATABLE
* @param connection
* @return
* @throws SQLException
*/
public static boolean isSupportsResultSet_TYPE_SCROLL_INSENSITIVE_CONCUR_UPDATABLE(Connection connection) throws SQLException {
return connection.getMetaData().supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE) ;
}
/**
* 是否支持 ANSI92 SQL
* @param connection
* @return
* @throws SQLException
*/
public static boolean isSupportsANSI92FullSQL(Connection connection) throws SQLException {
return connection.getMetaData().supportsANSI92FullSQL() ;
}
/**
* 是否支持SelectForUpdate
* @param connection
* @return
* @throws SQLException
*/
public static boolean isSupportsSelectForUpdate(Connection connection) throws SQLException {
return connection.getMetaData().supportsSelectForUpdate() ;
}
/**
* 是否支持批量更新。
* @param connection
* @return
* @throws SQLException
*/
public static boolean isSupportsBatchUpdates(Connection connection) throws SQLException {
return connection.getMetaData().supportsBatchUpdates() ;
}
/**
* 是否支持事务保存点
* @param connection
* @return
* @throws SQLException
*/
public static boolean isSupportsSavepoints(Connection connection) throws SQLException {
return connection.getMetaData().supportsSavepoints() ;
}
/**
* 设置事务保存点
* @param connection
* @param name
* @return
* @throws SQLException
*/
public static Savepoint setSavePoint(Connection connection, String name) throws SQLException {
if (isSupportsSavepoints(connection)) {
return connection.setSavepoint(name);
} else {
throw new RuntimeException("this database does not supports savepoints.") ;
}
}
/**
* 回滚到事务点
* @param connection
* @param savepoint
* @throws SQLException
*/
public static void rollback(Connection connection, Savepoint savepoint) throws SQLException {
if (savepoint == null) {
connection.rollback();
} else {
if(isSupportsSavepoints(connection))
connection.rollback(savepoint);
else
connection.rollback();
}
}
/**
* 回滚到事务点
* @param connection
* @throws SQLException
*/
public static void rollback(Connection connection) throws SQLException {
connection.rollback();
}
/**
* 提交事务
* @param connection
* @param savepoint
*/
public static void commit(Connection connection, Savepoint savepoint) throws SQLException {
if(savepoint == null) {
if (!connection.getAutoCommit()) {
connection.commit();
}
}
else {
if(isSupportsSavepoints(connection)) {
if (!connection.getAutoCommit()) {
connection.releaseSavepoint(savepoint);
}
}
else {
if (!connection.getAutoCommit()) {
connection.commit();
}
}
}
}
/**
* 提交事务
* @param connection
*/
public static void commit(Connection connection) throws SQLException {
if (!connection.getAutoCommit()) {
connection.commit();
}
}
/**
* 获取数据库连接数据源。
*
* @param jndiName
* jndi名称
* @return
* @throws NamingException
*/
public static DataSource getDataSource(String jndiName)
throws NamingException {
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(jndiName);
return ds;
}
public static Connection initConnection(String driver, String url, String user, String password) {
try {
Class.forName(driver).newInstance() ;
return DriverManager.getConnection(url, user, password) ;
} catch (InstantiationException e) {
logger.error("Driver Class >>> " + driver + ", " + url + ", " + user + ", " + password + " <<< Instantiation Error.", e) ;
throw new RuntimeException("Driver Class >>> " + driver + ", " + url + ", " + user + ", " + password + " <<< Instantiation Error.", e) ;
} catch (IllegalAccessException e) {
logger.error("Driver Class >>> " + driver + ", " + url + ", " + user + ", " + password + " <<< Illegal Access.", e) ;
throw new RuntimeException("Driver Class >>> " + driver + ", " + url + ", " + user + ", " + password + " <<< Illegal Access.", e) ;
} catch (ClassNotFoundException e) {
logger.error("Driver Class >>> " + driver + ", " + url + ", " + user + ", " + password + " <<< Not Found.", e) ;
throw new RuntimeException("Driver Class >>> " + driver + ", " + url + ", " + user + ", " + password + " <<< Not Found.", e) ;
} catch (SQLException e) {
logger.error("DriverManager Get Connection >>> " + driver + ", " + url + ", " + user + ", " + password + " <<< Error.", e) ;
throw new RuntimeException("DriverManager Get Connection >>> " + driver + ", " + url + ", " + user + ", " + password + " <<< Error.", e) ;
}
}
/**
* 测试数据库连接是否有效。
*
* @param driver
* @param user
* @param password
* @param url
* @return
*/
public static boolean testConnection(String driver, String user,
String password, String url) {
try {
Class.forName(driver).newInstance();
Connection connection = DriverManager.getConnection(url, user,
password);
DatabaseMetaData metaData = connection.getMetaData();
if (user.equals(metaData.getUserName())) {
return true;
}
} catch (InstantiationException e) {
logger.error("测试数据库连接异常", e) ;
} catch (IllegalAccessException e) {
logger.error("测试数据库连接异常", e) ;
} catch (ClassNotFoundException e) {
logger.error("测试数据库连接异常", e) ;
} catch (SQLException e) {
logger.error("测试数据库连接异常", e) ;
}
return false;
}
}
package org.liufei.util.jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
*
* @author 刘飞
*
*/
public class JdbcUser {
/**
* 查询
*
* @param <T>
* @param conn
* @param sql
* @param callback
* @param isCloseConnection
* @return
* @throws SQLException
*/
public static <T> T executeConnectionQueryCallback(final Connection conn,
final String sql, ResultSetCallback<T> callback, boolean isCloseConnection)
throws SQLException {
T t = new SqlCallback<T, ResultSet>() {
public T doInSQLCallback(String sql, Callback<T, ResultSet> callback)
throws SQLException {
return callback.doInSql(JdbcUtil.executeQuery(conn, sql));
}
}.doInSQLCallback(sql, callback);
if(isCloseConnection) {
JdbcUtil.release(null, null, conn, true) ;
}
return t;
}
/**
* 执行更新
* @param <T>
* @param conn
* @param isCloseConnection
* @param callback
* @return
* @throws SQLException
*/
public static <T> T executeSQLDML(final Connection conn, boolean isCloseConnection, final ConnectionCallback<T> callback) throws SQLException {
return new JdbcTransaction<T>(conn, isCloseConnection){
@Override
public T doInTransaction(Connection conn) throws SQLException {
return callback.doInSql(conn);
}}
.doInTransaction();
}
}