一:

对于springMVC的controller,有时候会需要记录里面接口映射的信息。比如:

@Controller
public class RoleManagementController {
......
/*
     * 初始化角色页面
     */
    @RequestMapping(value = "rolesList.s", method = RequestMethod.GET)
    @TestAno(name = "角色列表页面", remark = "角色列表页面")
    public String rolesListGet(Model model) {
......
}

这时,我需要读取映射值等信息。我们可以在web.xml文件中添加一个servlet:


        testInitialServlet
        com.yc.web.TestInitialServlet
        10
        
            switcher
            true
        

二:

如果有需要过滤掉的接口映射,可以首先配置一个过滤文件moduleFilter.xml:



    
    
    
    

处理类TestInitialServlet中通过如下方法处理:

private Set initFilteredModuleList(ApplicationContext context) {
        Set hsFilterUrls = new HashSet();
        try {
            Document document = new SAXReader().read(this.getClass().getClassLoader().getResourceAsStream("moduleFilter.xml"));
            List filteredItems = (List)document.selectNodes("//filter-modules/item");
            for(Element item : filteredItems) {
                String type = item.attributeValue("type");
                String value = item.attributeValue("value");
                if("url".equals(type)) {
                    hsFilterUrls.add(value);
                } else if("class".equals(type)) {
                    Class clazz = Class.forName(value);
                    Method[] methods = clazz.getMethods();
                    for(Method method : methods) {
                        if(method.isAnnotationPresent(RequestMapping.class)) {
                            RequestMapping mapping = method.getAnnotation(RequestMapping.class);
                            for(String url : mapping.value()) {
                                hsFilterUrls.add("/" + url);
                            }
                        }
                    }
                } else if("package".equals(type)) {
                    List classList = ReflectionUtil.getClassesByPackageName(value);
                    for(Class clazz : classList) {
                        Method[] methods = clazz.getMethods();
                        for(Method method : methods) {
                            if(method.isAnnotationPresent(RequestMapping.class)) {
                                RequestMapping mapping = method.getAnnotation(RequestMapping.class);
                                for(String url : mapping.value()) {
                                    hsFilterUrls.add("/" + url);
                                }
                            }
                        }
                    }
                }
            }
        } catch (DocumentException e) {
            logger.error("parse xml file faied!!!", e);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return hsFilterUrls;
    }

当然还需要引入相应jar包:

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.WebApplicationContext;

上述方法就是解析moduleFilter.xml文件得到可过滤掉的接口映射并保存。

三:

接下来,我们又可能附加一些controller没有的一些接口映射。这时候依然可把它们保存在一个xml文件中,比如initInfo.xml:



    
        
        
    

四:

此时,我们既有了要过滤的映射,也有了要附加的映射,那我们只需要扫描所有controller的mapping,并去掉要过滤的映射、加上要附加的映射就是了。整个类文件TestInitialServlet.java如下:

public class TestInitialServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        String switcher = config.getInitParameter("switcher");
        if("true".equals(switcher)) {
            ApplicationContext context = (ApplicationContext)config.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
            Set filterModuleList = initFilteredModuleList(context);
            initModuleList(context, filterModuleList);
        }
    }
                                                                            
    private Set initFilteredModuleList(ApplicationContext context) {
        Set hsFilterUrls = new HashSet();
        try {
            Document document = new SAXReader().read(this.getClass().getClassLoader().getResourceAsStream("moduleFilter.xml"));
            List filteredItems = (List)document.selectNodes("//filter-modules/item");
            for(Element item : filteredItems) {
                String type = item.attributeValue("type");
                String value = item.attributeValue("value");
                if("url".equals(type)) {
                    hsFilterUrls.add(value);
                } else if("class".equals(type)) {
                    Class clazz = Class.forName(value);
                    Method[] methods = clazz.getMethods();
                    for(Method method : methods) {
                        if(method.isAnnotationPresent(RequestMapping.class)) {
                            RequestMapping mapping = method.getAnnotation(RequestMapping.class);
                            for(String url : mapping.value()) {
                                hsFilterUrls.add("/" + url);
                            }
                        }
                    }
                } else if("package".equals(type)) {
                    List classList = ReflectionUtil.getClassesByPackageName(value);
                    for(Class clazz : classList) {
                        Method[] methods = clazz.getMethods();
                        for(Method method : methods) {
                            if(method.isAnnotationPresent(RequestMapping.class)) {
                                RequestMapping mapping = method.getAnnotation(RequestMapping.class);
                                for(String url : mapping.value()) {
                                    hsFilterUrls.add("/" + url);
                                }
                            }
                        }
                    }
                }
            }
        } catch (DocumentException e) {
            logger.error("parse xml file faied!!!", e);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return hsFilterUrls;
    }
                                                                            
    private void initModuleList(ApplicationContext context, Set filterModuleList) {
        logger.info("now begin initial module list");
        Map map = context.getBeansWithAnnotation(Controller.class);
        Map serial2DBMap = new HashMap();
        for(String beanName : map.keySet()) {
            Object bean = map.get(beanName);
            Method[] methods = bean.getClass().getMethods();
            for(Method method : methods) {
                if(method.isAnnotationPresent(RequestMapping.class)) {
                    RequestMapping mapping = method.getAnnotation(RequestMapping.class);
                    String[] urls = mapping.value();
                    String name = null;
                    String remark = null;
                    if(method.isAnnotationPresent(TestAno.class)) {
                        TestAno security = method.getAnnotation(TestAno.class);
                        name = security.name();
                        remark = security.remark();
                    }
                    for(String url : urls) {
                        if(filterModuleList.contains("/" + url)) {
                            logger.info("filtered url: [" + url + "]");
                            continue;
                        }
                        logger.info("initial module url: [/" + url + "], name: [" + name + "], remark: [" + remark + "]");
                        Modules module = new Modules();
                        module.setModuleName(name == null ? "/" + url : name);
                        module.setModuleUrl("/" + url);
                        module.setRemark(remark);
                        module.setStatus(CommonCondition.STATUS_TYPE_NORMAL);
                        serial2DBMap.put("/" + url, module);
                    }
                }
            }
        }
        try {
            Document document = new SAXReader().read(this.getClass().getClassLoader().getResourceAsStream("initInfo.xml"));
            List moduleNodes = (List)document.selectNodes("//init-info/modules/module");
            for(Element moduleNode : moduleNodes) {
                String moduleName = moduleNode.attributeValue("name");
                String moduleUrl = moduleNode.attributeValue("url");
                if(filterModuleList.contains(moduleUrl)) {
                    logger.info("filtered url: [" + moduleUrl + "]");
                    continue;
                }
                String remark = moduleNode.attributeValue("remark");
                Modules module = new Modules();
                module.setModuleName(moduleName);
                module.setModuleUrl(moduleUrl);
                module.setRemark(remark);
                module.setStatus(CommonCondition.STATUS_TYPE_NORMAL);
                serial2DBMap.put(moduleUrl, module);
            }
        } catch (DocumentException e) {
            logger.error("parse xml file faied!!!", e);
        }
        dao.serialModuleList2DB(serial2DBMap);
        logger.info("initial module list finish");
    }
}

五:    

   上述代码中包含一个Modules类,该类是一个持久化对象类,可根据实际需求进行替换。

   另外,我们自建了一个annotation---“TestAno”,对它的定义如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface TestAno {
                                      
    public String name();
    public String remark();
                                      
}

   根据上述步骤,我们就实现了从配置文件读要过滤的映射和要添加的映射,并扫描controller中的映射,影响保存。后面就可以自己写方法来进行数据库存储,或者别的操作了!