分类: Java
2008-04-25 15:38:05
9.2 applet与servlet通信示例
我们通过一个从服务器获得服务器的时间和日期例子来说明applet与servlet来通信的过程及实现方法,当然applet可以通过一定的方式获得客户机(applet运行所在的计算机)上的时间,但是考虑到一些特殊的需求我们需要获得服务器的当前时间(如网上交易的时间的确定要以服务器的当前时间为准):
为了实现applet和servlet通信,首先要有一个servlet的例子用于在服务器上运行,去获得服务器的日期和时间。其代码如下:
// 例 9-1 DaytimeServlet.java
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class DaytimeServlet extends HttpServlet{
public Date getDate(){
return new Date();
}
public void doGet (HttpServletRequest req,HttpServletResponse res)
throws ServletException,IOException
{
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println(getDate().toString());
}
public void doPost (HttpServletRequest req,HttpServletResponse res)
throws ServletException,IOException
{
doGet(req , res);
}
}
在本例中doGet和doPost分别响应从客户端发送过来的GET请求和POST请求,由于在浏览器中键入地址的请求是GET请求,我们可以在浏览器中键入来检测你的servlet是否能正常工作。
还要有一个applet,它通过HTTP方式去调用DaytimeServlet,然后将返回值显示出来。为了在请求过程中不乱码,我们定义了一个专门用于对发送HTTP请求的地址信息(URL)进行编码的类HttpMessage,它用于对请求信息进行编码。
// HttpMessage.java
package cuug;
import java.io.*;
import java.net.*;
import java.util.*;
public class HttpMessage {
URL servlet = null ;
String args = null;
public HttpMessage(URL servlet) {
this.servlet = servlet;
}
//发送不带参数的GET请求
public InputStream sendGetMessage() throws IOException{
return sendGetMessage(null);
}
//发送带参数的GET请求
public InputStream sendGetMessage(Properties args) throws IOException{
String argString = "";
if (args != null){
argString = "?" + toEncodedString(args);
}
URL url = new URL(servlet.toExternalForm()+ argString);
URLConnection con = url.openConnection();
con.setUseCaches(false);
return con.getInputStream();
}
//发送不带参数的POST请求
public InputStream sendPostMessage() throws IOException{
return sendPostMessage(null);
}
//发送带参数的POST请求
public InputStream sendPostMessage(Properties args) throws IOException{
String argString = "";
if (args != null){
argString = "?" + toEncodedString(args);
}
URLConnection con = servlet.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty ("Content-Type","application/x-www-form-urlencoded");
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(argString);
out.flush();
out.close();
return con.getInputStream();
}
//对参数进行URL编码
private String toEncodedString(Properties args){
StringBuffer buf = new StringBuffer();
Enumeration names = args.propertyNames();
while (names.hasMoreElements()){
String name = (String) names.nextElement();
String value = args.getProperty(name);
buf.append(URLEncoder.encode(name) + "=" + URLEncoder.encode(value));
if (names.hasMoreElements()) buf.append("&");
}
return buf.toString();
}
}
HttpMessage 把请求的servlet和参数进行URL编码,并向servlet发送请求(GET或POST),并作为一个客户端接收servelt发送过来的响应,并将接收到的数据流作为返回值(类型InputStream)。
applet的代码如下:
//DaytimeApplet.java
import java.applet.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.net.URL;
import cuug.HttpMessage;
public class DaytimeApplet extends Applet{
TextField httpText;
Button refresh;
public void init(){
setLayout(new BorderLayout());
Panel west = new Panel();
west.setLayout(new GridLayout(1,1));
west.add(new Label("HTTP text:",Label.RIGHT));
add("West",west);
Panel center = new Panel();
center.setLayout(new GridLayout(1,1));
httpText = new TextField();
httpText.setEditable(false);
center.add(httpText);
add("Center",center);
Panel south = new Panel();
refresh = new Button("Refresh");
south.add(refresh);
add("South",south);
}
public void start(){
refresh();
}
private void refresh(){
httpText.setText(getDateUsingHttpText());
}
private String getDateUsingHttpText(){
try{
URL url = new URL(getCodeBase(),"/servlet/DaytimeServlet");
HttpMessage msg = new HttpMessage(url);
InputStream in = msg.sendGetMessage();
DataInputStream result =
new DataInputStream(new BufferedInputStream(in));
String date = result.readLine();
in.close();
return date;
}
catch (Exception e){
e.printStackTrace();
return null;
}
}
public boolean handleEvent (Event event) {
switch (event.id){
case Event.ACTION_EVENT:
if (event.target == refresh ){
refresh();
return true;
}
}
return false;
}
}
BorderLayout和GridLayout分别是applet中了两种不同的布局方式,在本例中将两种方式结合起来使用。
一个applet要通过HTTP方式访问servlet,它必须和一个浏览器一样建立一个和servlet的连接。在本例中,每次“refresh”按钮被按下时,调用getDateUsingHttpText(),将返回值显示在文本框中。getDateUsingHttpText()实现了向servlet建立连接并取回返回值的工作:首先,她创建了一个URL对象指向server上运行的servlet,服务器的名称和端口号,通过applet的getCodeBase ()来获得,保证能和applet源代码所在的服务器保持一致;然后,创建一个HttpMessage对象来向那个URL进行通信。HttpMessage对象处理了一切繁杂的工作(建连接,传参数等工作),将servlet的响应作为一个InputStream型的变量返回。