什么网站上面能接点小活做,网上注册公司营业执照注册流程,塑业东莞网站建设,可以做推送的网站确定文件上传使用场景 通常情况下#xff0c;我们可以通过一个form#xff08;表单#xff09;来上传文件#xff0c;就以下面的“创建客户”为例来说明#xff08;对应的文件名是customer_create.jsp#xff09;#xff0c;需要提供一个form#xff0c;并将其enctype属…确定文件上传使用场景 通常情况下我们可以通过一个form表单来上传文件就以下面的“创建客户”为例来说明对应的文件名是customer_create.jsp需要提供一个form并将其enctype属性设为multipart/form-data表示以form data方式提交表单数据。 注意enctype的默认值为application/x-www-form-urlencoded表示以url encoded方式提交表单数据。 下面我们使用jQuery与jQuery Form插件快速编写一个基于Ajax的文件上传表单代码如下 % page pageEncodingUTF-8 contentTypetext/html;charsetUTF-8 languagejava %
%taglib prefixc urihttp://java.sun.com/jsp/jstl/core %c:set varBASE value${pageContext.request.contextPath}/
html
headtitle客户管理-创建客户/title
/head
bodyh1创建客户界面/h1
${msg}
form idcustomer_form enctypemultipart/form-datatabletrtd客户名称/tdtdinput typetext namename value${customer.name}/td/trtrtd联系人/tdtdinput typetext namecontact value${customer.contact}/td/trtrtd电话号码/tdtdinput typetext nametelephone value${customer.telephone}/td/trtrtd邮箱地址/tdtdinput typetext nameemail value${customer.email}/td/trtrtd照片/tdtdinput typefile namephoto value${customer.photo}/td/tr/tablebutton typesubmit保存/button
/formscript src${BASE}/asset/lib/jquery/jquery.min.js/script
script src${BASE}/asset/lib/jquery-form/jquery.form.min.js/script
script$(function () {$(#customer_form).ajaxForm({type:post,url:${BASE}/customer_create,success:function (data) {if(data){location.href ${BASE}/customer;}}});});
/script
/body
/html 当表单提交时请求会转发到CustomerController的createSubmit方法上。该方法带有一个Param参数我们打算通过该参数来获取“表单字段的名值对映射”与“所上传的文件参数对象”应该如何编码呢下面是我们要实现的目标 Controller
public class CustomerController {/*** 处理 创建客户请求 - 带图片*/Action(post:/customer_create)public Data createSubmit(Param param){MapString,Object fieldMap param.getFieldMap();FileParam fileParam param.getFile(photo);boolean result customerService.createCustomer(fieldMap,fileParam);return new Data(result);}
} 调用Param的getFieldMap()方法来获取表单字段的键值对映射Map fieldMap指定一个具体的文件字段名称photo并调用getFile方法即可获取对应的文件参数对象FileParam fileParam。随后可调用customerService的createCustomer方法将fieldMap与fileParam这两个参数传入。 Controller层的代码就是这样具体业务逻辑都在Service层了对于CustomerService而言只需写几行代码即可实现业务逻辑将输入参数存入数据库同时将文件上传到服务器上。 Service
public class CustomerService {/*** 创建客户*/Transactionpublic boolean createCustomer(MapString,Object fieldMap,FileParam fileParam){Boolean result DBHelper.insertEntity(Customer.class,fieldMap);if (result){UploadHelper.uploadFile(/tmp/upload/,fileParam);}return result;}
} 可见除了使用DatabaseHelper操作数据库还可以通过UploadHelper将文件上传到指定的服务器目录中。 注意实际上完全可以通过代码来读取配置文件中定义的文件上传路径此处只是为了简化请注意。 我们把计划要完成的事情总结一下 1改造Param结构可以通过它来获取已上传的文件参数FileParam 2使用UploadHelper助手类来上传文件。 实现文件上传功能 我们不妨从FileParam开始它实际上是一个用于封装文件参数的JavaBean代码如下 /*** program: FileParam* description: 封装文件参数的Bean*/
public class FileParam {private String fieldName; //文件表单的字段名private String fileName; //文件名private long fileSize; //文件大小private String contentType; //上传文件的Content-Type,可判断文件类型private InputStream inputStream; //上传文件的字节输入流public FileParam(String fieldName, String fileName, long fileSize, String contentType, InputStream inputStream) {this.fieldName fieldName;this.fileName fileName;this.fileSize fileSize;this.contentType contentType;this.inputStream inputStream;}public String getFieldName() {return fieldName;}public String getFileName() {return fileName;}public long getFileSize() {return fileSize;}public String getContentType() {return contentType;}public InputStream getInputStream() {return inputStream;}
} 除了文件参数FileParam我们还需要一个表单参数FormParam代码如下 /*** program: FormParam* description: 封装表单参数*/
public class FormParam {private String fieldName; //表单字段名private Object fieldValue; //表单字段值public FormParam(String fieldName, Object fieldValue) {this.fieldName fieldName;this.fieldValue fieldValue;}public String getFieldName() {return fieldName;}public Object getFieldValue() {return fieldValue;}
} 在一个表单中所有的参数可分为两类表单参数与文件参数。有必要将Param类做一个重构让它封装这两类参数并提供一系列的get方法用于从该对象中获取指定的参数。 /*** program: Param* description: 请求参数对象*/
public class Param {private ListFormParam formParamList;private ListFileParam fileParamList;public Param(ListFormParam formParamList) {this.formParamList formParamList;}public Param(ListFormParam formParamList, ListFileParam fileParamList) {this.formParamList formParamList;this.fileParamList fileParamList;}/*** 获取请求参数映射* return*/public MapString,Object getFieldMap(){MapString,Object fieldMap new HashMapString,Object();if (CollectionUtil.isNotEmpty(formParamList)){for (FormParam formParam:formParamList){String fieldName formParam.getFieldName(); //表单参数名Object fieldValue formParam.getFieldValue(); //表单参数值if (fieldMap.containsKey(fieldName)){ //如果已经有此参数名fieldValue fieldMap.get(fieldName) StringUtil.SEPARATOR fieldValue; // 旧的数据--新的数据作为value}fieldMap.put(fieldName,fieldValue);}}return fieldMap;}/*** 获取上传文件映射*/public MapString,ListFileParam getFileMap(){MapString,ListFileParam fileMap new HashMapString,ListFileParam();if (CollectionUtil.isNotEmpty(fileMap)){for (FileParam fileParam:fileParamList){ //遍历文件参数String fieldName fileParam.getFieldName(); //获取表单文件字段名ListFileParam fileParamList;if (fileMap.containsKey(fieldName)){ //如果Map已经存在fileParamList fileMap.get(fieldName); //获取Map中的值}else{fileParamList new ArrayListFileParam(); //否则,新建一个值}fileParamList.add(fileParam); //值fileMap.put(fieldName,fileParamList); //放入到表单文件字段名,ListFileParam的映射中}}return fileMap;}/*** 获取所有上传文件* param fieldName 表单文件字段名* return*/public ListFileParam getFileList(String fieldName){return getFileMap().get(fieldName);}/*** 获取唯一上传文件* param fieldName 表单文件字段名* return*/public FileParam getFile(String fieldName){ListFileParam fileParamList getFileList(fieldName);if (CollectionUtil.isNotEmpty(fileParamList) fileParamList.size() 1){return fileParamList.get(0);}return null;}/*** 验证参数是否为空* return*/public boolean isEmpty(){return CollectionUtil.isEmpty(formParamList) CollectionUtil.isEmpty(fileParamList);}/*** 根据参数名获取String型参数值* param name* return*/public String getString(String name){return CastUtil.castString(getFieldMap().get(name));}/*** 根据参数名获取Double型参数值* param name* return*/public Double getDouble(String name){return CastUtil.castDouble(getFieldMap().get(name));}/*** 根据参数名获取Long型参数值* param name* return*/public long getLong(String name){return CastUtil.castLong(getFieldMap().get(name));}/*** 根据参数名获取int型参数值* param name* return*/public int getInt(String name){return CastUtil.castInt(getFieldMap().get(name));}/*** 根据参数名获取boolean型参数值* param name* return*/public boolean getBoolean(String name){return CastUtil.castBoolean(getFieldMap().get(name));}} 可见Param包含了两个成员变量ListformParamList与ListfileParamList它们分别封装了表单参数与文件参数随后提供了两个构造器用于初始化Param对象还提供了两个get方法分别用于获取所有的表单参数与文件参数。返回值均为Map类型其中Map表示请求参数映射Map表示上传文件映射。对于同名的请求参数通过一个特殊的分隔符进行了处理该分隔符定义在StringUtil类中代码如下 /*** 分隔符*/public static final String SEPARATOR String .valueOf((char)29); 对于同名的上传文件通过一个List进行了封装可轻松实现多文件上传的需求。可通过List getFileList(String fieldName) 方法获取所有上传文件若只上传了一个文件则可直接使用FileParam getFile(String fieldName)方法获取唯一上传文件。还提供了一个boolean isEmpty()方法用于验证参数是否为空。最后提供了一组根据参数名获取指定类型的方法例如String getString(String name)、double getDouble(String name)等。 可借助Apache Commons提供的FileUpload类库实现文件上传特性首先需要在pom.xml中添加如下依赖 !--文件上传--dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.3.1/version/dependency 接下来我们需要编写一个UploadHelper类来封装Apache Commons FileUpload的相关代码 import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smart4j.framework.bean.FileParam;
import org.smart4j.framework.bean.FormParam;
import org.smart4j.framework.bean.Param;
import org.smart4j.framework.util.CollectionUtil;
import org.smart4j.framework.util.FileUtil;
import org.smart4j.framework.util.StreamUtil;
import org.smart4j.framework.util.StringUtil;import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** program: UploadHelper* description: 文件上传助手类* author: Created by Autumn* create: 2018-12-14 16:21*/
public final class UploadHelper {private static final Logger LOGGER LoggerFactory.getLogger(UploadHelper.class);/*** Apache Commons FileUpload提供的Servlet文件上传对象*/private static ServletFileUpload servletFileUpload;/*** 初始化*/public static void init(ServletContext servletContext){/*获取tomcat的work目录*/File repository (File) servletContext.getAttribute(javax.servlet.context.tempdir);/*** DiskFileItemFactory构造的两个参数* 第一个参数sizeThreadHold - 设置缓存(内存)保存多少字节数据默认为10240字节即10K* 如果一个文件没有大于10K则直接使用内存直接保存成文件就可以了。* 如果一个文件大于10K就需要将文件先保存到临时目录中去。* 第二个参数 File 是指临时目录位置 - 可以不用tomcat的work目录可以用任意一个目录*/DiskFileItemFactory fileItemFactory new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, repository);servletFileUpload new ServletFileUpload(fileItemFactory);int uploadLimit ConfigHelper.getAppUploadLimit(); //获取文件上传限制默认为10Mif (uploadLimit ! 0){servletFileUpload.setFileSizeMax(uploadLimit*1024*1024); //设置单文件最大大小为10M}}/*** 判断请求是否为multipart类型*/public static boolean isMultipart(HttpServletRequest request){return ServletFileUpload.isMultipartContent(request);}/*** 创建请求对象* 将request转换为Param参数* return*/public static Param createParam(HttpServletRequest request) throws IOException {ListFormParam formParamList new ArrayListFormParam();ListFileParam fileParamList new ArrayListFileParam();try{/*解析request*/MapString,ListFileItem fileItemListMap servletFileUpload.parseParameterMap(request); //将request转换为Mapif (CollectionUtil.isNotEmpty(fileItemListMap)){//遍历Map集合一个表单名可能有多个文件for (Map.EntryString,ListFileItem fileItemListEntry : fileItemListMap.entrySet()){String fieldName fileItemListEntry.getKey(); //获取表单字段名ListFileItem fileItemList fileItemListEntry.getValue(); //文件集合if (CollectionUtil.isNotEmpty(fileItemListMap)){for (FileItem fileItem:fileItemList){ //遍历文件集合if (fileItem.isFormField()){ //如果是表单字段String fieldValue fileItem.getString(UTF-8);formParamList.add(new FormParam(fieldName,fieldValue));}else{ //如果是文件String fileName FileUtil.getRealFileName(new String(fileItem.getName().getBytes(),UTF-8)); //获取文件名if (StringUtil.isNotEmpty(fileName)){ //如果文件名不为空long fileSize fileItem.getSize(); //获取文件大小String contentType fileItem.getContentType(); //获取文件类型InputStream inputStream fileItem.getInputStream(); //获取文件输入流fileParamList.add(new FileParam(fieldName,fileName,fileSize,contentType,inputStream));}}}}}}} catch (FileUploadException e) {LOGGER.error(create param failure,e);throw new RuntimeException(e);}return new Param(formParamList,fileParamList);}/*** 上传文件* param basePath* param fileParam*/public static void uploadFile(String basePath,FileParam fileParam){try{if (fileParam ! null){String filePath basePath fileParam.getFileName(); //路径文件名FileUtil.createFile(filePath); //创建文件InputStream inputStream new BufferedInputStream(fileParam.getInputStream()); //获取文件的输入流OutputStream outputStream new BufferedOutputStream(new FileOutputStream(filePath)); //获取输出流StreamUtil.copyStream(inputStream,outputStream); //输入流拷贝到输出流中}} catch (FileNotFoundException e) {LOGGER.error(upload file failure,e);throw new RuntimeException(e);}}/*** 批量上传文件* param basePath* param fileParamList*/public static void uploadFile(String basePath,ListFileParam fileParamList){try {if (CollectionUtil.isNotEmpty(fileParamList)){for (FileParam fileParam : fileParamList){uploadFile(basePath,fileParam);}}}catch (Exception e){LOGGER.error(upload file failure,e);throw new RuntimeException(e);}}
} 需要提供一个init方法在该方法中初始化ServletFileUpload对象。一般情况下只需设置一个上传文件的临时目录与上传文件的最大限制上传文件的临时目录可设置为应用服务器的临时目录上传文件的最大限制可让用户自行配置。所以我们使用了ConfigHelper.getAppUploadLimit()来获取可以在smart.properties文件中进行配置。 首先在ConfigConstant中添加一个配置常量APP_UPLOAD_LIMIT; String APP_UPLOAD_LIMIT smart.framework.app.upload_limit; 这也就意味着我们可以在smart.properties文件中使用smart.framwork.app.upload_limit配置项来设定上传文件的最大限制。 然后在ConfigHelper中添加一个int getAppUploadLimit()方法用于获取该配置的值此时可设置该配置的初始值10也就是说若不在smart.properties文件中提供该配置则上传文件的最大限制是10MB。 public class ConfigHelper {/*** 获取应用文件上传限制* return*/public static int getAppUploadLimit(){return PropsUtil.getInt(CONFIG_PROPS,ConfigConstant.APP_UPLOAD_LIMIT,10);}
} 在UploadHelper中提供一个boolean isMultipart(HttpServletRequest request)方法用于判断当前请求对象是否为multipart类型。只有在上传文件时对应的请求类型才是multipart类型也就是说可通过isMultipart方法来判断当前请求时否为文件上传请求。 接下来提供一个非常重要的方法可从当前请求中创建Param对象它就是Param createParam(HttpServletRequest request)方法其中我们使用了ServletFileUpload对象来解析请求参数并通过遍历所有请求参数来初始化List formParamList与List fileParamList变量的值。在遍历请求参数时需要对当前的org.apache.commons.fileupload.FileItem对象进行判断若为普通表单字段调用fileItem.isFormField()返回true则创建FormParam对象并添加到formParamList对象中。否则即为文件上传字段通过FileUtil提供的getRealFileName来获取上传文件后的真实文件名并从FileItem对象中构造FileParam对象添加到fileParamList对象中最后通过formParamList与fileParamList来构造Param对象并返回。 FileUtil代码如下 import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;/*** program: FileUtil* description: 文件操作工具类* author: Created by Autumn* create: 2018-12-19 13:03*/
public class FileUtil {private static final Logger LOGGER LoggerFactory.getLogger(FileUtil.class);/*** 获取真实文件名(自动去掉文件路径)** param fileName* return*/public static String getRealFileName(String fileName) {return FilenameUtils.getName(fileName);}/*** 创建文件** param filePath* return*/public static File createFile(String filePath) {File file;file new File(filePath); //根据路径创建文件try {File parentDir file.getParentFile(); //获取文件父目录if (!parentDir.exists()) { //判断上层目录是否存在FileUtils.forceMkdir(parentDir); //创建父级目录}} catch (IOException e) {LOGGER.error(create file failure,e);throw new RuntimeException(e);//e.printStackTrace();}return file;}
} 最后提供两个用于上传文件的方法一个用于上传单个文件另一个用于批量上传。此时用到了StreamUtil工具类的copyStream方法代码如下 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;/*** program: StreamUtil* description: 流操作常用工具类* author: Created by Autumn* create: 2018-10-24 15:41*/
public class StreamUtil {private static final Logger LOGGER LoggerFactory.getLogger(StreamUtil.class);/*** 从输入流中获取字符串* param is* return*/public static String getString(InputStream is){StringBuilder sb new StringBuilder();try {BufferedReader reader new BufferedReader(new InputStreamReader(is));String line;while((linereader.readLine())!null){sb.append(line);}} catch (IOException e) {LOGGER.error(get string failure,e);throw new RuntimeException(e);}return sb.toString();}/*** 将输入流复制到输出流* param inputStream 输入流* param outputStream 输出流*/public static void copyStream(InputStream inputStream, OutputStream outputStream){try {int length;byte[] buffer new byte[4*1024];while((length inputStream.read(buffer,0,buffer.length)) ! -1){outputStream.write(buffer,0,length);}outputStream.flush();} catch (IOException e) {LOGGER.error(copy stream failure,e);throw new RuntimeException(e);} finally {try {inputStream.close();outputStream.close();} catch (IOException e) {LOGGER.error(close stream failure,e);}}}} 现在UploadHelper已编写完毕接下来需要找一个地方来调用init方法。整个web框架的入口也就是DispatcherServlet的init方法了所有我们需要在该方法中调用UploadHelper的init方法。 除了在DispatcherServlet的init方法中添加一行代码还需要对service代码进行一些重构。首先需要跳过/favicon.ico请求只处理普通的请求。然后需要判断请求对象是否为上传文件针对两种不同的情况来创建Param对象其中通过UploadHelper来创建的方式已在前面描述了。相应的我们也对以前的代码进行封装提供一个名为RequestHelper类并通过它的createParam方法来初始化Param对象。 import org.smart4j.framework.bean.FormParam;
import org.smart4j.framework.bean.Param;
import org.smart4j.framework.util.ArrayUtil;
import org.smart4j.framework.util.CodecUtil;
import org.smart4j.framework.util.StreamUtil;
import org.smart4j.framework.util.StringUtil;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;/*** program: RequestHelper* description: 请求助手类* author: Created by Autumn* create: 2018-12-25 13:22*/
public class RequestHelper {public static Param createParam(HttpServletRequest request) throws IOException {ListFormParam formParamList new ArrayList();formParamList.addAll(parseParameterNames(request));formParamList.addAll(parseInputStream(request));return new Param(formParamList);}/*** 获取Form表单普通参数并放入ListFormParam中* 适用于application/x-www-form-urlencoded* param request* return ListFormParam*/private static ListFormParam parseParameterNames(HttpServletRequest request){ListFormParam formParamList new ArrayListFormParam();EnumerationString paramNames request.getParameterNames(); //获取request中的所有参数名称枚举while (paramNames.hasMoreElements()){ //遍历参数名枚举String fieldName paramNames.nextElement(); //获取参数名称//!!!!!!!!获取参数值(例如CheckBox的值有多个) request.getParameter(String name)是获得相应名的数据如果有重复的名则返回第一个的值.String[] fieldValues request.getParameterValues(fieldName);if (ArrayUtil.isNotEmpty(fieldValues)){ //判断是否为空Object fieldValue; //参数最终值if (fieldValues.length 1){ //如果只有一个值fieldValue fieldValues[0]; //直接赋值} else { //如果有多个值(CheckBox多选)StringBuilder sb new StringBuilder();for (int i 0; i fieldValues.length; i){ //遍历sb.append(fieldValues[i]);if (i ! fieldValues.length-1){ //如果不是最后一个sb.append(StringUtil.SEPARATOR); //加上通用分割符}}fieldValue sb.toString();}formParamList.add(new FormParam(fieldName,fieldValue)); //将参数键值对加入List参数列表中去}}return formParamList;}/*** 获取参数流并放入ListFormParam中* 适用于application/jsontext/xmlmultipart/form-data文本流或者大文件形式提交的请求或者xml等形式的报文* param request* return* throws IOException*/private static ListFormParam parseInputStream(HttpServletRequest request) throws IOException {ListFormParam formParamList new ArrayListFormParam();String body CodecUtil.decodeURL(StreamUtil.getString(request.getInputStream()));if (StringUtil.isNotEmpty(body)){String[] kvs StringUtil.splitString(body,);if (ArrayUtil.isNotEmpty(kvs)){for (String kv:kvs) {String[] array StringUtil.splitString(kv, );if (ArrayUtil.isNotEmpty(array) array.length 2){String fieldName array[0];String fieldValue array[1];formParamList.add(new FormParam(fieldName,fieldValue));}}}}return formParamList;}
} 可见以上代码逻辑并未变化只是将以前放在DispatcherServlet中的相关代码搬到了RequestHelper中了。最后获取的View同样也分两种情况进行了处理只是此时并未提供其他类来封装这些代码而是直接在当前类中添加了两个私有方法handleViewResult与handleDataResult。 重构后的Dispatcher代码 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smart4j.framework.bean.Data;
import org.smart4j.framework.bean.Handler;
import org.smart4j.framework.bean.Param;
import org.smart4j.framework.bean.View;
import org.smart4j.framework.helper.*;
import org.smart4j.framework.util.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;/*** program: DispatcherServlet* description: 请求转发器* author: Created by Autumn* create: 2018-10-24 11:34*/WebServlet(urlPatterns /*,loadOnStartup 0)
public class DispatcherServlet extends HttpServlet {private static final Logger LOGGER LoggerFactory.getLogger(DispatcherServlet.class);Overridepublic void init(ServletConfig servletConfig) throws ServletException {//初始化相关Helper类HelperLoader.init();//获取ServletContext对象(用于注册Servlet)ServletContext servletContext servletConfig.getServletContext();//注册处理JSP的ServletServletRegistration jspServlet servletContext.getServletRegistration(jsp);jspServlet.addMapping(ConfigHelper.getAppJspPath()*);//注册处理静态资源的默认ServletServletRegistration defaultServlet servletContext.getServletRegistration(default);defaultServlet.addMapping(ConfigHelper.getAppAssetPath()*);//初始化上传文件大小以及超过最大大小存放的目录UploadHelper.init(servletContext);}Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取请求方法与请求路径String requestMethod req.getMethod().toLowerCase();String requestPath req.getPathInfo();if (requestPath.equals(\favicon.ico)){return ;}//获取Action处理器Handler handler ControllerHelper.getHandler(requestMethod,requestPath);if(handler!null){//获取Controller类机器Bean实例Class? controllerClass handler.getControllerClass();Object controllerBean BeanHelper.getBean(controllerClass);Param param;if (UploadHelper.isMultipart(req)){ //如果是multipart/form-data streamparam UploadHelper.createParam(req); //multipart方式}else{ //如果是非multipart方式提交(即application/x-www-form-urlencodedapplication/jsontext/xml)param RequestHelper.createParam(req); //非multipart表单方式}/*将一下代码放入RequestHelper中去//创建请求参数对象MapString,Object paramMap new HashMapString, Object();EnumerationString paramNames req.getParameterNames();while(paramNames.hasMoreElements()){String paramName paramNames.nextElement();String paramValue req.getParameter(paramName);paramMap.put(paramName,paramValue);}//获取请求body中的参数String body CodecUtil.decodeURL(StreamUtil.getString(req.getInputStream()));if (StringUtil.isNotEmpty(body)){String[] params StringUtil.splitString(body,);if (ArrayUtil.isNotEmpty(params)){for (String param:params){String[] array StringUtil.splitString(param,);if (ArrayUtil.isNotEmpty(array)array.length2){String paramName array[0];String paramValue array[1];paramMap.put(paramName,paramValue);}}}}Param param new Param(paramMap);*/Object result null;//调用Action方法Method actionMethod handler.getActionMethod();/*优化没有参数的话不需要写参数*/if (param.isEmpty()){ //如果没有参数result ReflectionUtil.invokeMethod(controllerBean,actionMethod); //就不传参数}else{ //有参数result ReflectionUtil.invokeMethod(controllerBean,actionMethod,param); //传参数}//处理Action方法返回值if (result instanceof View){//返回JSP页面handleViewResult((View) result, req, resp);}else if (result instanceof Data){//返回Json数据handleDataResult((Data) result, resp);}}else{LOGGER.error(Request-Handler Mapping get null by Request(requestMethod,requestPath));throw new RuntimeException(Request-Handler Mapping get null by Request(requestMethod,requestPath));}}/*** 处理Json格式的数据* param result Data对象* param resp* throws IOException*/private void handleDataResult(Data result, HttpServletResponse resp) throws IOException {Data data result;Object model data.getModel();if (model!null){resp.setContentType(application/json);resp.setCharacterEncoding(UTF-8);PrintWriter writer resp.getWriter();String json JsonUtil.toJson(model);writer.write(json);writer.flush();writer.close();}}/*** 处理视图结果* param result View对象(jsp路径数据)* param req* param resp* throws IOException* throws ServletException*/private void handleViewResult(View result, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {View view result;String path view.getPath();if (StringUtil.isNotEmpty(path)){if (path.startsWith(/)){ //如果View的Path以/开头则以项目根目录为根路径resp.sendRedirect(req.getContextPath()path);} else { //如果View的Path没有以/开头,则以配置的APPJSP(/WEB-INF/view/)为根目录MapString,Object model view.getModel();for (Map.EntryString,Object entry:model.entrySet()){req.setAttribute(entry.getKey(),entry.getValue());}req.getRequestDispatcher(ConfigHelper.getAppJspPath()path).forward(req,resp);}}}
} 此时一个简单的文件上传特性已基本具备可以在框架中正常使用了。 可能出现的问题 获取注册处理JSP的Servlet报错 问题代码 这是因为tomcat用的是maven插件并不是真实的tomcat。所以导致获取jsp的servlet失败。 jQuery未引入导致用原生form提交 原生form提交的几个要素 actionurl 地址服务器接收表单数据的地址 method提交服务器的http方法一般为post和get enctype: 表单数据提交时使用的编码类型默认使用pplication/x-www-form-urlencoded。如果是使用POST请求则请求头中的content-type指定值就是该值。如果表单中有上传文件编码类型需要使用multipart/form-data类型才能完成传递文件数据。 写了method、enctype和action后最后form表单的提交按钮要用 input typesubmit保存/input 缺一个都会用默认的get方式提交。 form idcustomer_form action${BASE}/customer_create methodpost enctypemultipart/form-datainput typesubmit保存/input
/form 后台获取文件没有内容此bug由个人失误导致可过滤 调试框架源码发现一个方法判断有误写成了局部变量fileMap了。写时候一个不小心调试要调试半天呐 最终文件上传完毕结果如下。 框架源码 项目源码使用开发框架 转载于:https://www.cnblogs.com/aeolian/p/10118806.html