這些天由於任務需要,又研究了一下servlet,因爲以前學習過客戶端和服務器通過JSON串傳輸數據,知道可以在servlet中查詢數據庫,再將數據組裝成JSON串發送給客戶端,讓客戶端解析數據。但是這次由於涉及到客戶端上傳數據,經過servlet處理,然後存入數據庫中。這樣就不知道怎麼處理了。
在實踐過程發現,如果在客戶端將數據組裝成JSON串,在發送給servlet接收,用不了JSON的jar包(目測是需要導包的,因爲servlet是在一個java工程中寫的,JSON for java的包蠻難找的- - ),想解析就碰到問題了。
因爲比較懶^^,所以想如果客戶端發送List<?>數據(?號可以表示某個javabean),servlet能接收到,然後通過getXXX()的方法獲取數據該多好。。(感覺挺不錯的樣子)然後就開始找資料了…不知道是不是公司的網絡畢竟廢,限制很多的原因,貌似沒找到啥相關的資料,只看到有個發送List<String> 的例子,和預想中的自定義javabean還是有點差距。好在經過不懈的努力,最後終於成功了.廢話了一堆,以下開始寫流程:
1. 首先寫一個自定義的JavaBean,以UserInfo.java爲例,需要實現對象序列化的接口,因爲之後輸出流對象需要實現輸出可序列化的對象。不這樣的話,後續時發送時會報異常。
package xl.java.bean;
import java.io.Serializable;
/**
* 用戶信息
* @author xl 2012-9-20
*/
public class UserInfo implements Serializable
{
private static final long serialVersionUID = 1L;
/**
* 用戶名
*/
private String UserName;
/**
* 密碼
*/
private String Password;
/**
* 暱稱
*/
private String NickName;
/**
* QQ號
*/
private int QQNumber;
/**
* 電話號
*/
private String TelNumber;
/**
* 年齡
*/
private int Age;
public String getUserName()
{
return UserName;
}
public void setUserName(String userName)
{
UserName = userName;
}
public String getPassword()
{
return Password;
}
public void setPassword(String password)
{
Password = password;
}
public String getNickName()
{
return NickName;
}
public void setNickName(String nickName)
{
NickName = nickName;
}
public int getQQNumber()
{
return QQNumber;
}
public void setQQNumber(int qQNumber)
{
QQNumber = qQNumber;
}
public String getTelNumber()
{
return TelNumber;
}
public void setTelNumber(String telNumber)
{
TelNumber = telNumber;
}
public int getAge()
{
return Age;
}
public void setAge(int age)
{
Age = age;
}
}
1. 爲了讓客戶端引用的JavaBean包名和servlet引用的一致,請右鍵點擊UserInfo.java選擇Export----java---JAR file-----選好導出的路徑然後點finish,沒錯,我們這裏選擇將它打包,這是在LZ糾結了幾個小時後,才解決的一個問題。之前servlet端一直提示ClassNotFoundException,找不到這個bean類,由於沒仔細看Log,還一直以爲是servlet端的引用問題,後來才發現,因爲在客戶端工程中這個類的路徑是xl.java.bean.UserInfo.java,而我的servlet是在另外一個工程中寫的,相同的UserInfo.java路徑不同,在servlet中接收到的List<UserInfo>一直提示找不到UserInfo這個類,糾結的….打包完全是因爲水平不行..
(最新發現,可以不用打包,只要在WEB-INF \classes中建立文件夾xl\java\bean即可,然後將UserInfo放入bean文件夾內,通過javac UserInfo.java將它編譯成Class文件就可以了,也就是說,包名一樣就行- -)
好吧 讓我們跳過亂七八糟的第2步,進行第三步好了。。
3. 編寫客戶端模擬發送數據的類SendData.java。中間一大段的連接處理,具體解釋可參考http://blog.csdn.net/wlzf6296149/article/details/7998641 。
package xl.java.send;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import xl.java.bean.UserInfo;
/**
* 模擬發送數據
* @author xl 2012-9-20
*
*/
public class SendData
{
private static final String BASIC_URL_QUEST =
"http://192.168.1.1:8080/test/TestServlet";
public static void main(String[] args)
{
SendData senddata=new SendData();
try
{
senddata.sendDataToServer();
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
* 上傳處理結果
*
* @throws IOException
*
*/
private void sendDataToServer() throws IOException
{
//用於servlet判別請求,執行相應方法
String QuestId = "SubmitUserInfoList";
//模擬發送自定義類型的List數據
List<UserInfo> listdata = new ArrayList<UserInfo>();
for (int i = 0; i < 10; i++)
{
UserInfo li = new UserInfo();
li.setUserName("XL" + i);
li.setPassword("00000" + i);
li.setQQNumber(1234567 + i);
li.setTelNumber("15012344321" + i);
li.setNickName("xiaolang" + i);
li.setAge(18 + i);
listdata.add(li);
}
URL url = new URL(BASIC_URL_QUEST);
try
{
URLConnection con = url.openConnection();
HttpURLConnection httpUrlConnection = (HttpURLConnection) con;
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setDoInput(true);
httpUrlConnection.setRequestProperty("Content-type",
"application/x-java-serialized-object");
//不設置這個默認爲Get,服務器會沒反應,不知道什麼情況,
//糾結了很久,改成Post的話,servlet裏的
//doPost方法就有反應了
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.connect();
OutputStream outStrm = httpUrlConnection.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(outStrm);
//輸出流第一段數據是QuestId的值
oos.writeObject(QuestId);
//第二段數據是List數據
oos.writeObject(listdata); oos.flush();
oos.close();
InputStream inStrm = httpUrlConnection.getInputStream();
System.out.println("數據發送成功!");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
4. 編寫TestServlet.java類,並把編寫完成的類,放在E:\Tomcat 7.0\webapps\test\WEB-INF\classes路徑下,同時打開TestServlet.java類,把包名刪了,如下綠色字體部分,防止出現莫名其妙的錯誤- -然後通過javac編譯。
//package xl.java.servlet;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import xl.java.bean.UserInfo;
/**
* @author xl 2012-9-20
*
*/
public class TestServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
private Connection mConnection = null;
private Statement mStatement = null;
private String QuestId = "";
private static final String SUBMIT_USERINFO_LIST = "SubmitUserInfoList";// 客戶端提交到用戶信息
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
{
System.out.println("________---------doPost--------_____________");
try
{
// 鏈接數據庫
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
mConnection =
DriverManager
.getConnection("jdbc:mysql://localhost/test?user=root&password=123&useUnicode=true&characterEncoding=UTF-8");
mStatement =
mConnection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// 如果不是通過URL的Get形式上傳數據時,調用此方法,獲取上傳的list數據
getListDataByObjectInputStream(request, response);
}
catch (SQLException e)
{
e.printStackTrace();
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
* 獲取輸入流中的數據
*
* @param request
* @param response
* @throws IOException
* @throws ClassNotFoundException
*/
private void getListDataByObjectInputStream(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ClassNotFoundException
{
System.out.println("---------getListDataByObjectInputStream--------");
response.setContentType("text/html");
InputStream inStream = request.getInputStream();
ObjectInputStream objInStream = new ObjectInputStream(inStream);
QuestId = (String) objInStream.readObject();
@SuppressWarnings("unchecked")
List<UserInfo> inList = (List<UserInfo>) objInStream.readObject();
if (QuestId.equals(SUBMIT_USERINFO_LIST))
{
System.out.println("QuestId.equals(SUBMIT_ORDER_LIST)");
submitOrderList(request, response, inList);
}
objInStream.close();
System.out.println("objInStream.close()");
}
/**
* @param request
* @param response
* @param inList
*/
private void submitOrderList(HttpServletRequest request,
HttpServletResponse response, List<UserInfo> inList)
{
// 獲取數據,插入數據庫
for (UserInfo item : inList)
{
System.out.println("UserName=" + item.getUserName());
System.out.println("Password=" + item.getPassword());
System.out.println("NickName=" + item.getNickName());
System.out.println("QQNumber=" + item.getQQNumber());
System.out.println("TelNumber=" + item.getTelNumber());
System.out.println("Age=" + item.getAge() + "\n");
}
/**
* 插入數據庫代碼可以寫在這..
*/
}
}
5. 運行SendData.java文件,可看到控制檯輸出,根據前面的設定我們知道,客戶端和服務端已經建立連接,並且數據成功發送給了服務端,然後我們E:\Tomcat 7.0\logs下的stdout_20120920.log(反正目錄下最後一個文件),查看Tomcat的打印信息,如下圖
最後說明下,不知道以這種形式發送數據的效率怎麼樣,水平有限,感覺有點用,所以寫篇文章記錄下,如果大家對如何在android端通過servlet訪問MySql有疑問可以看下http://blog.csdn.net/wlzf6296149/article/details/7309971 比較早寫的一篇文章,應該能解決一些問題吧=. =