Servlet - Reasource loading

 

1. Load db3.properties

String path = this.getServletContext().getRealPath("/WEB-INF/classes/db/config/db3.properties");
InputStream in = new FileInputStream(path);
Properties prop = new Properties();
prop.load(in);

2. Load db4.properties

InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/gacl/servlet/study/db4.properties");
Properties prop = new Properties();
prop.load(in);
ClassLoader loader = ServletContextDemo.class.getClassLoader();
InputStream in = loader.getResourceAsStream("gacl/servlet/study/db4.properties");
Properties prop = new Properties();
prop.load(in);

3. Load db2.properties

InputStream in = this.getServletContext().getResourceAsStream("/db2.properties");
Properties prop = new Properties();
prop.load(in);

4. Load db1.properties

InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db1.properties");
Properties prop = new Properties();
prop.load(in);
ClassLoader loader = ServletContextDemo.class.getClassLoader();
InputStream in = loader.getResourceAsStream("db1.properties");
Properties prop = new Properties();
prop.load(in);

在客户端缓存Servlet的输出:

response.setDateHeader("expires",System.currentTimeMillis() + 24 * 3600 * 1000);
response.getOutputStream().write(data.getBytes());

多个Servlet通过ServletContext对象实现数据共享

ServletContext context = this.getServletConfig().getServletContext();
context.setAttribute("data", data);
ServletContext context = this.getServletContext();
String data = (String) context.getAttribute("data");

在web.xml文件中使用<context-param>标签配置WEB应用的初始化参数

<context-param>
   <param-name>url</param-name>
   <param-value>jdbc:mysql://localhost:3306/test</param-value>
</context-param>
ServletContext context = this.getServletContext();
String contextInitParam = context.getInitParameter("url");

用servletContext实现请求转发

ServletContext context = this.getServletContext();
RequestDispatcher rd = context.getRequestDispatcher("/servlet/ServletContextDemo5");
rd.forward(request, response);

 Servlet 3.0 with annotation of @WebServlet @WebInitParam and use reflection

<filter>
        <description>注解处理过滤器</description>
        <filter-name>AnnotationHandleFilter</filter-name>
        <filter-class>me.gacl.web.filter.AnnotationHandleFilter</filter-class>
        <init-param>
            <description>配置要扫描包及其子包, 如果有多个包,以逗号分隔</description>
            <param-name>basePackage</param-name>
            <param-value>me.gacl.web.controller,me.gacl.web.UI</param-value>
            <!-- <param-value>me.gacl.web.controller</param-value> -->
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>AnnotationHandleFilter</filter-name>
        <!-- 拦截后缀是.do的请求 -->
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
View Code
package me.gacl.web.filter;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import me.gacl.annotation.WebInitParam;
import me.gacl.annotation.WebServlet;
import me.gacl.util.ScanClassUtil;

/**
* @ClassName: AnnotationHandleFilter
* @Description: 使用Filter作为注解的处理器
* @author: 孤傲苍狼
* @date: 2014-11-12 下午10:15:19
*
*/ 
public class AnnotationHandleFilter implements Filter {

    private ServletContext servletContext = null;
    
    /* 过滤器初始化时扫描指定的包下面使用了WebServlet注解的那些类
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("---AnnotationHandleFilter过滤器初始化开始---");
        servletContext = filterConfig.getServletContext();
        Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
        //获取web.xml中配置的要扫描的包
        String basePackage = filterConfig.getInitParameter("basePackage");
        //如果配置了多个包,例如:<param-value>me.gacl.web.controller,me.gacl.web.UI</param-value>
        if (basePackage.indexOf(",")>0) {
            //按逗号进行分隔
            String[] packageNameArr = basePackage.split(",");
            for (String packageName : packageNameArr) {
                addServletClassToServletContext(packageName,classMap);
            }
        }else {
            addServletClassToServletContext(basePackage,classMap);
        }
        System.out.println("----AnnotationHandleFilter过滤器初始化结束---");
    }
    
    /**
    * @Method: addServletClassToServletContext
    * @Description:添加ServletClass到ServletContext中
    * @Anthor:孤傲苍狼
    *
    * @param packageName
    * @param classMap
    */ 
    private void addServletClassToServletContext(String packageName,Map<String, Class<?>> classMap){
        Set<Class<?>> setClasses =  ScanClassUtil.getClasses(packageName);
        for (Class<?> clazz :setClasses) {
            if (clazz.isAnnotationPresent(WebServlet.class)) {
                //获取WebServlet这个Annotation的实例
                WebServlet annotationInstance = clazz.getAnnotation(WebServlet.class);
                //获取Annotation的实例的value属性的值
                String annotationAttrValue = annotationInstance.value();
                if (!annotationAttrValue.equals("")) {
                    classMap.put(annotationAttrValue, clazz);
                }
                //获取Annotation的实例的urlPatterns属性的值
                String[] urlPatterns = annotationInstance.urlPatterns();
                for (String urlPattern : urlPatterns) {
                    classMap.put(urlPattern, clazz);
                }
                servletContext.setAttribute("servletClassMap", classMap);
                System.out.println("annotationAttrValue:"+annotationAttrValue);
                String targetClassName = annotationAttrValue.substring(annotationAttrValue.lastIndexOf("/")+1);
                System.out.println("targetClassName:"+targetClassName);
                System.out.println(clazz);
            }
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("---进入注解处理过滤器---");
        //将ServletRequest强制转换成HttpServletRequest
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse res = (HttpServletResponse)response;
        Map<String, Class<?>> classMap = (Map<String, Class<?>>) servletContext.getAttribute("servletClassMap");
        //获取contextPath
        String contextPath = req.getContextPath();
        //获取用户请求的URI资源
        String uri = req.getRequestURI();
        //如果没有指明要调用Servlet类中的哪个方法
        if (uri.indexOf("!")==-1) {
            //获取用户使用的请求方式
            String reqMethod = req.getMethod();
            //获取要请求的servlet路径
            String requestServletName = uri.substring(contextPath.length(),uri.lastIndexOf("."));
            //获取要使用的类
            Class<?> clazz = classMap.get(requestServletName);
            //创建类的实例
            Object obj = null;
            try {
                obj = clazz.newInstance();
            } catch (InstantiationException e1) {
                e1.printStackTrace();
            } catch (IllegalAccessException e1) {
                e1.printStackTrace();
            }
            Method targetMethod = null;
            if (reqMethod.equalsIgnoreCase("get")) {
                try {
                     targetMethod = clazz.getDeclaredMethod("doGet",HttpServletRequest.class,HttpServletResponse.class);
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }else {
                try {
                    targetMethod = clazz.getDeclaredMethod("doPost",HttpServletRequest.class,HttpServletResponse.class);
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
            
            try {
                //调用对象的方法进行处理
                targetMethod.invoke(obj,req,res);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }else {
            //获取要请求的servlet路径
            String requestServletName = uri.substring(contextPath.length(),uri.lastIndexOf("!"));
            //获取要调用的servlet的方法
            String invokeMethodName = uri.substring(uri.lastIndexOf("!")+1,uri.lastIndexOf("."));
        
            //获取要使用的类
            Class<?> clazz = classMap.get(requestServletName);
            //创建类的实例
            Object obj = null;
            try {
                obj = clazz.newInstance();
            } catch (InstantiationException e1) {
                e1.printStackTrace();
            } catch (IllegalAccessException e1) {
                e1.printStackTrace();
            }
            //获得clazz类定义的所有方法
            Method[] methods = clazz.getDeclaredMethods();
            //获取WebServlet这个Annotation的实例
            WebServlet annotationInstance = clazz.getAnnotation(WebServlet.class);
            //获取注解上配置的初始化参数数组
            WebInitParam[] initParamArr = annotationInstance.initParams();
            Map<String, String> initParamMap = new HashMap<String, String>();
            for (WebInitParam initParam : initParamArr) {
                initParamMap.put(initParam.paramName(), initParam.paramValue());
            }
            //遍历clazz类中的方法
            for (Method method : methods) {
                //该方法的返回类型
                Class<?> retType = method.getReturnType();
                //获得方法名
                String methodName = method.getName();
                //打印方法修饰符
                System.out.print(Modifier.toString(method.getModifiers()));
                System.out.print(" "+retType.getName() + " " + methodName +"(");
                //获得一个方法参数数组(getparameterTypes用于返回一个描述参数类型的Class对象数组)
                Class<?>[] paramTypes = method.getParameterTypes();
                for(int j = 0 ; j < paramTypes.length ; j++){
                     //如果有多个参数,中间则用逗号隔开,否则直接打印参数
                    if (j > 0){
                        System.out.print(",");
                    }  
                    System.out.print(paramTypes[j].getName());
                }
                System.out.println(");");
                if (method.getName().equalsIgnoreCase("init")) {
                    try {
                        //调用Servlet的初始化方法
                        method.invoke(obj, initParamMap);
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
            //获取WebServlet这个Annotation的实例
            System.out.println("invokeMethodName:"+invokeMethodName);
            try {
                try {
                    //利用反射获取方法实例,方法的签名必须符合:
                    //public void 方法名(HttpServletRequest request, HttpServletResponse response)
                    //例如:public void loginHandle(HttpServletRequest request, HttpServletResponse response)
                    Method targetMethod = clazz.getDeclaredMethod(invokeMethodName,HttpServletRequest.class,HttpServletResponse.class);
                    //调用对象的方法进行处理
                    targetMethod.invoke(obj,req,res);
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } 
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    public void destroy() {

    }
}
View Code
package me.gacl.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.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ScanClassUtil {

    /**
     * 从包package中获取所有的Class
     * 
     * @param pack
     * @return
     */
    public static Set<Class<?>> getClasses(String pack) {

        // 第一个class类的集合
        Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
        // 是否循环迭代
        boolean recursive = true;
        // 获取包的名字 并进行替换
        String packageName = pack;
        String packageDirName = packageName.replace('.', '/');
        // 定义一个枚举的集合 并进行循环来处理这个目录下的things
        Enumeration<URL> dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(
                    packageDirName);
            // 循环迭代下去
            while (dirs.hasMoreElements()) {
                // 获取下一个元素
                URL url = dirs.nextElement();
                // 得到协议的名称
                String protocol = url.getProtocol();
                // 如果是以文件的形式保存在服务器上
                if ("file".equals(protocol)) {
                    System.err.println("file类型的扫描");
                    // 获取包的物理路径
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    // 以文件的方式扫描整个包下的文件 并添加到集合中
                    findAndAddClassesInPackageByFile(packageName, filePath,
                            recursive, classes);
                } else if ("jar".equals(protocol)) {
                    // 如果是jar包文件
                    // 定义一个JarFile
                    System.err.println("jar类型的扫描");
                    JarFile jar;
                    try {
                        // 获取jar
                        jar = ((JarURLConnection) url.openConnection())
                                .getJarFile();
                        // 从此jar包 得到一个枚举类
                        Enumeration<JarEntry> entries = jar.entries();
                        // 同样的进行循环迭代
                        while (entries.hasMoreElements()) {
                            // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
                            JarEntry entry = entries.nextElement();
                            String name = entry.getName();
                            // 如果是以/开头的
                            if (name.charAt(0) == '/') {
                                // 获取后面的字符串
                                name = name.substring(1);
                            }
                            // 如果前半部分和定义的包名相同
                            if (name.startsWith(packageDirName)) {
                                int idx = name.lastIndexOf('/');
                                // 如果以"/"结尾 是一个包
                                if (idx != -1) {
                                    // 获取包名 把"/"替换成"."
                                    packageName = name.substring(0, idx)
                                            .replace('/', '.');
                                }
                                // 如果可以迭代下去 并且是一个包
                                if ((idx != -1) || recursive) {
                                    // 如果是一个.class文件 而且不是目录
                                    if (name.endsWith(".class")
                                            && !entry.isDirectory()) {
                                        // 去掉后面的".class" 获取真正的类名
                                        String className = name.substring(
                                                packageName.length() + 1, name
                                                        .length() - 6);
                                        try {
                                            // 添加到classes
                                            classes.add(Class
                                                    .forName(packageName + '.'
                                                            + className));
                                        } catch (ClassNotFoundException e) {
                                            // log
                                            // .error("添加用户自定义视图类错误 找不到此类的.class文件");
                                            e.printStackTrace();
                                        }
                                    }
                                }
                            }
                        }
                    } catch (IOException e) {
                        // log.error("在扫描用户定义视图时从jar包获取文件出错");
                        e.printStackTrace();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return classes;
    }
    
    /**
     * 以文件的形式来获取包下的所有Class
     * 
     * @param packageName
     * @param packagePath
     * @param recursive
     * @param classes
     */
    public static void findAndAddClassesInPackageByFile(String packageName,
            String packagePath, final boolean recursive, Set<Class<?>> classes) {
        // 获取此包的目录 建立一个File
        File dir = new File(packagePath);
        // 如果不存在或者 也不是目录就直接返回
        if (!dir.exists() || !dir.isDirectory()) {
            // log.warn("用户定义包名 " + packageName + " 下没有任何文件");
            return;
        }
        // 如果存在 就获取包下的所有文件 包括目录
        File[] dirfiles = dir.listFiles(new FileFilter() {
            // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
            public boolean accept(File file) {
                return (recursive && file.isDirectory())
                        || (file.getName().endsWith(".class"));
            }
        });
        // 循环所有文件
        for (File file : dirfiles) {
            // 如果是目录 则继续扫描
            if (file.isDirectory()) {
                findAndAddClassesInPackageByFile(packageName + "."
                        + file.getName(), file.getAbsolutePath(), recursive,
                        classes);
            } else {
                // 如果是java类文件 去掉后面的.class 只留下类名
                String className = file.getName().substring(0,
                        file.getName().length() - 6);
                try {
                    // 添加到集合中去
                    //classes.add(Class.forName(packageName + '.' + className));
                     //经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
                    classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));  
                    } catch (ClassNotFoundException e) {
                    // log.error("添加用户自定义视图类错误 找不到此类的.class文件");
                    e.printStackTrace();
                }
            }
        }
    }
}
View Code
package me.gacl.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 对java反射中操作的一些封装
 */
public class BeanUtils {
    
    /**
     * 实例化一个class 
     * @param <T>
     * @param clazz Person.class
     * @return
     */
    public static <T> T instanceClass(Class<T> clazz){
        if(!clazz.isInterface()){
            try {
                return clazz.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    
    /**
     * 通过构造函数实例化
     * @param <T>
     * @param ctor
     * @param args
     * @return
     * @throws IllegalArgumentException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static <T> T instanceClass(Constructor<T> ctor, Object... args)
            throws IllegalArgumentException, InstantiationException, 
            IllegalAccessException, InvocationTargetException{
        makeAccessible(ctor);
        return ctor.newInstance(args);//调用构造方法实例化
    }
    
    /**
     * 查找某个class的方法
     * @param clazz
     * @param methodName
     * @param paramTypes
     * @return
     * @throws SecurityException
     * @throws NoSuchMethodException
     */
    public static  Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes){
        try {
            return clazz.getMethod(methodName, paramTypes);
        } catch (NoSuchMethodException e) {
            return findDeclaredMethod(clazz, methodName, paramTypes);//返回共有的方法
        }
    }
    
    public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>[] paramTypes){
        try {
            return clazz.getDeclaredMethod(methodName, paramTypes);
        }
        catch (NoSuchMethodException ex) {
            if (clazz.getSuperclass() != null) {
                return findDeclaredMethod(clazz.getSuperclass(), methodName, paramTypes);
            }
            return null;
        }
    }
    
    public static Method [] findDeclaredMethods(Class<?> clazz){
            return clazz.getDeclaredMethods();
    }
    
    public static void makeAccessible(Constructor<?> ctor) {
        if ((!Modifier.isPublic(ctor.getModifiers()) 
                || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers()))
                && !ctor.isAccessible()) {
            ctor.setAccessible(true);//如果是私有的 设置为true 使其可以访问
        }
    }
    
    public static Field[] findDeclaredFields(Class<?> clazz){
        return clazz.getDeclaredFields();
    }
}
View Code

 

Listener-Class in Web.xml

<listener>
        <listener-class>com.sanlogic.uum.init.SystemSettingContextListener</listener-class>
</listener>
<listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

 

转载于:https://www.cnblogs.com/iiiDragon/p/9881100.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值