📄 multipartfilter.java
字号:
// ========================================================================// Copyright 1996-2005 Mort Bay Consulting Pty. Ltd.// ------------------------------------------------------------------------// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// ========================================================================package org.mortbay.servlet;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.Collections;import java.util.Enumeration;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.StringTokenizer;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import org.mortbay.util.MultiMap;import org.mortbay.util.StringUtil;import org.mortbay.util.TypeUtil;/* ------------------------------------------------------------ *//** * Multipart Form Data Filter. * <p> * This class decodes the multipart/form-data stream sent by a HTML form that uses a file input * item. Any files sent are stored to a tempary file and a File object added to the request * as an attribute. All other values are made available via the normal getParameter API and * the setCharacterEncoding mechanism is respected when converting bytes to Strings. * * If the init paramter "delete" is set to "true", any files created will be deleted when the * current request returns. * * @author Greg Wilkins * @author Jim Crossley */public class MultiPartFilter implements Filter{ private final static String FILES ="org.mortbay.servlet.MultiPartFilter.files"; private File tempdir; private boolean _deleteFiles; private ServletContext _context; private int _fileOutputBuffer = 0; /* ------------------------------------------------------------------------------- */ /** * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) */ public void init(FilterConfig filterConfig) throws ServletException { tempdir=(File)filterConfig.getServletContext().getAttribute("javax.servlet.context.tempdir"); _deleteFiles="true".equals(filterConfig.getInitParameter("deleteFiles")); String fileOutputBuffer = filterConfig.getInitParameter("fileOutputBuffer"); if(fileOutputBuffer!=null) _fileOutputBuffer = Integer.parseInt(fileOutputBuffer); _context=filterConfig.getServletContext(); } /* ------------------------------------------------------------------------------- */ /** * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, * javax.servlet.ServletResponse, javax.servlet.FilterChain) */ public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException, ServletException { HttpServletRequest srequest=(HttpServletRequest)request; if(srequest.getContentType()==null||!srequest.getContentType().startsWith("multipart/form-data")) { chain.doFilter(request,response); return; } BufferedInputStream in = new BufferedInputStream(request.getInputStream()); String content_type=srequest.getContentType(); // TODO - handle encodings String boundary="--"+value(content_type.substring(content_type.indexOf("boundary="))); byte[] byteBoundary=(boundary+"--").getBytes(StringUtil.__ISO_8859_1); // cross-container MultiMap params = new MultiMap(request.getParameterMap()); // jetty-specific but more efficient /*MultiMap params = new MultiMap(); if(srequest instanceof org.mortbay.jetty.Request) { org.mortbay.jetty.Request req = ((org.mortbay.jetty.Request)srequest); req.getUri().decodeQueryTo(params, req.getQueryEncoding()); }*/ try { // Get first boundary byte[] bytes=TypeUtil.readLine(in); String line=bytes==null?null:new String(bytes,"UTF-8"); if(line==null || !line.equals(boundary)) { throw new IOException("Missing initial multi part boundary"); } // Read each part boolean lastPart=false; String content_disposition=null; while(!lastPart) { while(true) { bytes=TypeUtil.readLine(in); // If blank line, end of part headers if(bytes==null || bytes.length==0) break; line=new String(bytes,"UTF-8"); // place part header key and value in map int c=line.indexOf(':',0); if(c>0) { String key=line.substring(0,c).trim().toLowerCase(); String value=line.substring(c+1,line.length()).trim(); if(key.equals("content-disposition")) content_disposition=value; } } // Extract content-disposition boolean form_data=false; if(content_disposition==null) { throw new IOException("Missing content-disposition"); } StringTokenizer tok=new StringTokenizer(content_disposition,";"); String name=null; String filename=null; while(tok.hasMoreTokens()) { String t=tok.nextToken().trim(); String tl=t.toLowerCase(); if(t.startsWith("form-data")) form_data=true; else if(tl.startsWith("name=")) name=value(t); else if(tl.startsWith("filename=")) filename=value(t); } // Check disposition if(!form_data) { continue; } if(name==null||name.length()==0) { continue; } OutputStream out=null; File file=null; try { if (filename!=null && filename.length()>0) { file = File.createTempFile("MultiPart", "", tempdir); out = new FileOutputStream(file); if(_fileOutputBuffer>0) out = new BufferedOutputStream(out, _fileOutputBuffer); request.setAttribute(name,file); params.put(name, filename); if (_deleteFiles) { file.deleteOnExit(); ArrayList files = (ArrayList)request.getAttribute(FILES); if (files==null) { files=new ArrayList(); request.setAttribute(FILES,files); } files.add(file); } } else out=new ByteArrayOutputStream(); int state=-2; int c; boolean cr=false; boolean lf=false; // loop for all lines` while(true) { int b=0; while((c=(state!=-2)?state:in.read())!=-1) { state=-2; // look for CR and/or LF if(c==13||c==10) { if(c==13) state=in.read(); break; } // look for boundary
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -