⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppg.java

📁 WAP Push实现源码!
💻 JAVA
字号:
package push;import javax.servlet.*;import javax.servlet.http.*;import java.net.*;import java.io.*;import java.util.StringTokenizer;/** * <code>PPG</code> class implements some push proxy gateway (PPG) functionality for  * the purposes of this example only. This simple PPG is targeted to be used in  * conjunction with WAP toolkit, and IPv4 type client addressing.  * */public final class PPG extends HttpServlet {    /* xml version */    private final static String XML_VERSION = "<?xml version=\"1.0\"?>";     /* Push Access Protocol (PAP) document type */    private final static String PAP_DOCTYPE = 	"<!DOCTYPE pap PUBLIC \"-//WAPFORUM//DTD PAP 1.0//EN\" \"http://www.wapforum.org/DTD/pap_1.0.dtd\" >";    /* content type of the push request multipart body */    private final static String CONTENT_TYPE = 	"multipart/related; boundary=multipart-boundary; type=\"application/xml\"";    /* WAP Push connection less service (client side). The registered port number. */    private static final int connectionlessPushPort = 2948;     private static int transactionId = 0;    /**     * <code>doPost</code>     *     * @param request a <code>HttpServletRequest</code> value     * @param response a <code>HttpServletResponse</code> value     * @exception ServletException if an error occurs     * @exception IOException if an error occurs     */    public void doPost(HttpServletRequest request, HttpServletResponse response) 	throws ServletException, IOException {	String clientAddress = null;	String pushId = null;	int resultCode = 1001; // accepted for processing	try {	    // first, check the content type which should be "multipart/related"	    String contentType = request.getHeader("content-type");	    StringTokenizer st = new StringTokenizer(contentType, ";");	    String token = st.nextToken();	    String boundary = null;	    if(!token.equalsIgnoreCase("multipart/related")) throw new Exception("wrong content type");	    // finds the boundary string	    while(st.hasMoreTokens()) {		token = st.nextToken().trim();		if(token.startsWith("boundary=")) {   		    boundary = token.substring(9);		    break;		}	    }	    if(boundary == null) throw new Exception("no multipart boundary"); 	    boundary = "--" + boundary;	    String endBoundary = boundary + "--";	    StringBuffer messageContent = new StringBuffer();	    BufferedReader in = request.getReader();	    String line;	    int i=0;	    boolean startContent = false;	 System.out.println("boundary=" + boundary);	    // extract message content part	    while((line = in.readLine()) != null) {		if(line.equals(boundary)) 		    ++i;		else if(line.equals(endBoundary))		    break;		if(i == 1) { // PAP control entity		    int j = line.indexOf("address-value=");		    if(j >= 0) {			clientAddress = line.substring(j+15, line.indexOf('"', j+17));		    }		    j = line.indexOf("push-id=");		    if(j >= 0) {			pushId = line.substring(j+9, line.indexOf('"', j+11));		    }		}		else if(i == 2) { // PAP content entity		    if(startContent) 			messageContent.append(line);		    else if(line.trim().equals("")) // end of headers			startContent = true;		    else if(line.toLowerCase().startsWith("content-type:")) 			contentType = line.substring(13).trim();		}	    }	    if((i = clientAddress.indexOf("/TYPE=IPv4")) == -1) {		resultCode = 2002; // address error		throw new Exception("This PPG can handle only IPv4 type addresses");	    }	    clientAddress = clientAddress.substring(clientAddress.indexOf("WAPPUSH=")+8, i);	    if(clientAddress == null) { 		resultCode = 2002; // address error		throw new Exception("Client address is not known");	    }	    System.out.println("clientAddress: " + clientAddress);	    System.out.println("pushId: " + pushId);	    System.out.println("message content: " + messageContent);	    	    unitPushRequest(clientAddress, messageContent.toString().trim(), contentType);	}	catch (Exception e) {	    System.err.println(e);	    if(resultCode < 2000) resultCode = 2000; // bad message	}	// start writing the result	response.setStatus(202); // accepted	response.setContentType("application/xml");	PrintWriter out = response.getWriter();	out.println(XML_VERSION);	out.println(PAP_DOCTYPE);	out.println("<pap product-name=\"MobileZoo PPG\">");	out.println("  <push-response push-id=\"" + pushId  + "\">");	out.println("    <response result");	out.println("       code=\"" + resultCode + "\"");	out.println("       desc=\"" + resultCodeDesc(resultCode) + "\">");	out.println("    </response-result>");	out.println("  </push-response>");	out.println("</pap>");    }    /**     * Returns description of a PAP result response code     *     * @param code an <code>int</code> value     * @return a <code>String</code> value     */    private static String resultCodeDesc(int code) {	switch(code) {	case 1001:	    return "Accepted for Processing";	case 2000:	    return "Bad Request";	case 2002:	    return "Address Error";	}	return "Unknown result code";    }    /**     * <code>unitPushRequest</code> generates a connectionless mode Push request     *     * @param clientAddress a <code>String</code> value     * @param messageContent a <code>String</code> value     * @param contentType a <code>String</code> value     * @exception Exception if an error occurs     */    private void unitPushRequest(String clientAddress, String messageContent, 				 String contentType) 	throws Exception {	ByteArrayOutputStream content = new ByteArrayOutputStream();	contentType = encodeContent(messageContent, content, contentType);	int wspContentType = encodeContentType(contentType);	transactionId %= 127;	byte[] wspPdu = wspPduPUSH(transactionId++, wspContentType, content.toByteArray());	sendData(clientAddress, connectionlessPushPort, wspPdu, wspPdu.length);    }    /**     * A simplified "WBXML encoder".     * It handles only SI content type, and only href attribute within      * SI content (others ignored).     * No well-formedness nor validity checks are performed during the encoding.      *     * @param messageContent a <code>String</code> value     * @param content a <code>ByteArrayOutputStream</code> value     * @param contentType a <code>String</code> value     * @return a <code>String</code> value     */    private static String encodeContent(String messageContent, ByteArrayOutputStream content, 					String contentType) throws Exception {	if(contentType.startsWith("text/vnd.wap.si")) {	    int i = messageContent.indexOf("href=\"http://");	    if(i > 0) {		try {		    final byte[] bytes1 = { 0x0, 0x5, 0x4, 0x0, 0x45, (byte)0xc6, 0xc, 0x3 }; 		    final byte[] bytes2 = { 0x0, 0x7, 0x1, 0x3 };		    final byte[] bytes3 = { 0x0, 0x1, 0x1};		    String href = messageContent.substring(i+13, messageContent.indexOf("\"", i+14));		    String message = messageContent.substring(messageContent.indexOf(">", i+15)+1,					  messageContent.indexOf("</indication>", i+16));		    content.write(bytes1);		    content.write(href.getBytes());		    content.write(bytes2);		    content.write(message.trim().getBytes());		    content.write(bytes3);		    return "application/vnd.wap.sic";		}		catch (Exception e) {		    content.reset();		}	    }	}	content.write(messageContent.getBytes());	return contentType;    }    /**     * <code>encodeContentType</code> encodes mime type (cf. WSP specification WAP-203-WSP 4-May-2000)     *     * @param contentType a <code>String</code> value     * @return an <code>int</code> value     */    private static int encodeContentType(String contentType) throws Exception {	contentType = contentType.toLowerCase();	if(contentType.startsWith("text/vnd.wap.wml")) 	    return 0x88; 	else if(contentType.startsWith("text/vnd.wap.si"))	    return 0xAD;	else if(contentType.startsWith("text/vnd.wap.sl"))	    return 0xAF;	else if(contentType.startsWith("application/vnd.wap.wmlc")) 	    return 0x94; 	else if(contentType.startsWith("application/vnd.wap.sic"))	    return 0xAE;	else if(contentType.startsWith("applicavtion/vnd.wap.slc"))	    return 0xB0;	throw new Exception("unsupported content type:" + contentType);    }    // WSP PDU Type Assigments     // Table 34 (page 94) in WSP specification WAP-203-WSP 4-May-2000    private static final int WSP_PUSH = 0x06;    /**     * Generate WSP PUSH PDU (note: only partial functionality provided)     *     * @param tid an <code>int</code> value     * @param contentType an <code>int</code> value     * @param content a <code>byte[]</code> value     * @return a <code>byte[]</code> value     * @exception Exception if an error occurs     */    private static byte[] wspPduPUSH(int tid, int contentType, byte[] content) throws Exception {	ByteArrayOutputStream data = new ByteArrayOutputStream();	data.write(tid);	data.write(WSP_PUSH); 	data.write(1); // contenttype size + headers size	data.write(contentType);	data.write(content);	return data.toByteArray();    }        /**     * <code>sendData</code> sends data to given address and port using UDP datagram socket     *     * @param addressStr a <code>String</code> value     * @param port an <code>int</code> value     * @param data a <code>byte[]</code> value     * @param dataSize an <code>int</code> value     * @return an <code>int</code> value     * @exception Exception if an error occurs     */    private static int sendData(String addressStr, int port, final byte[] data, int dataSize) 	throws Exception {	if(dataSize <= 0) return 0;	InetAddress addr = InetAddress.getByName(addressStr);	System.out.println("sendData addr = " + addr.getHostAddress() + "; port = " + port + 			   "; data_size = " + dataSize);	DatagramSocket s =  new DatagramSocket();	// s.setSoTimeout(1000);	DatagramPacket packet = new DatagramPacket(data, dataSize, addr, port);	s.send(packet);	int nBytes = packet.getLength();	if(dataSize != nBytes) 	    System.err.println("warning: not all bytes of a datagram are sent to socket!?");	s.close();	return nBytes;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -