如果上传文件form表单使用了enctype="multipart/form-data",必须先调用getFile系列方法才能使getPara系列方法正常工作。
因为使用layui的上传控件,是通过Ajax方式上传文件,使用FormData进行Ajax请求,并不是enctype="multipart/form-data"方式。
所以,文件上传请求统一改为使用FormData进行Ajax请求提交,此时不用考虑是否要先调用getFile系列方法。
但是在使用微信小程序的wx.uploadFile接口上传文件时,是需要先调用getFile系列方法,才能获取到其他的表单参数。
这个无法更改请求方式。只能是后台先调用getFile系列方法了。
目前有个问题是,系统的权限校验拦截器,获取token判断权限,通过wx.uploadFile接口上传文件时,获取不到token,导致权限校验不通过。
一种快速的简单的解决方案是:直接在拦截器中先调用一次getFile系列方法,然后就能正常获取表单参数了。
这种方案的缺点:权限校验拦截器会拦截所有请求,都调用getFile系列方法,感觉会影响性能,毕竟系统大部分拦截的请求都不是文件上传的。另外没有上传文件,使用getFile系列方法不确定是否会有其他异常。
另一种解决方案:
需要先调用getFile系列方法的请求,统一其URI以指定的字符结尾。如“upload”。如果url已upload结尾,则先调用getFile系列方法。
private static final String UPLOAD_ACTIONKEY_SUFFIX = "upload";
/**
* actionKey以upload结尾,则该操作包含上传文件,则需要先调用controller.getFiles();
* @param actionKey 例子 /dangan/uploadPhoto/upload 或者 /dangan/uploadPhoto/XXXXupload
* @param controller
*/
private void uploadFileUrlDeal(String actionKey, Controller controller) {
if(actionKey.length() >= UPLOAD_ACTIONKEY_SUFFIX.length()){
String endStr = actionKey.substring(actionKey.length() - UPLOAD_ACTIONKEY_SUFFIX.length(), actionKey.length());
if(UPLOAD_ACTIONKEY_SUFFIX.equals(endStr) || UPLOAD_ACTIONKEY_SUFFIX.equals(StrKit.firstCharToLowerCase(endStr))){
controller.getFiles();
}
}
}
public void intercept(Invocation inv) {
Controller controller= inv.getController();
HttpSession session = inv.getController().getSession();
String actionKey = inv.getActionKey();
uploadFileUrlDeal(actionKey,controller);
String token = controller.getPara(TokenUtil.TOKEN_STR);
// ....
}