最近兩個項目之間的需要做數據同步,要求是A項目的數據以及圖片文件要同步到B項目,首先兩個項目都是獨立的採集錄入信息的項目,數據庫數據同步不說了,還有一些圖片等文件也得需要同步, 首先想到的是B項目調用A項目的圖片路徑,因爲兩個項目的圖片文件路徑有很多種生成情況,兩項目都在運行中,這種圖片路徑方法就排除了。 後面就想到了兩種解決方法:
1 socket 方法 就是在B項目添加偵聽 B項目啓動時候start, 在A項目中用Client 。
2 在A項目中通過HttpURLConnection模擬post表單提交到B項目對應方法。(個人感覺這種比較好)
HttpURLConnection:
package test.httpUp;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
public class HttpPostUtil {
URL url;
HttpURLConnection conn;
String boundary = "--------http";
Map<String, String> textParams = new HashMap<String, String>();
Map<String, File> fileparams = new HashMap<String, File>();
DataOutputStream ds;
public HttpPostUtil(String url) throws Exception {
this.url = new URL(url);
}
//重新設置要請求的服務器地址,即上傳文件的地址。
public void setUrl(String url) throws Exception {
this.url = new URL(url);
}
//增加一個普通字符串數據到form表單數據中
public void addTextParameter(String name, String value) {
textParams.put(name, value);
}
//增加一個文件到form表單數據中
public void addFileParameter(String name, File value) {
fileparams.put(name, value);
}
// 清空所有已添加的form表單數據
public void clearAllParameters() {
textParams.clear();
fileparams.clear();
}
// 發送數據到服務器,返回一個字節包含服務器的返回結果的數組
public byte[] send() throws Exception {
initConnection();
try {
conn.connect();
} catch (SocketTimeoutException e) {
// something
throw new RuntimeException();
}
ds = new DataOutputStream(conn.getOutputStream());
writeFileParams();
writeStringParams();
paramsEnd();
InputStream in = conn.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
conn.disconnect();
return out.toByteArray();
}
//文件上傳的connection的一些必須設置
private void initConnection() throws Exception {
conn = (HttpURLConnection) this.url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(10000); //連接超時爲10秒
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
}
//普通字符串數據
private void writeStringParams() throws Exception {
Set<String> keySet = textParams.keySet();
for (Iterator<String> it = keySet.iterator(); it.hasNext();) {
String name = it.next();
String value = textParams.get(name);
ds.writeBytes("--" + boundary + "\r\n");
ds.writeBytes("Content-Disposition: form-data; name=\"" + name
+ "\"\r\n");
ds.writeBytes("\r\n");
ds.writeBytes(encode(value) + "\r\n");
}
}
//文件數據
private void writeFileParams() throws Exception {
Set<String> keySet = fileparams.keySet();
for (Iterator<String> it = keySet.iterator(); it.hasNext();) {
String name = it.next();
File value = fileparams.get(name);
ds.writeBytes("--" + boundary + "\r\n");
ds.writeBytes("Content-Disposition: form-data; name=\"" + name
+ "\"; filename=\"" + encode(value.getName()) + "\"\r\n");
ds.writeBytes("Content-Type: " + getContentType(value) + "\r\n");
ds.writeBytes("\r\n");
ds.write(getBytes(value));
ds.writeBytes("\r\n");
}
}
//獲取文件的上傳類型,圖片格式爲image/png,image/jpg等。非圖片爲application/octet-stream
private String getContentType(File f) throws Exception {
// return "application/octet-stream"; // 此行不再細分是否爲圖片,全部作爲application/octet-stream 類型
ImageInputStream imagein = ImageIO.createImageInputStream(f);
if (imagein == null) {
return "application/octet-stream";
}
Iterator<ImageReader> it = ImageIO.getImageReaders(imagein);
if (!it.hasNext()) {
imagein.close();
return "application/octet-stream";
}
imagein.close();
return "image/" + it.next().getFormatName().toLowerCase();//將FormatName返回的值轉換成小寫,默認爲大寫
}
//把文件轉換成字節數組
private byte[] getBytes(File f) throws Exception {
FileInputStream in = new FileInputStream(f);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while ((n = in.read(b)) != -1) {
out.write(b, 0, n);
}
in.close();
return out.toByteArray();
}
//添加結尾數據
private void paramsEnd() throws Exception {
ds.writeBytes("--" + boundary + "--" + "\r\n");
ds.writeBytes("\r\n");
}
// 對包含中文的字符串進行轉碼,此爲UTF-8。服務器那邊要進行一次解碼
private String encode(String value) throws Exception{
return URLEncoder.encode(value, "UTF-8");
}
public static void main(String[] args) throws Exception {
HttpPostUtil u = new HttpPostUtil("http://xxxxxx.action");
u.addTextParameter("path", "qs/");
u.addTextParameter("fileName", "111.jpg");
u.addFileParameter("picFile", new File(
"D://272.jpg"));
u.addTextParameter("text", "utf-8");
byte[] b = u.send();
String result = new String(b);
System.out.println(result);
}
}
=====================socket client
package test.socket;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
/**
* 文件發送客戶端主程序
* @author admin_Hzw
*
*/
public class BxClient {
/**
* 程序main方法
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
int length = 0;
double sumL = 0 ;
byte[] sendBytes = null;
Socket socket = null;
DataOutputStream dos = null;
FileInputStream fis = null;
boolean bool = false;
try {
File file = new File("d:/272.jpg"); //要傳輸的文件路徑
long l = file.length();
socket = new Socket();
socket.connect(new InetSocketAddress("192.168.1.110", 8877));
dos = new DataOutputStream(socket.getOutputStream());
fis = new FileInputStream(file);
sendBytes = new byte[1024];
while ((length = fis.read(sendBytes, 0, sendBytes.length)) > 0) {
sumL += length;
System.out.println("已傳輸:"+((sumL/l)*100)+"%");
dos.write(sendBytes, 0, length);
dos.flush();
}
//雖然數據類型不同,但JAVA會自動轉換成相同數據類型後在做比較
if(sumL==l){
bool = true;
}
}catch (Exception e) {
System.out.println("客戶端文件傳輸異常");
bool = false;
e.printStackTrace();
} finally{
if (dos != null)
dos.close();
if (fis != null)
fis.close();
if (socket != null)
socket.close();
}
System.out.println(bool?"成功":"失敗");
}
}
socket server
web.xml
<listener>
<listener-class>XXX.web.listener.SocketServiceLoader</listener-class>
</listener>
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SocketServiceLoader implements ServletContextListener { //socket server 線程
private SocketThread socketThread;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
if(null!=socketThread && !socketThread.isInterrupted())
{
socketThread.closeSocketServer();
socketThread.interrupt();
}
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
if(null==socketThread)
{
//新建線程類
socketThread=new SocketThread(null);
//啓動線程
socketThread.start();
}
} }
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketThread extends Thread{
private ServerSocket serverSocket = null;
public SocketThread(ServerSocket serverScoket){
try {
if(null == serverSocket){
this.serverSocket = new ServerSocket(8877);
System.out.println("socket start");
}
} catch (Exception e) {
System.out.println("SocketThread創建socket服務出錯");
e.printStackTrace();
}
}
public void run(){
while(!this.isInterrupted()){
try {
Socket socket = serverSocket.accept();
if(null != socket && !socket.isClosed()){
//處理接受的數據
new SocketOperate(socket).start();
}
socket.setSoTimeout(30000);
}catch (Exception e) {
e.printStackTrace();
}
}
}
public void closeSocketServer(){
try {
if(null!=serverSocket && !serverSocket.isClosed())
{
serverSocket.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Random;
public class SocketOperate extends Thread{
private Socket socket;
public SocketOperate(Socket socket) {
this.socket=socket;
}
@SuppressWarnings("unused")
public void run()
{
try{
System.out.println("開始監聽...");
/*
* 如果沒有訪問它會自動等待
*/
System.out.println("有鏈接");
receiveFile(socket);
} catch (Exception e) {
System.out.println("服務器異常");
e.printStackTrace();
}
}
/*public void run() {
}*/
/**
* 接收文件方法
* @param socket
* @throws IOException
*/
public static void receiveFile(Socket socket) throws IOException {
byte[] inputByte = null;
int length = 0;
DataInputStream dis = null;
FileOutputStream fos = null;
String filePath = "D:/temp/"+new Random().nextInt(10000)+".jpg";
try {
try {
dis = new DataInputStream(socket.getInputStream());
File f = new File("D:/temp");
if(!f.exists()){
f.mkdir();
}
/*
* 文件存儲位置
*/
fos = new FileOutputStream(new File(filePath));
inputByte = new byte[1024];
System.out.println("開始接收數據...");
while ((length = dis.read(inputByte, 0, inputByte.length)) > 0) {
fos.write(inputByte, 0, length);
fos.flush();
}
System.out.println("完成接收:"+filePath);
} finally {
if (fos != null)
fos.close();
if (dis != null)
dis.close();
if (socket != null)
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}