Java tutorial
/* * Copyright (C) 2014 Integration Architects * * 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 be.integrationarchitects.web.dragdrop.servlet.impl; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.URLDecoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import org.apache.commons.codec.binary.Hex; import be.integrationarchitects.web.dragdrop.servlet.DragDropConstants; import be.integrationarchitects.web.dragdrop.servlet.DragDropContext; import be.integrationarchitects.web.dragdrop.servlet.DragDropMimeFile; import be.integrationarchitects.web.dragdrop.servlet.DragDropMimeHandlerRequest; import be.integrationarchitects.web.dragdrop.servlet.Logger; public class DragDropServletUtils { protected File folder; protected boolean checkHash = true; protected Logger logger; public DragDropServletUtils(File folder, boolean checkHash, Logger logger) { this.folder = folder; this.checkHash = checkHash; this.logger = logger; } protected Map<String, Map<String, String>> getHeadersParams(HttpServletRequest request, boolean readFormDataPost) throws IOException { Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>(); Map<String, String> reqparams = new HashMap<String, String>(); Map<String, String> reqheaders = new HashMap<String, String>(); map.put("params", reqparams); map.put("headers", reqheaders); if (readFormDataPost) { // servlet api <3.0 will return null values for formdata post, from 3.0 servlet api use request.getParts() //using 2.0 api and parsing ourselves parts // in the javascript we use jquery object.serialize() to submit the form with ajax //this format is used: /**FORM DATA will be: * * ------WebKitFormBoundary3UAOvASvkiQACgBY Content-Disposition: form-data; name="formsubmitdata" dropId=1406409768959&md5_1=5b9f16527d8d27f541cbb3fabf432eb6&filename_1=17.csv&doctype_1= ------WebKitFormBoundary3UAOvASvkiQACgBY-- */ InputStream in = request.getInputStream(); ByteArrayOutputStream bout = new ByteArrayOutputStream(); byte[] buff = new byte[10000]; int bytesread = 0; BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = null; //while((line=br.readLine()).length()>0){ while ((bytesread = in.read(buff)) > 0) { bout.write(buff, 0, bytesread); //System.out.println("FORMDATA:"+new String(buff,0,bytesread)); // System.out.println("FORMDATA:"+line); //bout.write(buff,0,bytesread); // if(!line.startsWith("Content-Disposition")){ // //bout.write(buff,0,bytesread); // bout.write(line.getBytes()); // } } String formparamsStr = new String(bout.toByteArray()); logger.logTrace("FORMDATA:" + formparamsStr); int jj = formparamsStr.indexOf("name=\"formsubmitdata\""); formparamsStr = formparamsStr.substring(jj + 21); jj = formparamsStr.indexOf("---"); formparamsStr = formparamsStr.substring(0, jj); String[] formParamPairs = formparamsStr.split("&"); if (formParamPairs != null) { for (String pair : formParamPairs) { int ii = pair.indexOf("="); if (ii <= 0) { continue; } String key = pair.substring(0, ii).trim(); String value = pair.substring(ii + 1).trim(); value = URLDecoder.decode(value, "UTF-8"); reqparams.put(key, value); logger.logTrace("FORM PARAM:" + key + ":" + value); } } logger.logTrace("FORM PARAMZZ:" + reqparams); } Enumeration<String> headers = request.getHeaderNames(); while (headers.hasMoreElements()) { String header = headers.nextElement(); String val = request.getHeader(header); logger.logTrace("HEADER:" + header + "=" + val); reqheaders.put(header, val); } Enumeration<String> params = request.getParameterNames(); if (params == null) return map; while (params.hasMoreElements()) { String param = params.nextElement(); if (param == null) continue; String val = request.getHeader(param); logger.logTrace("PARAM:" + param + "=" + val); reqparams.put(param, val); } return map; } protected void getFilesToSubmitForPreparedRequest(DragDropMimeHandlerRequest mr) throws IOException { if (mr.getCtx().getDropID() == null || mr.getCtx().getDropID().equals("")) { throw new RuntimeException("dropId form submit param missing"); } String[] files = folder.list(); if (files == null) return; mr.setFiles(new ArrayList<DragDropMimeFile>()); for (String fileName : files) { File f = new File(folder, fileName); if (!f.isFile()) { continue; } if (!fileName.startsWith(mr.getCtx().getUser() + "." + mr.getCtx().getDropID())) { continue; } if (fileName.endsWith(".inf")) { DragDropMimeFile mf = new DragDropMimeFile(); //TODO: Check if file was selected with checkbox and documenttype was selected //TODO: set corrected filename and documenttype mr.getFiles().add(mf); int j = fileName.lastIndexOf(".inf"); String dataFileName = fileName.substring(0, j) + ".dat"; mf.setFile(new File(folder, dataFileName)); parseInfoFile(mf, new File(folder, fileName)); mf.setFileName(mf.getPrepareParams().get("filename")); setSubmtFileDetails(mr, mf); } } } protected void setSubmtFileDetails(DragDropMimeHandlerRequest mr, DragDropMimeFile mf) { //set doctype, selection & new filename from urlformat params fileparam_1=... // * FORM PARAM:md5_1:5b9f16527d8d27f541cbb3fabf432eb6 //search file in total params map based on mf hash String fileIndex = null; for (String key : mr.getRequestParams().keySet()) { if (key.startsWith("md5_") && mr.getRequestParams().get(key).equals(mf.getHash())) { fileIndex = key.substring(4); break; } } logger.logTrace("FILE_INDEX:" + fileIndex); if (fileIndex != null) { mf.setNewfileName(mr.getRequestParams().get(DragDropConstants.FORM_PROCESS_FILES_FILENAME + fileIndex)); mf.setDocumentType(mr.getRequestParams().get(DragDropConstants.FORM_PROCESS_FILES_DOCTYPE + fileIndex)); mf.setNote(mr.getRequestParams().get(DragDropConstants.FORM_PROCESS_FILES_NOTE + fileIndex)); String checked = mr.getRequestParams().get(DragDropConstants.FORM_PROCESS_FILES_CHECK + fileIndex); mf.setChecked(checked.equalsIgnoreCase("checked") || checked.equalsIgnoreCase("on") || checked.equalsIgnoreCase("true")); logger.logTrace("+++" + mf.getNewfileName()); logger.logTrace("+++" + mf.getDocumentType()); logger.logTrace("+++" + mf.isChecked()); } } private void parseInfoFile(DragDropMimeFile mf, File infoFile) throws IOException { InputStream in = new FileInputStream(infoFile); mf.setPrepareParams(new HashMap<String, String>()); ByteArrayOutputStream bout = new ByteArrayOutputStream(); byte[] buff = new byte[10000]; int bytesread = 0; while ((bytesread = in.read(buff)) > 0) { bout.write(buff, 0, bytesread); } in.close(); String ss = new String(bout.toByteArray()); if (ss.startsWith("{")) { ss = ss.substring(1); } if (ss.endsWith("}")) { ss = ss.substring(0, ss.length() - 1); } String[] pairs = ss.split(","); for (String param : pairs) { int ii = param.indexOf("="); if (ii <= 0) { continue; } String key = param.substring(0, ii).trim(); String value = param.substring(ii + 1).trim(); if (value.endsWith("\"")) { value = value.substring(0, value.lastIndexOf("\"")); } if (value.startsWith("\"")) { value = value.substring(1); } mf.getPrepareParams().put(key, value); } mf.setHash(mf.getPrepareParams().get("md5")); } /* * Stream will start with ... (content-type can be different) * note that every formdata.add will w-be new stream * ------WebKitFormBoundaryBniKJXj8uBw05BXM Content-Disposition: form-data; name="fileSize" 3528 ------WebKitFormBoundaryBniKJXj8uBw05BXM Content-Disposition: form-data; name="file"; filename="DragDropServlet.class" Content-Type: application/octet-stream * ... * * Stream will end with * * ------WebKitFormBoundaryRBrfsAQYjBh5Rlfm-- * */ protected File serialize(DragDropContext ctx, ServletInputStream instream, int fileUploadSpeed) throws IOException { byte[] buff = new byte[1024]; int bytesread = 0; int totalBytes = 0; int totalBytes2 = 0; //ByteArrayOutputStream bout=new ByteArrayOutputStream(); File f = new File(folder, ctx.getUser() + "." + ctx.getDropID() + ".upload.mime"); FileOutputStream fout = new FileOutputStream(f); while ((bytesread = instream.read(buff)) > 0) { totalBytes += bytesread; totalBytes2 += bytesread; fout.write(buff, 0, bytesread); //approximite timing ,assume stream reading/writing takes no time, just wait 1 second when limit per/sec is reached if (fileUploadSpeed > 0) { if (totalBytes2 > fileUploadSpeed) { try { System.out.println("Sleeping..."); Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); throw new RuntimeException(e); } totalBytes2 = 0; } } } return f; } protected Map<String, String> getFilePartParams(String header) throws IOException { Map<String, String> map = new HashMap<String, String>(); //header can have CRLF BufferedReader br = new BufferedReader(new StringReader(header)); String line = null; while ((line = br.readLine()) != null) { for (String param : line.split(";")) { int ii = param.indexOf("="); if (ii <= 0) { continue;//first param form-data has no = sign } String key = param.substring(0, ii).trim(); String value = param.substring(ii + 1).trim(); if (value.endsWith("\"")) { value = value.substring(0, value.lastIndexOf("\"")); } if (value.startsWith("\"")) { value = value.substring(1); } if (key.equalsIgnoreCase("name")) { //special case: in javascript we've added the params as part of the filename,since no way to set other params in te form data //without creating a new form data item //name="FILEDATA,filesize=7253,md5=4a827628abf0efcf85f40330f5d5af71" String[] pairs = value.split(","); for (String pair : pairs) { ii = pair.indexOf("="); if (ii <= 0) { continue; } key = pair.substring(0, ii).trim(); value = pair.substring(ii + 1).trim(); if (value.endsWith("\"")) { value = value.substring(0, value.lastIndexOf("\"")); } map.put(key, value); } } else { map.put(key, value); } } } return map; } protected String getHash(File f3) throws IOException { MessageDigest m = null; try { m = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } byte[] buff = new byte[1024]; FileInputStream fin = new FileInputStream(f3); int bytesread = 0; while ((bytesread = fin.read(buff)) > 0) { m.update(buff, 0, bytesread); } fin.close(); byte[] d = m.digest(); String str = new String(Hex.encodeHex(d)); return str; } }