下面列出了怎么用 io.netty.handler.codec.http.multipart.DefaultHttpDataFactory 的API类实例代码及写法,或者点击链接到github查看源代码。
private static Map<String,String> getAttribs(FullHttpRequest request) {
String header = HttpHeaders.getHeader(request, HttpHeaders.Names.CONTENT_TYPE);
if (HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED.equalsIgnoreCase(header)) {
Map<String,String> attribs = new HashMap<>();
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), request);
List<InterfaceHttpData> data = decoder.getBodyHttpDatas();
if (data != null) {
for (InterfaceHttpData datum : data) {
if (datum.getHttpDataType() == HttpDataType.Attribute) {
Attribute attribute = (Attribute)datum;
try {
attribs.put(attribute.getName(), attribute.getString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
return attribs;
}
}
return null;
}
private Map<String, List<String>> parsePostFormParameters(FullHttpRequest request) {
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), request);
Map<String, List<String>> attributes = new HashMap<String, List<String>>();
List<InterfaceHttpData> datas = decoder.getBodyHttpDatas();
for (InterfaceHttpData data : datas) {
if (data.getHttpDataType() == HttpDataType.Attribute) {
try {
String name = data.getName();
String value = ((Attribute) data).getString();
attributes.putIfAbsent(name, new ArrayList<String>());
attributes.get(name).add(value);
} catch (IOException e) {
LOGGER.error("Error getting HTTP attribute from POST request");
}
}
}
decoder.destroy();
return attributes;
}
void copyHttpBodyData(FullHttpRequest fullHttpReq, MockHttpServletRequest servletRequest){
ByteBuf bbContent = fullHttpReq.content();
if(bbContent.hasArray()) {
servletRequest.setContent(bbContent.array());
} else {
if(fullHttpReq.getMethod().equals(HttpMethod.POST)){
HttpPostRequestDecoder decoderPostData = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), fullHttpReq);
String bbContentStr = bbContent.toString(Charset.forName(UTF_8));
servletRequest.setContent(bbContentStr.getBytes());
if( ! decoderPostData.isMultipart() ){
List<InterfaceHttpData> postDatas = decoderPostData.getBodyHttpDatas();
for (InterfaceHttpData postData : postDatas) {
if (postData.getHttpDataType() == HttpDataType.Attribute) {
Attribute attribute = (Attribute) postData;
try {
servletRequest.addParameter(attribute.getName(),attribute.getValue());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
/**
* Creates a {@link HttpPostRequestEncoder} that encodes the given {@code request} and {@code parts}.
* @param request the {@link HttpRequest} containing headers and other metadata about the request.
* @param parts the {@link InMemoryFile}s that will form the parts of the request.
* @return a {@link HttpPostRequestEncoder} that can encode the {@code request} and {@code parts}.
* @throws HttpPostRequestEncoder.ErrorDataEncoderException
* @throws IOException
*/
private HttpPostRequestEncoder createEncoder(HttpRequest request, InMemoryFile[] parts)
throws HttpPostRequestEncoder.ErrorDataEncoderException, IOException {
HttpDataFactory httpDataFactory = new DefaultHttpDataFactory(false);
HttpPostRequestEncoder encoder = new HttpPostRequestEncoder(httpDataFactory, request, true);
if (parts != null) {
for (InMemoryFile part : parts) {
FileUpload fileUpload =
new MemoryFileUpload(part.name, part.name, "application/octet-stream", "", Charset.forName("UTF-8"),
part.content.remaining());
fileUpload.setContent(Unpooled.wrappedBuffer(part.content));
encoder.addBodyHttpData(fileUpload);
}
}
return encoder;
}
private static String formatContent(FullHttpRequest request) {
String header = HttpHeaders.getHeader(request, HttpHeaders.Names.CONTENT_TYPE);
StringBuffer bf = new StringBuffer();
if (HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED.equalsIgnoreCase(header)) {
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), request);
List<InterfaceHttpData> data = decoder.getBodyHttpDatas();
if (data != null) {
for (InterfaceHttpData datum : data) {
if (datum.getHttpDataType() == HttpDataType.Attribute) {
Attribute attribute = (Attribute)datum;
try {
bf.append(attribute.getName()).append(" -> ").append(attribute.getString()).append("\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
else {
bf.append("[No Data]\n");
}
}
else if ("application/json".equalsIgnoreCase(header)) {
ByteBuf byteBuf = request.content();
byte[] bytes = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(bytes);
String s = new String(bytes, StandardCharsets.UTF_8);
bf.append(s);
}
else {
bf.append("[Unknown Data Type ").append(header).append("]");
}
return bf.toString();
}
/**
* {@inheritDoc}
*/
@Override
public synchronized @Nullable List<InterfaceHttpData> getMultipartParts() {
if (!isMultipartRequest() || !isCompleteRequestWithAllChunks())
return null;
if (multipartData == null) {
byte[] contentBytes = getRawContentBytes();
HttpVersion httpVersion = getProtocolVersion();
HttpMethod httpMethod = getMethod();
// HttpVersion and HttpMethod cannot be null because DefaultFullHttpRequest doesn't allow them to be
// null, but our getProtocolVersion() and getMethod() methods might return null (i.e. due to an
// invalid request). They shouldn't be null in practice by the time this getMultipartParts() method
// is called, but since they don't seem to be used by the Netty code we delegate to, we can just
// default them to something if null somehow slips through.
if (httpVersion == null) {
httpVersion = HttpVersion.HTTP_1_0;
}
if (httpMethod == null) {
httpMethod = HttpMethod.POST;
}
HttpRequest fullHttpRequestForMultipartDecoder =
(contentBytes == null)
? new DefaultFullHttpRequest(httpVersion, httpMethod, getUri())
: new DefaultFullHttpRequest(httpVersion, httpMethod, getUri(),
Unpooled.wrappedBuffer(contentBytes));
fullHttpRequestForMultipartDecoder.headers().add(getHeaders());
multipartData = new HttpPostMultipartRequestDecoder(
new DefaultHttpDataFactory(false), fullHttpRequestForMultipartDecoder, getContentCharset()
);
}
return multipartData.getBodyHttpDatas();
}
public URIDecoder(HttpRequest httpRequest, Map<String, String> extractedParams) {
super(httpRequest.uri());
this.paths = path().split("/");
if (httpRequest.method() == HttpMethod.PUT || httpRequest.method() == HttpMethod.POST) {
if (httpRequest instanceof HttpContent) {
this.contentType = httpRequest.headers().get(HttpHeaderNames.CONTENT_TYPE);
if (contentType != null && contentType.equals(MediaType.APPLICATION_FORM_URLENCODED)) {
this.decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), httpRequest);
} else {
this.bodyData = ((HttpContent) httpRequest).content();
}
}
}
this.pathData = extractedParams;
}
public MultipartFormUpload(Context context,
MultipartForm parts,
boolean multipart,
HttpPostRequestEncoder.EncoderMode encoderMode) throws Exception {
this.context = context;
this.pending = new InboundBuffer<>(context)
.handler(this::handleChunk)
.drainHandler(v -> run()).pause();
this.request = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1,
io.netty.handler.codec.http.HttpMethod.POST,
"/");
this.encoder = new HttpPostRequestEncoder(
new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE),
request,
multipart,
HttpConstants.DEFAULT_CHARSET,
encoderMode);
for (FormDataPart formDataPart : parts) {
if (formDataPart.isAttribute()) {
encoder.addBodyAttribute(formDataPart.name(), formDataPart.value());
} else {
encoder.addBodyFileUpload(formDataPart.name(),
formDataPart.filename(), new File(formDataPart.pathname()),
formDataPart.mediaType(), formDataPart.isText());
}
}
encoder.finalizeRequest();
}
/**
* {@inheritDoc}
* <p/>
* Prepares the request for reading by decoding all the content added via {@link #addContent(HttpContent)}.
* @throws RestServiceException if request channel is closed or if the request could not be decoded/prepared.
*/
@Override
public void prepare() throws RestServiceException {
if (!isOpen()) {
nettyMetrics.multipartRequestAlreadyClosedError.inc();
throw new RestServiceException("Request is closed", RestServiceErrorCode.RequestChannelClosed);
} else if (!readyForRead) {
// make sure data is held in memory.
HttpDataFactory httpDataFactory = new DefaultHttpDataFactory(false);
HttpPostMultipartRequestDecoder postRequestDecoder =
new HttpPostMultipartRequestDecoder(httpDataFactory, request);
try {
HttpContent httpContent = rawRequestContents.poll();
while (httpContent != null) {
try {
// if the request is also an instance of HttpContent, the HttpPostMultipartRequestDecoder does the offer
// automatically at the time of construction. We should not add it again.
if (httpContent != request) {
postRequestDecoder.offer(httpContent);
}
} finally {
ReferenceCountUtil.release(httpContent);
}
httpContent = rawRequestContents.poll();
}
for (InterfaceHttpData part : postRequestDecoder.getBodyHttpDatas()) {
processPart(part);
}
requestContents.add(LastHttpContent.EMPTY_LAST_CONTENT);
readyForRead = true;
} catch (HttpPostRequestDecoder.ErrorDataDecoderException e) {
nettyMetrics.multipartRequestDecodeError.inc();
throw new RestServiceException("There was an error decoding the request", e,
RestServiceErrorCode.MalformedRequest);
} finally {
postRequestDecoder.destroy();
}
}
}
/**
* Creates a {@link HttpPostRequestEncoder} that encodes the given {@code request} and {@code blobContent}.
* @param request the {@link HttpRequest} containing headers and other metadata about the request.
* @param blobContent the {@link ByteBuffer} that represents the content of the blob.
* @return a {@link HttpPostRequestEncoder} that can encode the {@code request} and {@code blobContent}.
* @throws HttpPostRequestEncoder.ErrorDataEncoderException
* @throws IOException
*/
private HttpPostRequestEncoder createEncoder(HttpRequest request, ByteBuffer blobContent)
throws HttpPostRequestEncoder.ErrorDataEncoderException, IOException {
HttpDataFactory httpDataFactory = new DefaultHttpDataFactory(false);
HttpPostRequestEncoder encoder = new HttpPostRequestEncoder(httpDataFactory, request, true);
FileUpload fileUpload = new MemoryFileUpload(RestUtils.MultipartPost.BLOB_PART, RestUtils.MultipartPost.BLOB_PART,
"application/octet-stream", "", Charset.forName("UTF-8"), blobContent.remaining());
fileUpload.setContent(Unpooled.wrappedBuffer(blobContent));
encoder.addBodyHttpData(fileUpload);
return encoder;
}
public static void main(String[] args) throws Exception {
String postSimple, postFile, get;
if (BASE_URL.endsWith("/")) {
postSimple = BASE_URL + "formpost";
postFile = BASE_URL + "formpostmultipart";
get = BASE_URL + "formget";
} else {
postSimple = BASE_URL + "/formpost";
postFile = BASE_URL + "/formpostmultipart";
get = BASE_URL + "/formget";
}
URI uriSimple = new URI(postSimple);
String scheme = uriSimple.getScheme() == null? "http" : uriSimple.getScheme();
String host = uriSimple.getHost() == null? "127.0.0.1" : uriSimple.getHost();
int port = uriSimple.getPort();
if (port == -1) {
if ("http".equalsIgnoreCase(scheme)) {
port = 80;
} else if ("https".equalsIgnoreCase(scheme)) {
port = 443;
}
}
if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) {
System.err.println("Only HTTP(S) is supported.");
return;
}
final boolean ssl = "https".equalsIgnoreCase(scheme);
final SslContext sslCtx;
if (ssl) {
sslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
URI uriFile = new URI(postFile);
File file = new File(FILE);
if (!file.canRead()) {
throw new FileNotFoundException(FILE);
}
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
// setup the factory: here using a mixed memory/disk based on size threshold
HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE); // Disk if MINSIZE exceed
DiskFileUpload.deleteOnExitTemporaryFile = true; // should delete file on exit (in normal exit)
DiskFileUpload.baseDirectory = null; // system temp directory
DiskAttribute.deleteOnExitTemporaryFile = true; // should delete file on exit (in normal exit)
DiskAttribute.baseDirectory = null; // system temp directory
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(new HttpUploadClientInitializer(sslCtx));
// Simple Get form: no factory used (not usable)
List<Entry<String, String>> headers = formget(b, host, port, get, uriSimple);
if (headers == null) {
factory.cleanAllHttpData();
return;
}
// Simple Post form: factory used for big attributes
List<InterfaceHttpData> bodylist = formpost(b, host, port, uriSimple, file, factory, headers);
if (bodylist == null) {
factory.cleanAllHttpData();
return;
}
// Multipart Post form: factory used
formpostmultipart(b, host, port, uriFile, factory, headers, bodylist);
} finally {
// Shut down executor threads to exit.
group.shutdownGracefully();
// Really clean all temporary files if they still exist
factory.cleanAllHttpData();
}
}
public static void main(String[] args) throws Exception {
String postSimple, postFile, get;
if (BASE_URL.endsWith("/")) {
postSimple = BASE_URL + "formpost";
postFile = BASE_URL + "formpostmultipart";
get = BASE_URL + "formget";
} else {
postSimple = BASE_URL + "/formpost";
postFile = BASE_URL + "/formpostmultipart";
get = BASE_URL + "/formget";
}
URI uriSimple = new URI(postSimple);
String scheme = uriSimple.getScheme() == null? "http" : uriSimple.getScheme();
String host = uriSimple.getHost() == null? "127.0.0.1" : uriSimple.getHost();
int port = uriSimple.getPort();
if (port == -1) {
if ("http".equalsIgnoreCase(scheme)) {
port = 80;
} else if ("https".equalsIgnoreCase(scheme)) {
port = 443;
}
}
if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) {
System.err.println("Only HTTP(S) is supported.");
return;
}
final boolean ssl = "https".equalsIgnoreCase(scheme);
final SslContext sslCtx;
if (ssl) {
sslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
URI uriFile = new URI(postFile);
File file = new File(FILE);
if (!file.canRead()) {
throw new FileNotFoundException(FILE);
}
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
// setup the factory: here using a mixed memory/disk based on size threshold
HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE); // Disk if MINSIZE exceed
DiskFileUpload.deleteOnExitTemporaryFile = true; // should delete file on exit (in normal exit)
DiskFileUpload.baseDirectory = null; // system temp directory
DiskAttribute.deleteOnExitTemporaryFile = true; // should delete file on exit (in normal exit)
DiskAttribute.baseDirectory = null; // system temp directory
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(new HttpUploadClientInitializer(sslCtx));
// Simple Get form: no factory used (not usable)
List<Entry<String, String>> headers = formget(b, host, port, get, uriSimple);
if (headers == null) {
factory.cleanAllHttpData();
return;
}
// Simple Post form: factory used for big attributes
List<InterfaceHttpData> bodylist = formpost(b, host, port, uriSimple, file, factory, headers);
if (bodylist == null) {
factory.cleanAllHttpData();
return;
}
// Multipart Post form: factory used
formpostmultipart(b, host, port, uriFile, factory, headers, bodylist);
} finally {
// Shut down executor threads to exit.
group.shutdownGracefully();
// Really clean all temporary files if they still exist
factory.cleanAllHttpData();
}
}
public static void main(String[] args) throws Exception {
String postSimple, postFile, get;
if (BASE_URL.endsWith("/")) {
postSimple = BASE_URL + "formpost";
postFile = BASE_URL + "formpostmultipart";
get = BASE_URL + "formget";
} else {
postSimple = BASE_URL + "/formpost";
postFile = BASE_URL + "/formpostmultipart";
get = BASE_URL + "/formget";
}
URI uriSimple = new URI(postSimple);
String scheme = uriSimple.getScheme() == null? "http" : uriSimple.getScheme();
String host = uriSimple.getHost() == null? "127.0.0.1" : uriSimple.getHost();
int port = uriSimple.getPort();
if (port == -1) {
if ("http".equalsIgnoreCase(scheme)) {
port = 80;
} else if ("https".equalsIgnoreCase(scheme)) {
port = 443;
}
}
if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) {
System.err.println("Only HTTP(S) is supported.");
return;
}
final boolean ssl = "https".equalsIgnoreCase(scheme);
final SslContext sslCtx;
if (ssl) {
sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE);
} else {
sslCtx = null;
}
URI uriFile = new URI(postFile);
File file = new File(FILE);
if (!file.canRead()) {
throw new FileNotFoundException(FILE);
}
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
// setup the factory: here using a mixed memory/disk based on size threshold
HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE); // Disk if MINSIZE exceed
DiskFileUpload.deleteOnExitTemporaryFile = true; // should delete file on exit (in normal exit)
DiskFileUpload.baseDirectory = null; // system temp directory
DiskAttribute.deleteOnExitTemporaryFile = true; // should delete file on exit (in normal exit)
DiskAttribute.baseDirectory = null; // system temp directory
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(new HttpUploadClientIntializer(sslCtx));
// Simple Get form: no factory used (not usable)
List<Entry<String, String>> headers = formget(b, host, port, get, uriSimple);
if (headers == null) {
factory.cleanAllHttpDatas();
return;
}
// Simple Post form: factory used for big attributes
List<InterfaceHttpData> bodylist = formpost(b, host, port, uriSimple, file, factory, headers);
if (bodylist == null) {
factory.cleanAllHttpDatas();
return;
}
// Multipart Post form: factory used
formpostmultipart(b, host, port, uriFile, factory, headers, bodylist);
} finally {
// Shut down executor threads to exit.
group.shutdownGracefully();
// Really clean all temporary files if they still exist
factory.cleanAllHttpDatas();
}
}
/**
*
* @param request
* the request to decode
* @throws NullPointerException
* for request
* @throws ErrorDataDecoderException
* if the default charset was wrong when decoding or other
* errors
*/
public HttpPostRequestDecoder(HttpRequest request) {
this(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE), request, HttpConstants.DEFAULT_CHARSET);
}
/**
*
* @param request the request to decode
* @throws NullPointerException for request
* @throws ErrorDataDecoderException if the default charset was wrong when
* decoding or other errors
*/
public HttpPostMultipartRequestDecoder(HttpRequest request) {
this(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE), request, HttpConstants.DEFAULT_CHARSET);
}