Java tutorial
/* * Copyright 2006 Wyona * * 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.wyona.org/licenses/APACHE-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.wyona.yanel.servlet.communication; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; /** * This class wraps a HttpServlerRequest and does parameter decoding. Further it handles multipart requests for file upload. */ public class HttpRequest extends HttpServletRequestWrapper { private static final Logger log = LogManager.getLogger(HttpRequest.class); public static String form_encoding = "UTF-8"; public static String container_encoding = "ISO-8859-1"; protected List items; Exception exception; /** * */ public HttpRequest(HttpServletRequest request) throws ServletException { this(request, -1); } /** * @param maxFileSize Maximum file size */ public HttpRequest(HttpServletRequest request, long maxFileSize) throws ServletException { super(request); if (isMultipartRequest()) { try { DiskFileItemFactory factory = new DiskFileItemFactory(); // INFO: Set factory constraints int maxSize = 64000; // TODO: Make configurable factory.setSizeThreshold(maxSize); //log.info("Size threshold: " + factory.getSizeThreshold() + " bytes"); File repoDir = new File(System.getProperty("java.io.tmpdir")); factory.setRepository(repoDir); //log.info("Repository directory where temporary files will be created in order to handle files beyond the size threshold: " + factory.getRepository()); // INFO: Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); if (maxFileSize >= 0) { upload.setFileSizeMax(maxFileSize); log.warn("DEBUG: Maximum file size: " + upload.getFileSizeMax() + " bytes"); } else { log.warn("No maximum file size limit set, hence unlimited!"); } // INFO: Parse the request items = upload.parseRequest(request); } catch (Exception e) { log.error(e, e); if (e.getClass().getName().indexOf("FileSizeLimitExceededException") >= 0) { //if (e instanceof org.apache.commons.fileupload.FileUploadBase$FileSizeLimitExceededException) { setMultipartRequestException(e); // TODO: Set a yanel based exception in order to hide apache commons implementation } else { setMultipartRequestException(e); } log.warn("Create empty list of items in order to prevent NullPointer exceptions!"); items = new java.util.ArrayList(); // INFO: Create empty list, such that no NullPointer is being generated } } else { //log.debug("No multipart request '" + request.getServletPath() + "', hence do nothing."); } } /** * Remember exception, such that resources and Yanel itself will be able to check and access it * @param exception Exception which has occured while parsing request */ private void setMultipartRequestException(Exception exception) { this.exception = exception; } /** * Get exception which might have happened while parsing multipart request * @return exception when there was an exception and null when there was no exception */ public Exception getMultipartRequestException() { return exception; } /** * @see javax.servlet.ServletRequestWrapper#getParameter(java.lang.String) */ public String getParameter(String name) { String value = super.getParameter(name); if (!isMultipartRequest()) { return fixEncoding(value); } Iterator iter = this.items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.getFieldName().equals(name) && item.isFormField()) { return item.getString(); // TODO: fix encoding ? } } //log.debug("No such parameter: " + name); return null; } /** * */ private String fixEncoding(String str) { if (form_encoding == null || container_encoding == null || str == null) { return str; } // Form and container encoding are equal, skip expensive value decoding if (container_encoding.equals(form_encoding)) { return str; } return decode(str); } private String decode(String str) { if (str == null) return null; try { if (container_encoding == null) container_encoding = "ISO-8859-1"; byte[] bytes = str.getBytes(container_encoding); return new String(bytes, form_encoding); } catch (UnsupportedEncodingException uee) { throw new RuntimeException("Unsupported Encoding Exception", uee); } } /** * Not really implemented yet. * @see javax.servlet.ServletRequestWrapper#getParameterMap() */ public Map getParameterMap() { if (!isMultipartRequest()) { return super.getParameterMap(); } Map map = new HashMap(); Iterator iter = this.items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.isFormField()) { map.put(item.getFieldName(), item.getString()); // TODO: fix encoding // TODO: fix multiple parameters for one name -> create array } else { // TODO } } return map; } /** * @see javax.servlet.ServletRequestWrapper#getParameterNames() */ public Enumeration getParameterNames() { if (!isMultipartRequest()) { return super.getParameterNames(); } // use a set to avoid duplicate entries HashSet set = new HashSet(); Iterator iter = this.items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.isFormField()) { // don't add file upload fields set.add(item.getFieldName()); } } return new Vector(set).elements(); } /** * @see javax.servlet.ServletRequestWrapper#getParameterValues(java.lang.String) */ public String[] getParameterValues(String name) { if (!isMultipartRequest()) { // TODO: fix encoding return super.getParameterValues(name); } ArrayList values = new ArrayList(); Iterator iter = this.items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.getFieldName().equals(name)) { values.add(item.getString()); // TODO: fix encoding ? } } return (String[]) values.toArray(new String[values.size()]); } /** * */ public boolean isMultipartRequest() { return ServletFileUpload.isMultipartContent((HttpServletRequest) this.getRequest()); } // methods for multipart requests /** * Gets the field names of all file upload fields. * @return enumeration of field names */ public Enumeration getFileNames() { if (!isMultipartRequest()) { return null; } Vector parameterNames = new Vector(); Iterator iter = this.items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (!item.isFormField()) { parameterNames.addElement(item.getFieldName()); } } return parameterNames.elements(); } /** * Gets the filename of the uploaded file on the clients computer. * @param name Input field name * @return filename */ public String getFilesystemName(String name) { if (!isMultipartRequest()) { return null; } Iterator iter = this.items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.getFieldName().equals(name)) { return fixFileName(item.getName()); } } return null; } /** * Gets the content-type of the uploaded file. * @param name Input field name * @return content-type */ public String getContentType(String name) { if (!isMultipartRequest()) { return null; } Iterator iter = this.items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.getFieldName().equals(name)) { return item.getContentType(); } } return null; } /** * Gets an input stream of the uploaded file * @param name * @return input stream * @throws IOException */ public InputStream getInputStream(String name) throws IOException { if (!isMultipartRequest()) { return null; } Iterator iter = this.items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.getFieldName().equals(name)) { return item.getInputStream(); } } return null; } protected String fixFileName(String name) { // some browsers may send the whole path: int i = name.lastIndexOf("\\"); if (i > -1) { name = name.substring(i + 1); } i = name.lastIndexOf("/"); if (i > -1) { name = name.substring(i + 1); } name = name.replaceAll(" |&|%|\\?", "_"); return name; } }