jfinal的路由如果多了,都放在一个方法里面设置很容易混淆,因此可以考虑在每个controller类上面定义,如下面的controller类,RequestMap代表类的路径,WebDir代表view的相对目录,controller类定义
package com.js.jshop.boot.controller; import com.jfinal.core.Controller; import com.js.common.anno.RequestMap; import com.js.common.anno.WebDir; import java.util.List; @RequestMap(name="/boot/brand") @WebDir(name="/boot/brand") public class BrandController extends Controller{ public void hello() { System.out.println("hello"); render("hello.html"); } }
增加两个anno,一个定义路径RequestMap,如下
package com.js.common.anno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMap { public String name(); }
一个定义view的相对目录WebDir
package com.js.common.anno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface WebDir { String name(); }
增加Controller包扫描类ClassUtil.java,用于读取包下controller的定义,注意这里用到的方法是提取controller类的
package com.js.common.util; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.net.URLDecoder; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jfinal.core.Controller; import com.js.common.anno.RequestMap; import com.js.common.anno.WebDir; /** * 类加载工具类 * @ClassName: ClassUtil * @Description: TODO(这里用一句话描述这个类的作用) * @author 刘楠,xlp * @date 2017-1-12 下午4:54:19 * @date 2018-3-9 */ public class ClassUtil { public static void main(String[] args) { String controllerPackageName = "com.js.jshop.boot.controller"; Set<Class<? extends Controller>> claesses=getControllerClassSet(controllerPackageName); for(Class<?> c:claesses){ System.out.println(c.getGenericSuperclass()); System.out.println(c.getName()); RequestMap requestMap=c.getAnnotation(RequestMap.class); WebDir webDir=c.getAnnotation(WebDir.class); System.out.println(requestMap.name()); System.out.println(webDir.name()); } } private static final Logger LOGGER = LoggerFactory.getLogger(ClassUtil.class); /** * 获取类加载器 * @Title: getClassLoader * @Description: TODO(这里用一句话描述这个方法的作用) * @param @return 设定文件 * @return ClassLoader 返回类型 * @throws */ public static ClassLoader getClassLoader() { return Thread.currentThread().getContextClassLoader(); } /** * 加载类 * 需要提供类名与是否初始化的标志, * 初始化是指是否执行静态代码块 * @Title: loadClass * @Description: TODO(这里用一句话描述这个方法的作用) * @param @param className * @param @param isInitialized 为提高性能设置为false * @param @return 设定文件 * @return Class<?> 返回类型 * @throws */ public static Class<?> loadClass(String className, boolean isInitialized) { Class<?> cls; try { cls = Class.forName(className, isInitialized, getClassLoader()); //Thread.currentThread().getContextClassLoader().loadClass(className); } catch (ClassNotFoundException e) { e.printStackTrace(); LOGGER.error("加载类失败 loadClass->{}", e); throw new RuntimeException(e); } return cls; } public static Class<? extends Controller> loadControllerClass(String className, boolean isInitialized) { Class<? extends Controller> cls; try { cls = (Class<? extends Controller>) Class.forName(className, isInitialized, getClassLoader()); //Thread.currentThread().getContextClassLoader().loadClass(className); } catch (ClassNotFoundException e) { e.printStackTrace(); LOGGER.error("加载类失败 loadClass->{}", e); throw new RuntimeException(e); } return cls; } /** * 加载指定包下的所有类 * @Title: getClassSet * @Description: TODO(这里用一句话描述这个方法的作用) * @param @param packageName * @param @return 设定文件 * @return Set<Class<?>> 返回类型 * @throws */ public static Set<Class<?>> getClassSet(String packageName) { Set<Class<?>> classSet = new HashSet<Class<?>>(); try { Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".", "/")); while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (url != null) { String protocol = url.getProtocol(); if (protocol.equals("file")) { // 转码 String packagePath = URLDecoder.decode(url.getFile(), "UTF-8"); // String packagePath =url.getPath().replaceAll("%20", // ""); // 添加 addClass(classSet, packagePath, packageName); } else if (protocol.equals("jar")) { JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); if (jarURLConnection != null) { JarFile jarFile = jarURLConnection.getJarFile(); if (jarFile != null) { Enumeration<JarEntry> jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith(".class")) { String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")) .replaceAll("/", "."); doAddClass(classSet, className); } } } } } } } } catch (IOException e) { e.printStackTrace(); LOGGER.error("查找包下的类失败{}", e); } return classSet; } /** * 加载指定包下的所有类 * @Title: getClassSet * @Description: TODO(这里用一句话描述这个方法的作用) * @param @param packageName * @param @return 设定文件 * @return Set<Class<?>> 返回类型 * @throws */ public static Set<Class<? extends Controller>> getControllerClassSet(String packageName) { Set<Class<? extends Controller>> classSet = new HashSet<Class<? extends Controller>>(); try { Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".", "/")); while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (url != null) { String protocol = url.getProtocol(); if (protocol.equals("file")) { // 转码 String packagePath = URLDecoder.decode(url.getFile(), "UTF-8"); // String packagePath =url.getPath().replaceAll("%20", // ""); // 添加 addControllerClass(classSet, packagePath, packageName); } else if (protocol.equals("jar")) { JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); if (jarURLConnection != null) { JarFile jarFile = jarURLConnection.getJarFile(); if (jarFile != null) { Enumeration<JarEntry> jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith(".class")) { String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")) .replaceAll("/", "."); doAddControllerClass(classSet, className); } } } } } } } } catch (IOException e) { e.printStackTrace(); LOGGER.error("查找包下的类失败{}", e); } return classSet; } private static void addControllerClass(Set<Class<? extends Controller>> classSet, String packagePath, String packageName) { File[] files = new File(packagePath).listFiles(new FileFilter() { public boolean accept(File file) { return (file.isFile() && file.getName().endsWith(".class") || file.isDirectory()); } }); for (File file : files) { String fileName = file.getName(); if (file.isFile()) { String className = fileName.substring(0, fileName.lastIndexOf(".")); if (StringUtils.isNotEmpty(packageName)) { className = packageName + "." + className; LOGGER.error("className: {}", className); } // 添加 doAddControllerClass(classSet, className); } else { // 子目录 String subPackagePath = fileName; if (StringUtils.isNotEmpty(packagePath)) { subPackagePath = packagePath + "/" + subPackagePath; } String subPackageName = fileName; if (StringUtils.isNotEmpty(packageName)) { subPackageName = packageName + "." + subPackageName; } addControllerClass(classSet, subPackagePath, subPackageName); } } } /** * 添加文件到SET集合 * @Title: addClass * @Description: TODO(这里用一句话描述这个方法的作用) * @param @param classSet * @param @param packagePath * @param @param packageName 设定文件 * @return void 返回类型 * @throws */ private static void addClass(Set<Class<?>> classSet, String packagePath, String packageName) { File[] files = new File(packagePath).listFiles(new FileFilter() { public boolean accept(File file) { return (file.isFile() && file.getName().endsWith(".class") || file.isDirectory()); } }); for (File file : files) { String fileName = file.getName(); if (file.isFile()) { String className = fileName.substring(0, fileName.lastIndexOf(".")); if (StringUtils.isNotEmpty(packageName)) { className = packageName + "." + className; LOGGER.error("className: {}", className); } // 添加 doAddClass(classSet, className); } else { // 子目录 String subPackagePath = fileName; if (StringUtils.isNotEmpty(packagePath)) { subPackagePath = packagePath + "/" + subPackagePath; } String subPackageName = fileName; if (StringUtils.isNotEmpty(packageName)) { subPackageName = packageName + "." + subPackageName; } addClass(classSet, subPackagePath, subPackageName); } } } private static void doAddClass(Set<Class<?>> classSet, String className) { Class<?> cls = loadClass(className, false); classSet.add(cls); } private static void doAddControllerClass(Set<Class<? extends Controller>> classSet, String className) { Class<? extends Controller> cls = loadControllerClass(className, false); classSet.add(cls); } }
在DemoConfig主类里面增加方法
/** * 增加controller路由定义 * @param me 路由表 * @param controllerPackageName controller所在的包名 */ private void addControllerAnnoRequestMap(Routes me,String controllerPackageName){ Set<Class<? extends Controller>> claesses=ClassUtil.getControllerClassSet(controllerPackageName); //Set<Class<? extends Controller>> claesses=ClassUtil.getClassSet("com.js.jshop.boot.controller"); for(Class<?> c:claesses){ System.out.println(c.isInstance(Controller.class)); System.out.println(c.getName()); RequestMap requestMap=c.getAnnotation(RequestMap.class); WebDir webDir=c.getAnnotation(WebDir.class); System.out.println(requestMap.name()); System.out.println(webDir.name()); me.add(requestMap.name(),(Class<? extends Controller>) c,webDir.name()); } }
在DemoConfig主类里面的方法configRoute中增加所有扫描的controller类的方法使用
public void configRoute(Routes me){ //对文件夹中的所有的controller进行路径映射,第二个参数是controller的类包 addControllerAnnoRequestMap(me,"com.js.jshop.boot.controller"); }
测试结果
经过测试可以用,望大家指教!~