I made a encoder/decoder can be uploaded to web application server by mina 2.0
It is difficult to manipulate byte stream in mina, because I could not estimate how many bytes sent.
So, the encoder just send file bytes stream, and meta-information.
The docoder stack the stream untile output of stream is end, process it.
If you are first in mina, its examples are useful.
Encoder
public class ImageUploadRequestEncoder extends ProtocolEncoderAdapter {
private static final Log log = LogFactory.getLog(ImageUploadRequestDecoder.class);
private CharsetEncoder encoder;
public ImageUploadRequestEncoder() {
Charset charset = Charset.forName("UTF-8");
encoder = charset.newEncoder();
}
@Override
public void encode(IoSession session, Object obj, ProtocolEncoderOutput out) throws Exception {
ImageUploadRequestData data = (ImageUploadRequestData) obj;
IoBuffer buffer = IoBuffer.allocate(1, false);
buffer.setAutoExpand(true);
int StringLength = ImageUploadCodecFactory.DELIMITER.length() * 5 +
data.getId().length() + data.getCompanyID().length() + data.getFromFileName().length() +
data.getToDirName().length() + data.getPureFileName().length() + data.getPhase().name().length();
int totalLength = 4 + data.getByteStreamLength() + 4 + StringLength;
log.debug("total length : " + totalLength);
buffer.putInt(totalLength);
buffer.putInt(data.getByteStreamLength());
buffer.put(data.getByteStream());
buffer.putInt(StringLength);
buffer.putString(data.getId(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getCompanyID(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getFromFileName(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getPureFileName(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getToDirName(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getPhase().name(), encoder);
buffer.flip();
out.write(buffer);
}
}
Charset charset = Charset.forName("UTF-8");
encoder = charset.newEncoder();
}
@Override
public void encode(IoSession session, Object obj, ProtocolEncoderOutput out) throws Exception {
ImageUploadRequestData data = (ImageUploadRequestData) obj;
IoBuffer buffer = IoBuffer.allocate(1, false);
buffer.setAutoExpand(true);
int StringLength = ImageUploadCodecFactory.DELIMITER.length() * 5 +
data.getId().length() + data.getCompanyID().length() + data.getFromFileName().length() +
data.getToDirName().length() + data.getPureFileName().length() + data.getPhase().name().length();
int totalLength = 4 + data.getByteStreamLength() + 4 + StringLength;
log.debug("total length : " + totalLength);
buffer.putInt(totalLength);
buffer.putInt(data.getByteStreamLength());
buffer.put(data.getByteStream());
buffer.putInt(StringLength);
buffer.putString(data.getId(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getCompanyID(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getFromFileName(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getPureFileName(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getToDirName(), encoder);
buffer.putString(ImageUploadCodecFactory.DELIMITER, encoder);
buffer.putString(data.getPhase().name(), encoder);
buffer.flip();
out.write(buffer);
}
}
Decoder
public class ImageUploadRequestDecoder extends CumulativeProtocolDecoder {
private static final Log log = LogFactory.getLog(ImageUploadRequestDecoder.class);
private static final int MIN_READ_LENGTH = 4;
public static final int MAX_SIZE = 1024 * 1024 * 100;
private IoBuffer savedBuffer = IoBuffer.allocate(4096, true);
private int remainLength = 0;
public ImageUploadRequestDecoder() {
savedBuffer.setAutoExpand(true);
}
savedBuffer.setAutoExpand(true);
}
private boolean isFirst = false;
@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
if (isDecodable(session, in) == MessageDecoderResult.NEED_DATA) {
return false;
}
if (isFirst == false) {
int byteStreamLength = getStreamLength(in);
log.debug("byteStreamLength : " + byteStreamLength);
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
if (isDecodable(session, in) == MessageDecoderResult.NEED_DATA) {
return false;
}
if (isFirst == false) {
int byteStreamLength = getStreamLength(in);
log.debug("byteStreamLength : " + byteStreamLength);
if (byteStreamLength <= 0) {
throw new IOException("Total length of file is negative : " + byteStreamLength);
} else if (byteStreamLength >= MAX_SIZE) {
log.warn("Total length of file is so big to receive : " + byteStreamLength);
}
throw new IOException("Total length of file is negative : " + byteStreamLength);
} else if (byteStreamLength >= MAX_SIZE) {
log.warn("Total length of file is so big to receive : " + byteStreamLength);
}
log.debug("in.remaining() : " + in.remaining());
if (in.remaining() == byteStreamLength) {
savedBuffer.put(in);
savedBuffer.flip();
decodeBody(session, out);
reset();
} else { // not yet received
isFirst = true;
remainLength = byteStreamLength - in.remaining();
savedBuffer.put(in);
log.debug("not yet received");
}
return true;
}
savedBuffer.put(in);
savedBuffer.flip();
decodeBody(session, out);
reset();
} else { // not yet received
isFirst = true;
remainLength = byteStreamLength - in.remaining();
savedBuffer.put(in);
log.debug("not yet received");
}
return true;
}
int readableSize = remainLength - in.remaining();
if (readableSize == 0) { // all received.
savedBuffer.put(in);
savedBuffer.flip();
decodeBody(session, out);
reset();
} else { // more received.W
isFirst = true;
remainLength = remainLength - in.remaining();
savedBuffer.put(in);
}
if (readableSize == 0) { // all received.
savedBuffer.put(in);
savedBuffer.flip();
decodeBody(session, out);
reset();
} else { // more received.W
isFirst = true;
remainLength = remainLength - in.remaining();
savedBuffer.put(in);
}
return true;
}
}
private void reset() {
savedBuffer.clear();
remainLength = 0;
isFirst = false;
}
savedBuffer.clear();
remainLength = 0;
isFirst = false;
}
private void decodeBody(IoSession session, ProtocolDecoderOutput out) throws IOException {
PushbackInputStream stream = new PushbackInputStream(savedBuffer.asInputStream(), savedBuffer.remaining());
byte[] sizeArray = new byte[4];
if (stream.read(sizeArray, 0, 4) < 0) {
throw new IOException("wrong bytes transmitted.");
}
int size = byteArrayToInt(sizeArray);
PushbackInputStream stream = new PushbackInputStream(savedBuffer.asInputStream(), savedBuffer.remaining());
byte[] sizeArray = new byte[4];
if (stream.read(sizeArray, 0, 4) < 0) {
throw new IOException("wrong bytes transmitted.");
}
int size = byteArrayToInt(sizeArray);
byte[] byteStream = new byte[size];
int datasize = stream.read(byteStream, 0, size);
int datasize = stream.read(byteStream, 0, size);
ImageUploadRequestData data = new ImageUploadRequestData();
data.setByteStream(byteStream);
data.setByteStreamLength(datasize);
data.setByteStream(byteStream);
data.setByteStreamLength(datasize);
sizeArray = new byte[4];
datasize = stream.read(sizeArray, 0, 4);
datasize = stream.read(sizeArray, 0, 4);
int StringLength = byteArrayToInt(sizeArray);
byte[] strStream = new byte[StringLength];
datasize = stream.read(strStream, 0, StringLength);
byte[] strStream = new byte[StringLength];
datasize = stream.read(strStream, 0, StringLength);
String s = new String(strStream, "UTF-8");
StringTokenizer tokenizer = new StringTokenizer(s, ImageUploadCodecFactory.DELIMITER);
int i = 0;
while (tokenizer.hasMoreTokens()) {
// id : 1256117865031||KR12662||d:\a.txt||a.txt||e:\vuscript
String token = tokenizer.nextToken();
if (i == 0) {
data.setId(token);
;
} else if (i == 1) {
data.setCompanyID(token);
;
} else if (i == 2) {
data.setFromFileName(token);
} else if (i == 3) {
data.setPureFileName(token);
} else if (i == 4) {
data.setToDirName(token);
} else if (i == 5) {
if (token.equals("alpha")) {
data.setPhase(DEPLOYPHASE.alpha);
} else if (token.equals("real")) {
data.setPhase(DEPLOYPHASE.real);
} else if (token.equals("cache")) {
data.setPhase(DEPLOYPHASE.cache);
}
}
i++;
}
out.write(data);
//out.flush();
}
int i = 0;
while (tokenizer.hasMoreTokens()) {
// id : 1256117865031||KR12662||d:\a.txt||a.txt||e:\vuscript
String token = tokenizer.nextToken();
if (i == 0) {
data.setId(token);
;
} else if (i == 1) {
data.setCompanyID(token);
;
} else if (i == 2) {
data.setFromFileName(token);
} else if (i == 3) {
data.setPureFileName(token);
} else if (i == 4) {
data.setToDirName(token);
} else if (i == 5) {
if (token.equals("alpha")) {
data.setPhase(DEPLOYPHASE.alpha);
} else if (token.equals("real")) {
data.setPhase(DEPLOYPHASE.real);
} else if (token.equals("cache")) {
data.setPhase(DEPLOYPHASE.cache);
}
}
i++;
}
out.write(data);
//out.flush();
}
private MessageDecoderResult isDecodable(IoSession session, IoBuffer in) {
if (in.remaining() < MIN_READ_LENGTH) {
return MessageDecoderResult.NEED_DATA;
}
if (in.remaining() < MIN_READ_LENGTH) {
return MessageDecoderResult.NEED_DATA;
}
return MessageDecoderResult.OK;
}
}
protected int getStreamLength(IoBuffer iobuffer) throws Exception {
if (iobuffer.remaining() >= 4) {
return iobuffer.getInt();
}
if (iobuffer.remaining() >= 4) {
return iobuffer.getInt();
}
return Integer.MIN_VALUE;
}
}
class Message {
long bytesLength = -1;
byte[] bytes;
}
long bytesLength = -1;
byte[] bytes;
}
private static int byteArrayToInt(byte[] b) {
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (b[i] & 0x000000FF) << shift;
}
return value;
}
}
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (b[i] & 0x000000FF) << shift;
}
return value;
}
}
CodecFactory
public class ImageUploadCodecFactory implements ProtocolCodecFactory {
private ProtocolEncoder encoder;
private ProtocolDecoder decoder;
public static String DELIMITER = "||";
public ImageUploadCodecFactory() {
encoder = new ImageUploadRequestEncoder();
decoder = new ImageUploadRequestDecoder();
}
public ImageUploadCodecFactory() {
encoder = new ImageUploadRequestEncoder();
decoder = new ImageUploadRequestDecoder();
}
public ProtocolEncoder getEncoder(IoSession ioSession) throws Exception {
return encoder;
}
return encoder;
}
public ProtocolDecoder getDecoder(IoSession ioSession) throws Exception {
return decoder;
}
return decoder;
}
}
'general java' 카테고리의 다른 글
Lucene에서 한글 내용 (0) | 2009.12.24 |
---|---|
Invalid argument: sun.nio.ch.Net.setIntOption (Mina)- Solution (0) | 2009.12.23 |
Spring에서 namespace를 주기 (0) | 2009.07.22 |
DBCP] Without given validationQuery, no test. (0) | 2009.04.28 |
using merge statement in ibatis. (to 2.3.4) (0) | 2009.04.25 |