Filter实现简陋版MVC

 

先说一下涉及的技术点,filter,servlet,io,反射,Map,注解

整体思路:

一:容器准配

1,先加载properties配置文件, 遍历配置文件中所有的key-value对,key为名,value为类的全路径

2,根据反射创建对象,将对象放入Map容器当中,以配置文件中配置的key作为Map容器的key值,对象作为value

3,遍历map容器,获得对象中的所有field,遍历field数组,如果field字段上有@Resource注解,就根据注解的name值作为key从容器中获得相应对象,然后使用反射将注入到字段当中

4,判断Map容器的key最后一位是否含有%,如果含有说明是一个Controller,获得对象的所有method。遍历中method,获得方法上的注解。如果是@ReuqestMapper注解,则使用注解中的url作为key,Map容器的key加上方法签名作为value,然后放入url映射容器当中,将方法签名作为key,method方法作为value,放入方法映射器中

二:接收请求时的处理思路

1,在web.xml配置filter过滤器,

2,拦截到请求,在处理器映射器中的url映射器查找,如果不存在该key,就放行,存在就拦截

3,拦截后,根据url从处理器映射器中的url映射器获得对应的处理器信息

4,将处理器信息和request,response传给处理器适配器的executeMethod处理

5,executeMethod根据处理器信息,根据参数名和参数类型封装参数并执行相应的方法,获得获得返回结果

6,将返回结果返回给Filter由,filter做转发还是重定向的处理

下面直接撸代码了

代码前奏

由于在封装方法参数时需要方法名作为key,所以需要,jdk1.8以上,如果使用的IDE是Eeclipse需要如下配置

代码正式开撸

/** 
 * 类描述:
 * 作者: xuchang
 * 创建日期:2019年2月28日
 * 修改人:
 * 修改日期:
 * 修改内容:
 * 版本号: 1.0.0   
 */
public class BeanFactory {

    // 存放bean的容器
    private static final Map<Object, Object> map = new HashMap<>();
    // 配置文件的url
    private static String filePath = "bean.properties";
    private static BeanFactory beanFactory = null;
    
    private BeanFactory(){}
    
    private static class GetInstance{
        private static BeanFactory beanFactory = new BeanFactory();
        
        static{
            try {
                // 加载bean
                loadBeanByConfig();
                // 为容器对象自动注入属性
                AttributeResource.beanAttrbuteResource(map);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 静态代码块结束
        
        // 获得内部容器
        private static Map<Object, Object> getBeanContainer(){
            return map;
        }
        
    }
    // 静态内部类结束
    
    
    /**
     * 方法描述:获得单例bean工厂
     *     配置信息默认是存放在src目录下的bean.properties文件
     * @return
     */
    public static BeanFactory getBeanFactory() {
        return GetInstance.beanFactory;
    }
    
    /**
     * 方法描述:获得单例bean工厂
     * @param configPath  存放类元数据配置文件的类路径,
     * @return
     */
    public static BeanFactory getBeanFactory(String configPath) {
        filePath = configPath;
        return GetInstance.beanFactory;
    }
    
    // 获得bean容器
    public Map<Object, Object> getBeanContainer(){
        // GetInstance.getBeanContainer()调用静态方法,由static修饰的属性或方法,一旦加载类被加载类中的静态属性和方法块也会被加载,
        // 所以一旦调用GetInstance.getBeanContainer(),static代码块也会自动加载
        return GetInstance.getBeanContainer();
    }
    
    // 根据name获得bean
    public Object getBean(String name){
        return map.get(name);
    }
    
    // 根据配置文件中bean的元数据信息创建bean并放入容器
    private static void loadBeanByConfig() {
        try {
            // 加载bean元数据配置文件
            Properties config = new Properties();
            config.load(BeanFactory.class.getClassLoader().getResourceAsStream(filePath));
            @SuppressWarnings("rawtypes")
            Enumeration enumNams = config.propertyNames();
            
            while (enumNams.hasMoreElements()) {
                String key = (String) enumNams.nextElement();
                String value = config.getProperty(key);
                
                // 通过反射创建对象
                Class clazz = Class.forName(value);
                Object obj = clazz.newInstance();
                
                // 将对象放入容器中
                map.put(key, obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
}
 

/** 
 * 类描述:属性注入
 * 作者: xuchang
 * 创建日期:2019年2月28日
 * 修改人:
 * 修改日期:
 * 修改内容:
 * 版本号: 1.0.0   
 */
public class AttributeResource {

    /**
     * 为容器中的属性进行属性注入,和方法映射
     * 方法描述:
     * @param map
     * @throws Exception
     */
    public static void beanAttrbuteResource(Map<Object, Object> map) throws Exception{
        
        Set<Entry<Object, Object>> entrys = map.entrySet();
        
        // 遍历容器对象
        for (Entry<Object, Object> entry : entrys) {
            // 获得容器中的bean
            Object obj = entry.getValue();
            
            // 获得对象的class对象
            Class<? extends Object> clazz = obj.getClass();
            // 获得所有字段
            Field[] fields = clazz.getDeclaredFields();
            
            // 遍历字段,并根据注解的name值为字段进行属性注入
            for (Field field : fields) {
                // 判断字段上是否有Resource类型的注解  如果有,为true
                if(field.isAnnotationPresent(Resource.class)){
                    Resource resourceAnno = field.getAnnotation(Resource.class);
                    // resourceAnno.name() 获得字段注解上name的值
                    String name = "".equals(resourceAnno.name())?field.getName():resourceAnno.name();
                    // 设置操作权限为true 可以操作私有属性
                    field.setAccessible(true);
                    
                    Object bean = BeanFactory.getBeanFactory().getBean(name);
                    
                    if(bean!=null){
                        // 向bean的属性中进行属性注入
                        field.set(obj, bean);
                    }else{
                        new RuntimeException("属性注入时:没有找到,名为"+name+"的bean").printStackTrace();
                    }
                    
                }
                
            }
            // 遍历bean字段结束
            
            // 映射容器
            HandleMapper mapper = HandleMapper.getInstance();
            
            //获得容器中bean对象对应的key,并判断key是不是controller
            String key = (String) entry.getKey();
            // 截取key最后一位,并判断是否是 %,如果是说明他是一个web控制器
            if( "%".equals(key.substring(key.length()-1,key.length())) ){
                // 获得他的所有方法
                Method[] methods = clazz.getDeclaredMethods();
                //遍历methods
                for (Method method : methods) {
                    
                    // 存放拼接的方法签名
                    StringBuffer sb = null;
                    
                    method.setAccessible(true);
                    // 判断方法上是否有RequestMapper类型的注解, 
                    // 如果有,将方法上的注解值,url作为key,bean容器的key加上方法名作为value ,然后把它放入url映射map
                    if(method.isAnnotationPresent(RequestMapper.class)){
                        // 获得方法上的注解对象
                        RequestMapper rMapper = method.getAnnotation(RequestMapper.class);
                        String url = rMapper.url();
                        // 获得方法名
                        String methodName = method.getName();
                        
                        // 拼接方法签名
                        sb = new StringBuffer();
                        sb.append(methodName+"(");
                        
                        // 获得方法上所有的参数
                        Parameter[] params = method.getParameters();
                        // 遍历参数列表
                        for (int i=0;i<params.length;i++) {
                            
                            Parameter parameter = params[i];
                            
                            // 获得形参参数类型名
                            String paramTypeName = parameter.getType().getName();
                            // 获得形参名
                            String paramName = parameter.getName();
                            
                            sb.append(paramTypeName+" "+paramName+",");
                        }
                        if( ",".equals( sb.substring(sb.length()-1, sb.length()) ) ) 
                            sb.delete(sb.length()-1, sb.length());
                        
                        sb.append(")");
                        
                        // 放入method方法映射map
                        mapper.putMethod(sb.toString(), method);
                        // 放入属性url映射map
                        mapper.putURL(url, key+sb.toString());
                    }
                    // 注解判断结束
                    
                }
                
                // method方法遍历结束
                
            }
            // 判断是否是web控制器结束
            
        }
        // 遍历容器结束
        
    }
    
}
 

/** 
 * 类描述:Bean工具类
 * 作者: xuchang
 * 创建日期:2019年2月28日
 * 修改人:
 * 修改日期:
 * 修改内容:
 * 版本号: 1.0.0   
 */
public class BeanUtil {

    // 映射容器
    private static final HandleMapper mapper = HandleMapper.getInstance();

    public static Object arrayTransform(String[] values,Class paramType) throws Exception{
        // 获得参数类型名
        String typeName = paramType.getName();
        
        // 动态创建数组
        Object paramValue = Array.newInstance(paramType, values.length);
        
        // 构造器
        Constructor constructor = null;
        
        if( mapper.getConstructorByClassName(typeName)!=null ){// 可以在存放类型集合的map中找到说明是 包装类型或基本类型
            // constructor = BASIC_TYPE_CONSTRUCTOR.get(flag);
            constructor = mapper.getConstructorByClassName(typeName);
        }else{ // TODO: 其他类型
            // 待定
        }
        
        // 通过for循环遍历从中requerst获取的数组, 然后将其中的值进行转换然后动态赋值,paramValue数组动态赋值
        for(int v=0;v<values.length;v++){
            Array.set(paramValue, v, constructor.newInstance(values[v]));
        }
        
        return paramValue;
    }
    
    
    /**
     * 方法描述:将字符串转换成指定的基本类型数据,只有数字类型的可以转换成char类型
     * @param value 被转换的值
     * @param typeName 转换的类型
     * @return
     */
    public static Object basicTypeTran(String value,String paramTypeName){
        if(ToolUtil.isNullOrBlank(value)||ToolUtil.isNullOrBlank(paramTypeName)){
            return null;
        }
        
        Constructor c = mapper.getConstructorByClassName(paramTypeName);
        
        try {
            // 根据相应的参数类型从map中获得相应的构造器
            if("char".equals(paramTypeName)){
                return c.newInstance((char)Integer.parseInt(value));
            }else{
                return c.newInstance(value);
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        
        return null;
    }
    
    
    public static void main(String[] args) {
    }
    
}
 

@Retention(RUNTIME)
@Target(METHOD)
/** 
 * 类描述:
 * 作者: xuchang
 * 创建日期:2019年2月28日
 * 修改人:
 * 修改日期:
 * 修改内容:
 * 版本号: 1.0.0   
 */
public @interface RequestMapper {

    /**
     * 
     * 方法描述:注入的值得名称
     * @return
     */
    String url() default "";
    
}

 

/** 
 * 类描述:
 * 作者: xuchang
 * 创建日期:2019年2月28日
 * 修改人:
 * 修改日期:
 * 修改内容:
 * 版本号: 1.0.0   
 */
@Retention(RUNTIME)
@Target(FIELD)
public @interface Resource {
    /**
     * 
     * 方法描述:注入的值得名称
     * @return
     */
    String name() default "";
}

 

/** 
 * 类描述:
 * 作者: xuchang
 * 创建日期:2019年2月28日
 * 修改人:
 * 修改日期:
 * 修改内容:
 * 版本号: 1.0.0   
 */
public class HandleMapper{
    
    private HandleMapper(){}
    
    private static final HandleMapper HANDLE_MAPPER = new HandleMapper();
    
    // url映射器  key:url value:类名%方法签名
    private static final Map<String, Object> URL_MAAPPER = new HashMap<>();
    
    // method映射器  key:方法签名 value:method对象
    private static final Map<String, Method> METHOD_MAAPPER = new HashMap<>();
    
    // 存放基本类型和包装类的有参构造器
    @SuppressWarnings("rawtypes")
    private final static Map<String,Constructor> BASIC_TYPE_CONSTRUCTOR = new HashMap<>();
    // 存放基本类型和包装类的有参构造器
    @SuppressWarnings("rawtypes")
    private final static Map<String,Class> BASIC_TYPE = new HashMap<>();
    static{
        
        try {
            BASIC_TYPE_CONSTRUCTOR.put(Byte.class.getName(), Byte.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put(Character.class.getName(), Character.class.getDeclaredConstructor(char.class));
            BASIC_TYPE_CONSTRUCTOR.put(Short.class.getName(), Short.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put(Integer.class.getName(), Integer.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put(Long.class.getName(), Long.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put(Float.class.getName(), Float.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put(Double.class.getName(), Double.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put(Boolean.class.getName(), Boolean.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put("byte", Byte.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put("char", Character.class.getDeclaredConstructor(char.class));
            BASIC_TYPE_CONSTRUCTOR.put("short", Short.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put("int", Integer.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put("long", Long.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put("float", Float.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put("double", Double.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put("boolean", Boolean.class.getDeclaredConstructor(String.class));
            BASIC_TYPE_CONSTRUCTOR.put("java.lang.String", String.class.getDeclaredConstructor(String.class));
            
            BASIC_TYPE.put(Byte.class.getName(), Byte.class);
            BASIC_TYPE.put(Character.class.getName(), Character.class);
            BASIC_TYPE.put(Short.class.getName(), Short.class);
            BASIC_TYPE.put(Integer.class.getName(), Integer.class);
            BASIC_TYPE.put(Long.class.getName(), Long.class);
            BASIC_TYPE.put(Float.class.getName(), Float.class);
            BASIC_TYPE.put(Double.class.getName(), Double.class);
            BASIC_TYPE.put(Boolean.class.getName(), Boolean.class);
            BASIC_TYPE.put("java.lang.String", String.class);
            BASIC_TYPE.put("byte", Byte.class);
            BASIC_TYPE.put("char", Character.class);
            BASIC_TYPE.put("short", Short.class);
            BASIC_TYPE.put("int", Integer.class);
            BASIC_TYPE.put("long", Long.class);
            BASIC_TYPE.put("float", Float.class);
            BASIC_TYPE.put("double", Double.class);
            BASIC_TYPE.put("boolean", Boolean.class);
            BASIC_TYPE.put("[B", byte.class);
            BASIC_TYPE.put("[C", char.class);
            BASIC_TYPE.put("[S", short.class);
            BASIC_TYPE.put("[I", int.class);
            BASIC_TYPE.put("[J", long.class);
            BASIC_TYPE.put("[F", float.class);
            BASIC_TYPE.put("[D", double.class);
            BASIC_TYPE.put("[Z", boolean.class);
        } catch (NoSuchMethodException | SecurityException e) {
            e.printStackTrace();
        }
    }
    
    
    public static HandleMapper getInstance(){
        return HANDLE_MAPPER;
    }

    public Object getClassInfoByURL(String url){
        return URL_MAAPPER.get(url);
    }

    public Object putURL(String key, String value) {
        return URL_MAAPPER.put(key, value);
    }
    
    /**
     * 
     * 方法描述:根据方法签名获得方法
     * @param methodSignature
     * @return
     *         方法签名对应的方法
     */
    public Method getMethodSignatureByMethod(String methodSignature){
        return METHOD_MAAPPER.get(methodSignature);
    }

    /**
     * 
     * 方法描述:将方法放入方法映射容器当中
     * @param key  方法签名
     * @param value  method对象
     * @return
     *         放入的方法
     */
    public Method putMethod(String key, Method value) {
        return METHOD_MAAPPER.put(key, value);
    }
    
    /**
     * 
     * 方法描述:通过基本类型或String类型的完整类名字符串获得该类型的有参构造器
     * @param className 类名
     * @return
     *     该类型的构造器
     */
    public Constructor getConstructorByClassName(String className) {
        return BASIC_TYPE_CONSTRUCTOR.get(className);
    }
    
    /**
     * 
     * 方法描述:将构造器放入map对象中
     * @param key 完整类名
     * @param value 构造器
     * @return
     */
    public Constructor putConstructorMap(String key,Constructor value) {
        return BASIC_TYPE_CONSTRUCTOR.put(key, value);
    }
    
    /**
     * 
     * 方法描述:将类对象放入映射器中
     * @param className 完整类名
     * @param clazz Class对象
     * @return
     */
    public Class putClassMap(String className,Class clazz) {
        return BASIC_TYPE.put(className, clazz);
    }
    
    /**
     * 
     * 方法描述:根据完整类名获得类对象
     * @param className 完整类名
     * @return
     */
    public Class getClassMap(String className) {
        return BASIC_TYPE.get(className);
    }
    
}
 

/** 
 * 类描述:
 * 作者: xuchang
 * 创建日期:2019年2月28日
 * 修改人:
 * 修改日期:
 * 修改内容:
 * 版本号: 1.0.0   
 */
public class HandleAdapter {
    
    private HandleAdapter(){}
    
    private BeanFactory beanFactory = BeanFactory.getBeanFactory();
    
    private static final HandleAdapter HANDLE_ADAPTER = new HandleAdapter();
    
    // 映射容器
    private static final HandleMapper mapper = HandleMapper.getInstance();
    
    public static HandleAdapter getInstance(){
        return HANDLE_ADAPTER;
    }
    
    @SuppressWarnings({ "rawtypes", "unused" })
    public Object executeMethod(HttpServletRequest request, HttpServletResponse response,String info,String separator){
        // 将信息进行分割,下标0表示对象在Bean中的key,下标1表示 请求对应的方法
        String[] classInfo = info.split(separator);
        // 获得对应的对象
        Object obj = beanFactory.getBean(classInfo[0]+"%");
        
        try {
            Class clazz = obj.getClass();
            // Method method = clazz.getDeclaredMethod(classInfo[1], HttpServletRequest.class,HttpServletResponse.class);
            // 从方法映射器中根据方法签名获得method
            Method method = mapper.getMethodSignatureByMethod(classInfo[1]);
            Object[] paramsValue = getMethodParams(request,response,method);
            // 通过反射执行方法
            return method.invoke(obj, paramsValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
    @SuppressWarnings({ "rawtypes", "unused", "unchecked" })
    public Object[] getMethodParams(HttpServletRequest request, HttpServletResponse response,Method method) throws Exception{
        // 获得方法上所有的参数
        Parameter[] params = method.getParameters();
        // 存放参数列表
        Object[] paramValues = new Object[params.length];
        
        if(params==null||params.length==0){
            return null;
        }
        
        // 遍历参数列表
        for (int i=0;i<params.length;i++) {
            
            Parameter parameter = params[i];
            
            // 获得参数类型
            Class paramType = parameter.getType();
            // 获得参数类型名
            String paramTypeName = paramType.getName();
            // 存放创建的形参参数
            String paramName = parameter.getName();
            // 存放创建的形参参数
            Object paramValue = null;
            
            if( paramType.isAssignableFrom(response.getClass()) ){
                paramValue = response;
            }else if( paramType.isAssignableFrom(request.getClass()) ) {
                paramValue = request;
            }else{ // 其他类型对象
                paramValue = getParamValue(request,paramType,paramName);
            }
            
            paramValues[i] = paramValue;
            
        }
        
        return paramValues;
    }
    
    
    /**
     * 
     * 方法描述:从请求中获得指定参数
     * @param request  HttpServletRequest 请求对象
     * @param paramType 参数类型的类对象
     * @param paramName 参数名
     * @return
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public Object getParamValue(HttpServletRequest request,Class paramType,String paramName) throws Exception{
        
        // 获得参数类型名
        String paramTypeName = paramType.getName();
        // 存放创建的形参参数
        Object paramValue = null;
        // 根据方法形参名或属性名,从request中获得参数
        String[] values = request.getParameterValues(paramName);
        
        // 判断形参是不是基本类型获得包装类型
        if( mapper.getClassMap(paramTypeName)!=null ){
            if("java.lang.String".equals(paramTypeName)){
                paramValue = values.length==1?values[0]:Arrays.toString(values);
            }else if (values.length==1) {
                // 创建对象 ,并向对象设置值
                paramValue = BeanUtil.basicTypeTran(values[0],paramTypeName);
            }else{
                // 创建对象 ,并向对象设置值
                paramValue = BeanUtil.basicTypeTran(Arrays.toString(values),paramTypeName);
            }
            
        }else if( paramType.isArray() ){// 判断反射对象是不是数组类型 是返回true
            
            //基本数据类型名字的格式[J 引用类型的数据格式 [Ljava.lang.Integer,所以只要从格式的第二位一直截取到最后一位,如果为空就是基本类型
            String flag = paramTypeName.substring(2, paramTypeName.length()).replace(";", "");
            
            if(flag.length()==0){ //基本数据类型
                Class type = mapper.getClassMap(paramTypeName);
                paramValue = BeanUtil.arrayTransform(values, type);
            }else{ // 包装数据类型
                
                // 如果是基本类型或包装类就直接从BASIC_TYPE中获取,如果不是;利用完整类名直接创建一个Class
                Class type = mapper.getClassMap(paramTypeName)!=null?mapper.getClassMap(paramTypeName):Class.forName(flag);
                paramValue = BeanUtil.arrayTransform(values, type);
            }
        }else{ // 其他类型对象
            paramValue = getBean(request,paramType);
            
        }
        
        return paramValue;
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes"})
    public Object getBean(HttpServletRequest request,Class clazz){
        Object bean = null;
        
        try {
            bean = clazz.newInstance();
            // 获得类中所有的字段
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String name = field.getName();
                
                if( !ToolUtil.isNullOrBlank(request.getParameter(name)) ){
                    Class fieldClazz = (Class) field.getGenericType();
                    Object value = getParamValue(request, fieldClazz, name);
                    
                    // 拼接set方法
                    Method method = clazz.getMethod("set"+( 
                            name.substring(0, 1).toUpperCase()+name.substring(1, name.length())
                            ), fieldClazz);
                    method.invoke(bean, value);
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return bean;
    }
    
}

 

/** 
 * 类描述:中央控制器
 * 作者: xuchang
 * 创建日期:2019年3月1日
 * 修改人:
 * 修改日期:
 * 修改内容:
 * 版本号: 1.0.0   
 */
public class ControllerFilter implements Filter{

    // 重定向
    private static final String REDIRECT = "redirect";
    
    // 转发(默认)
    private static final String FORWARD = "forward";
    
    // 配置文件存放的类路径
    private static final String CONFIG_PATH = "config_path";
    
    // 编码格式
    @SuppressWarnings("unused")
    private static final String CHARACTER_ENCODING = "character_encoding";
    
    @SuppressWarnings("unused")
    private String encoding = "utf-8";
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        String path = filterConfig.getInitParameter(CONFIG_PATH);
        String encoding = filterConfig.getInitParameter(CONFIG_PATH);
        
        if(StringUtils.isNotBlank(path)){
            // 初始化容器
            @SuppressWarnings("unused")
            BeanFactory beanFactory = BeanFactory.getBeanFactory(path);
        }else{
            // 初始化容器
            @SuppressWarnings("unused")
            BeanFactory beanFactory = BeanFactory.getBeanFactory();
        }
        
        if(StringUtils.isNotBlank(encoding)){
            this.encoding = encoding;
        }
        
    }
    

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        request = requestEncoding(request,response);
        
        response.setContentType("text/html;charset=utf-8");
        // 如果servlet-mapper配置为/*使用servletPath()的路径为空,使用request.getPathInfo()可以获得值
        // servlet-mapper配置不为/*,request.getPathInfo()获得值为空,servletPath()可以获得值
        //获得请求的相对url  
        String url = request.getServletPath();
        url = StringUtils.isNotBlank(url)?url:request.getPathInfo();
        // 根据请求获得类信息,以及方法中间以%分割
        String info = (String) HandleMapper.getInstance().getClassInfoByURL(url);
        
        // 如果info为空,说明在映射器中没有这个路径
        if(info!=null){
            // 通过适配找到指定的方法 并执行
            Object object = HandleAdapter.getInstance().executeMethod(request, response, info, "%");
            
            // object不为空说明有返回值
            if(object!=null){
                System.err.println( object.getClass() );
                // 查看返回值类型 如果是字符串说明是返回值得路径
                if(object instanceof String){
                    // 元素0是转发或重定向方式, 元素1的是地址,如果只有一个元素则是请求地址,默认是转发方式
                    String[] strings = ((String)object).split(":");
                    if(REDIRECT.equals(strings[0].trim())){
                        response.sendRedirect(strings[1]);
                        return;
                    };
                    
                    request.getRequestDispatcher( FORWARD.equals(strings[0].trim())?strings[1]:strings[0] ).forward(request, response);
                    return;
                }
                // 字符串判断结束
            }
        }else{
            // 放行
            chain.doFilter(request, response);
        }
        
    }

    /**
     * 方法描述:处理请求参数乱码
     * @param request
     * @param response
     * @return
     */
    public HttpServletRequest requestEncoding(HttpServletRequest request,HttpServletResponse response) {
        return (HttpServletRequest)Proxy.newProxyInstance(request.getClass().getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
            
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 获得执行方法的方法名
                String methodName = method.getName();
                //如果是getParameter方法,进行代理
                if("getParameter".equals(method)){
                    // 获得请求的方式 post直接放行,get进行乱码处理
                    String type = request.getMethod();
                    if("get".equalsIgnoreCase(type)){
                        String result = (String) method.invoke(request, args);
                        return new String(result.getBytes("ISO-8859-1"),"UTF-8");
                    } else if("post".equalsIgnoreCase(type)){
                        // 放行
                        request.setCharacterEncoding("utf-8");
                        return method.invoke(request, args);
                    }
                }
                // 放行
                return method.invoke(request, args);
                
            }
        });
            
    }
    
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

}

配置文件是properties后缀名默认是放在sec目录下,

格式普通的bean直接写key即可,controller的后缀要加上 %

userService=com.hpe.service.impl.UserServiceimpl
userDao=com.hpe.dao.impl.UserDaoImpl

# web
userController%=com.hpe.controller.UserController
userLoginController%=com.hpe.controller.UserLoginController

 

 

 

PS:并没有加上日期类型的处理等

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值