关于servlet服务端接收客户端发送的List数据的问题

   这些天由于任务需要,又研究了一下servlet,因为以前学习过客户端和服务器通过JSON串传输数据,知道可以在servlet中查询数据库,再将数据组装成JSON串发送给客户端,让客户端解析数据。但是这次由于涉及到客户端上传数据,经过servlet处理,然后存入数据库中。这样就不知道怎么处理了。

   在实践过程发现,如果在客户端将数据组装成JSON串,在发送给servlet接收,用不了JSONjar(目测是需要导包的,因为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 比较早写的一篇文章,应该能解决一些问题吧=. =








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章