最近做的一个java 与flash通讯的项目,由于项目框架的需要,要把AMF 格式解析代码抽出.代码有点乱,现丑了.
package com.musicxx.web.servlet;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import juan.framework.action.Action4J;
import juan.framework.arguments.ArgumentsFactory;
import juan.framework.arguments.IArguments;
import juan.view.context.IContext;
import juan.view.context.impl.InnerContextImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.ActionMessage;
import flex.messaging.io.amf.Amf0Input;
import flex.messaging.io.amf.Amf0Output;
import flex.messaging.io.amf.Java15Amf0Output;
import flex.messaging.io.amf.MessageBody;
import flex.messaging.io.amf.MessageHeader;
/**
* Description : AMF通讯方式
*
* @author: JayChou
* @version 1.0
* @Created on Aug 18, 2008 5:57:21 PM
*/
public class AmfServlet extends HttpServlet {
private static Log logger = LogFactory.getLog(AmfServlet.class);
/**
* flash-->java
* @return
* @throws IOException
* @throws ClassNotFoundException
* @throws Exception
*/
private ActionMessage in(InputStream is) throws IOException, ClassNotFoundException {
ActionMessage inMs = new ActionMessage();
Amf0Input amfIn = new Amf0Input(SerializationContext.getSerializationContext());
amfIn.setInputStream(is);
int version = amfIn.readUnsignedShort();
inMs.setVersion(version);
int headerCount = amfIn.readUnsignedShort();
for (int i = 0; i < headerCount; ++i) {
MessageHeader header = new MessageHeader();
inMs.addHeader(header);
header.setName(amfIn.readUTF());
header.setMustUnderstand(amfIn.readBoolean());
amfIn.readInt();
amfIn.reset();
header.setData(amfIn.readObject());
}
int bodyCount = amfIn.readUnsignedShort();
for (int i = 0; i < bodyCount; ++i) {
MessageBody body = new MessageBody();
inMs.addBody(body);
body.setTargetURI(amfIn.readUTF());
body.setResponseURI(amfIn.readUTF());
amfIn.readInt();
amfIn.reset();
body.setData(amfIn.readObject());
}
amfIn.close();
amfIn=null;
return inMs;
}
/**
* java --> flash
* @param o
* @throws IOException
* @throws Exception
*/
private void out(ActionMessage outMs,HttpServletRequest request, HttpServletResponse response) throws IOException {
ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
Amf0Output amfOut = new Java15Amf0Output(SerializationContext.getSerializationContext());
int version = outMs.getVersion();
amfOut.setAvmPlus(version > 0);
amfOut.setOutputStream(outBuffer);
amfOut.writeShort(version);
int headerCount = outMs.getHeaderCount();
amfOut.writeShort(headerCount);
for (int i = 0; i < headerCount; ++i) {
MessageHeader header = outMs.getHeader(i);
amfOut.writeUTF(header.getName());
amfOut.writeBoolean(header.getMustUnderstand());
amfOut.writeInt(-1);
amfOut.reset();
amfOut.writeObject(header.getData());
}
int bodyCount = outMs.getBodyCount();
amfOut.writeShort(bodyCount);
for (int i = 0; i < bodyCount; ++i) {
MessageBody body = outMs.getBody(i);
if (body.getTargetURI() == null)
amfOut.writeUTF("null");
else
amfOut.writeUTF(body.getTargetURI());
if (body.getResponseURI() == null)
amfOut.writeUTF("null");
else
amfOut.writeUTF(body.getResponseURI());
amfOut.writeInt(-1);
amfOut.reset();
amfOut.writeObject(body.getData());
}
response.setContentType(request.getContentType());
response.setContentLength(outBuffer.size());
outBuffer.writeTo(response.getOutputStream());
response.flushBuffer();
amfOut.flush();
amfOut.close();
amfOut=null;
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Action4J action = new Action4J();
IContext icontext = new InnerContextImpl();
IArguments args = ArgumentsFactory.getArguments();
action.setContext(icontext);
action.setRequest(req);
action.setResponse(resp);
action.setServletConfig(getServletConfig());
action.setServletContext(getServletContext());
ActionMessage outMs = new ActionMessage();
ActionMessage inMs = null;
try {
inMs = in(req.getInputStream());
outMs.setVersion(inMs.getVersion());
for(int i=0;i<inMs.getBodyCount();i++){
MessageBody body = inMs.getBody(i);
String method = body.getReplyMethod().split("\\.")[1];
Object[] o = (Object[]) body.getData();
Object[] arr = (Object[]) o;
for (int j = 0; j < arr.length; j++){
args.add("index" + (j+1), arr[j]);
}
action.execute("/"+method, args);
Object result=action.getContext().get("result");
MessageBody responseBody = new MessageBody();
responseBody.setData(result);
responseBody.setTargetURI( body.getResponseURI()+ "/onResult");
outMs.addBody(responseBody);
args.clear();
}
} catch (Exception e) {
logger.error(e.getMessage());
MessageBody responseBody = new MessageBody();
responseBody.setData(new Object[]{100});
responseBody.setTargetURI( inMs.getBody(0).getResponseURI()+ "/onResult");
outMs.addBody(responseBody);
} finally {
args.clear();
out(outMs,req,resp);
}
}
}