现在jfinal里面获取post有点麻烦,特别是要整个写入model的时候,都要用get
这边目标是使用注解定义controller里面的方法的参数,然后根据注解和参数的类型自动传值,同时解决getFile及访问后删除文件的问题
例如
public void aaa(@ModelPara User user, @PostPara String username, @PostPara String phone)
1.初始化操作
//缓存model字段名称及其数据类型,用于@ModelPara public static final Map<Class, Map<String, Class>> fieldClassMap = new HashMap(); //定义model类所在位置 public static final String modelPackage = "com.xx.common.model"; public static final String baseModelPackage = "com.xx.common.model.base"; static { //加载model字段名称及其数据类型 Set<Class<?>> classSet = ClassUtil.scanPackage(baseModelPackage); for (Class<?> aClass : classSet) { Method[] methods = aClass.getDeclaredMethods(); LinkedList<Method> getMethodList = new LinkedList<>(); for (Method method : methods) { if (method.getName().matches("get[A-Z]\\w*")) { getMethodList.add(method); } } Map<String, Class> map = new HashMap<>(getMethodList.size()); for (Method method : getMethodList) { String name = method.getName().substring(3); name = ((char) (name.charAt(0) + 32)) + name.substring(1); map.put(name, method.getReturnType()); } try { fieldClassMap.put(Class.forName(aClass.getTypeName().replace( baseModelPackage + ".Base", modelPackage + "." )), map); } catch (ClassNotFoundException e) { e.printStackTrace(); } } // System.out.println(fieldClassMap); }
2.定义拦截函数
@SneakyThrows //忽略抛出异常 @Override public void intercept(Invocation invocation) { try { JSONObject json = null; if ("POST".equals(invocation.getController().getRequest().getMethod())) { //获取文件 if (invocation.getController().getRequest().getContentType() != null && invocation.getController().getRequest().getContentType().contains("multipart/form-data")) { invocation.getController().getFiles(); } //获取post body中的json if (StrUtil.equals(invocation.getController().getRequest().getContentType(), "application/json")) { String jsonString = HttpKit.readData(invocation.getController().getRequest()); if (StrUtil.isNotBlank(jsonString)) { json = JSONObject.parseObject(jsonString); for (Map.Entry<String, Object> entry : json.entrySet()) { invocation.getController().setAttr(entry.getKey(), entry.getValue()); } } invocation.getController().setAttr("postJson", jsonString); } } if (json == null) { json = new JSONObject(); } //获取form-data和get参数 for (Map.Entry<String, String[]> entry : invocation.getController().getParaMap().entrySet()) { if (entry.getValue() != null && entry.getValue().length > 0) { json.put(entry.getKey(), entry.getValue()[0]); } } //设置注解 setAnnotation(invocation, json); invocation.invoke(); } catch (CustomException e1) { throw e1; } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e2) { e2.printStackTrace(); throw new Exception("POST映射错误:" + e2.getMessage()); } //删除上传的文件 try { if (invocation.getController().getRequest().getContentType().contains("multipart/form-data")) { for (UploadFile uploadFile : invocation.getController().getFiles()) { uploadFile.getFile().delete(); } } } catch (Exception e) { } }
3.定义根据注解传参的函数
private void setAnnotation(Invocation invocation, JSONObject json) throws CustomException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { for (int index = 0; index < invocation.getMethod().getParameters().length; index++) { Parameter parameter = invocation.getMethod().getParameters()[index]; if (parameter.getAnnotation(ModelPara.class) != null) { //ModelPara类型的注解 Object instance = parameter.getType().getDeclaredConstructor().newInstance(); Method setParaMethod = parameter.getType().getMethod("set", String.class, Object.class); for (Map.Entry<String, Object> entry : json.entrySet()) { Object o = entry.getValue(); Class c = fieldClassMap.get(parameter.getType()).get(entry.getKey()); if (c != null) { //参数类型转化 o = BaseDataConvertUtil.convert(o, c); try { setParaMethod.invoke(instance, entry.getKey(), o); } catch (InvocationTargetException e) { if (e.getCause() == null || e.getCause().getMessage() == null || !e.getCause().getMessage().contains("The attribute name does not exist")) { throw e; } } } } invocation.setArg(index, instance); } else if (parameter.getAnnotation(PostPara.class) != null) { //PostPara类型的注解 Object o = json.get(parameter.getName()); if (o != null) { if (parameter.getType().isAssignableFrom(o.getClass())) { invocation.setArg(index, o); } else { //参数类型转化 if (!BaseDataConvertUtil.inConvertType(o)) { o = o.toString(); } o = BaseDataConvertUtil.convert(o, parameter.getType()); if (o != null) { if (parameter.getType().isAssignableFrom(o.getClass())) { invocation.setArg(index, o); } else { //字段类型错误:%s,应为%s或其子类 throw new CustomException(ErrorCodeConstant.B1002, parameter.getName(), parameter.getType().getSimpleName()); } } } } } else { // invocation.setArg(index, null); } } }
4.基本参数自动转化(复杂的参数就直接是jsonobject或jsonarray了)
public class BaseDataConvertUtil { public static Set<Class> classSet = new HashSet<>(); static { classSet.add(String.class); classSet.add(Double.class); classSet.add(Integer.class); classSet.add(BigDecimal.class); classSet.add(Long.class); classSet.add(Boolean.class); classSet.add(Date.class); } //是否是可转化的类型 public static boolean inConvertType(Object object) { return object == null || classSet.contains(object.getClass()); } //自动转化 public static Object convert(Object object, Class<?> c) { if (object == null) return null; else if (object.getClass().equals(c)) { return object; } else if (c == String.class) { if (object instanceof Date) return DateUtil.formatDateTime((Date) object); return object.toString(); } else if (c == Double.class) { if (object instanceof Integer) return ((Integer) object).doubleValue(); if (object instanceof Double) return object; if (object instanceof Long) return ((Long) object).doubleValue(); if (object instanceof BigDecimal) return ((BigDecimal) object).doubleValue(); if (object instanceof Boolean) return (Boolean) object ? 1.0D : 0.0D; if (object instanceof Date) return (double) ((Date) object).getTime(); try { return Double.valueOf(object.toString()); } catch (Exception e) { return null; } } else if (c == Integer.class) { if (object instanceof Integer) return object; if (object instanceof Double) return ((Double) object).intValue(); if (object instanceof Long) return ((Long) object).intValue(); if (object instanceof BigDecimal) return ((BigDecimal) object).intValue(); if (object instanceof Boolean) return (Boolean) object ? 1 : 0; if (object instanceof Date) return (int) ((Date) object).getTime(); try { return Integer.valueOf(object.toString()); } catch (Exception e) { return null; } } else if (c == Long.class) { if (object instanceof Integer) return ((Integer) object).longValue(); if (object instanceof Double) return ((Double) object).longValue(); if (object instanceof Long) return object; if (object instanceof BigDecimal) return ((BigDecimal) object).longValue(); if (object instanceof Boolean) return (Boolean) object ? 1L : 0L; if (object instanceof Date) return ((Date) object).getTime(); try { return Long.valueOf(object.toString()); } catch (Exception e) { return null; } } else if (c == Boolean.class) { if (object instanceof Integer) return !object.equals(0); if (object instanceof Double) return !object.equals(0D); if (object instanceof Long) return !object.equals(0L); if (object instanceof BigDecimal) return ((BigDecimal) object).intValue() != 1; if (object instanceof Boolean) return object; if (object instanceof Date) return object != null; try { return "true".equals(object.toString()) || "1".equals(object.toString()); } catch (Exception e) { return null; } } else if (c == Date.class) { if (object instanceof Integer) return new Date((Integer) object); if (object instanceof Double) return new Date(((Double) object).longValue()); if (object instanceof Long) return new Date((Long) object); if (object instanceof BigDecimal) return new Date(((BigDecimal) object).longValue()); if (object instanceof Boolean) return (Boolean) object ? new Date() : null; if (object instanceof Date) return object; try { return DateUtil.parse(object.toString()); } catch (Exception e) { return null; } } return object; } public static Integer convertToInteger(Object object) { return (Integer) convert(object, Integer.class); } public static Double convertToDouble(Object object) { return (Double) convert(object, Double.class); } public static String convertToString(Object object) { return (String) convert(object, String.class); } public static Long convertToLong(Object object) { return (Long) convert(object, Long.class); } public static void main(String[] args) { Object object = convert(1.0, Integer.class); System.out.println(object); System.out.println(object.getClass()); } }
拦截器完整类
package com.xx.interceptor; import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.xx.annotation.ModelPara; import com.xx.annotation.PostPara; import com.xx.constant.ErrorCodeConstant; import com.xx.exception.CustomException; import com.xx.util.BaseDataConvertUtil; import com.jfinal.aop.Interceptor; import com.jfinal.aop.Invocation; import com.jfinal.kit.HttpKit; import com.jfinal.upload.UploadFile; import lombok.SneakyThrows; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Set; public class PostParaInterceptor implements Interceptor { /** * 缓存model字段名称及其数据类型,用于@ModelPara */ public static final Map<Class, Map<String, Class>> fieldClassMap = new HashMap(); /** * 定义model类所在位置 */ public static final String modelPackage = "com.xx.common.model"; public static final String baseModelPackage = "com.xx.common.model.base"; static { //加载model字段名称及其数据类型 Set<Class<?>> classSet = ClassUtil.scanPackage(baseModelPackage); for (Class<?> aClass : classSet) { Method[] methods = aClass.getDeclaredMethods(); LinkedList<Method> getMethodList = new LinkedList<>(); for (Method method : methods) { if (method.getName().matches("get[A-Z]\\w*")) { getMethodList.add(method); } } Map<String, Class> map = new HashMap<>(getMethodList.size()); for (Method method : getMethodList) { String name = method.getName().substring(3); name = ((char) (name.charAt(0) + 32)) + name.substring(1); map.put(name, method.getReturnType()); } try { fieldClassMap.put(Class.forName(aClass.getTypeName().replace( baseModelPackage + ".Base", modelPackage + "." )), map); } catch (ClassNotFoundException e) { e.printStackTrace(); } } // System.out.println(fieldClassMap); } @SneakyThrows //忽略抛出异常 @Override public void intercept(Invocation invocation) { try { JSONObject json = null; if ("POST".equals(invocation.getController().getRequest().getMethod())) { //获取文件 if (invocation.getController().getRequest().getContentType() != null && invocation.getController().getRequest().getContentType().contains("multipart/form-data")) { invocation.getController().getFiles(); } //获取post body中的json if (StrUtil.equals(invocation.getController().getRequest().getContentType(), "application/json")) { String jsonString = HttpKit.readData(invocation.getController().getRequest()); if (StrUtil.isNotBlank(jsonString)) { json = JSONObject.parseObject(jsonString); for (Map.Entry<String, Object> entry : json.entrySet()) { invocation.getController().setAttr(entry.getKey(), entry.getValue()); } } invocation.getController().setAttr("postJson", jsonString); } } if (json == null) { json = new JSONObject(); } //获取form-data和get参数 for (Map.Entry<String, String[]> entry : invocation.getController().getParaMap().entrySet()) { if (entry.getValue() != null && entry.getValue().length > 0) { json.put(entry.getKey(), entry.getValue()[0]); } } //设置注解 setAnnotation(invocation, json); invocation.invoke(); } catch (CustomException e1) { throw e1; } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e2) { e2.printStackTrace(); throw new Exception("POST映射错误:" + e2.getMessage()); } //删除上传的文件 try { if (invocation.getController().getRequest().getContentType().contains("multipart/form-data")) { for (UploadFile uploadFile : invocation.getController().getFiles()) { uploadFile.getFile().delete(); } } } catch (Exception e) { } } private void setAnnotation(Invocation invocation, JSONObject json) throws CustomException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { for (int index = 0; index < invocation.getMethod().getParameters().length; index++) { Parameter parameter = invocation.getMethod().getParameters()[index]; if (parameter.getAnnotation(ModelPara.class) != null) { //ModelPara类型的注解 Object instance = parameter.getType().getDeclaredConstructor().newInstance(); Method setParaMethod = parameter.getType().getMethod("set", String.class, Object.class); for (Map.Entry<String, Object> entry : json.entrySet()) { Object o = entry.getValue(); Class c = fieldClassMap.get(parameter.getType()).get(entry.getKey()); if (c != null) { //参数类型转化 o = BaseDataConvertUtil.convert(o, c); try { setParaMethod.invoke(instance, entry.getKey(), o); } catch (InvocationTargetException e) { if (e.getCause() == null || e.getCause().getMessage() == null || !e.getCause().getMessage().contains("The attribute name does not exist")) { throw e; } } } } invocation.setArg(index, instance); } else if (parameter.getAnnotation(PostPara.class) != null) { //PostPara类型的注解 Object o = json.get(parameter.getName()); if (o != null) { if (parameter.getType().isAssignableFrom(o.getClass())) { invocation.setArg(index, o); } else { //参数类型转化 if (!BaseDataConvertUtil.inConvertType(o)) { o = o.toString(); } o = BaseDataConvertUtil.convert(o, parameter.getType()); if (o != null) { if (parameter.getType().isAssignableFrom(o.getClass())) { invocation.setArg(index, o); } else { //字段类型错误:%s,应为%s或其子类 throw new CustomException(ErrorCodeConstant.B1002, parameter.getName(), parameter.getType().getSimpleName()); } } } } } else { // invocation.setArg(index, null); } } } }
ModelPara类
package com.xx.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface ModelPara { }
PostPara类
package com.xx.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface PostPara { }