33、最简单的mvc框架tiny,自动转型TinyMap

痴心易碎 提交于 2020-04-07 04:58:08

前面我说的实现一个自动转型功能的TinyMap,实现思路前面已经说过,我引用下


解决思路: 重写一个TinyMap类继承HashMap。我们实现getInt,getString等方法,调用这些方法可以对类型自动转换,当使用get方法时,其实是调用HashMap的get方法,放回object类型,代码如下: TinyMap tMap = new TinyMap(参); tMap.getInt(key); tMap.getString(key); tMap.get(key);//Ojbect 然后由前置控制器中将页面的参数转换为TinyMap类型(现在转换为HashMap),最后放入action参数中。由于action中参数为map接口,所有对原设计无影响,用户可同时使用HashMap和TinyMap的方法。
TinyMap.java


package tiny;

import java.util.Date;
import java.util.HashMap;

public class TinyMap extends HashMap<String, Object> {

    public TinyMap() {
        super();
    }

    public TinyMap(HashMap<String, Object> map) {
        super();
        this.putAll(map);
    }

    public int getInt(String key) {
        Object value = super.get(key);
        return value != null ? this.converter(value,int.class):null;
    }

    public float getFloat(String key) {
        Object value = super.get(key);
        return value != null ? this.converter(value,float.class):null;
    }

    public long getLong(String key) {
        Object value = super.get(key);
        return value != null ? this.converter(value,long.class):null;
    }

    public double getDouble(String key) {
        Object value = super.get(key);
        return value != null ? this.converter(value,double.class):null;
    }

    public boolean getBoolean(String key) {
        Object value = super.get(key);
        return value != null ? this.converter(value,boolean.class):null;
    }

    public String getString(String key) {
        Object value = super.get(key);
        return value != null ? this.converter(value,String.class):null;
    }

    public Date getTime(String key) {
        Object value = super.get(key);
        return value != null ? this.converter(value,Date.class):null;
    }

    public <T> T getAs(String key, Class<T> custom) {
    	Object value = super.get(key);
        return value != null ? this.converter(value,custom):null;
    }
    
    private <T> T converter(Object value, Class<T> t){
   		return (T) value;
    }
}

思路,上面的代码大家一看就明白了,我在补充几句,TinyMap可以接受 HashMap类型的参数,然后putAll。转型的实现我写了一个泛型方法,通过返回泛型T,来自动转型,泛型T就是传入想要转型的具体类型,然后把value转化为T类型,呵呵。



测试代码

public static void main(String[] args){
    	TinyMap tm = new TinyMap();
    	tm.put("a", 1);
    	tm.put("b","a2");
    	tm.put("c",0.12f);
    	
    	int a = tm.getInt("a");
    	String b = tm.getString("b");
    	float c = tm.getFloat("c");
    	String d = tm.getAs("b", String.class);
    	
    	System.out.println(a);
    	System.out.println(b);
    	System.out.println(c);
    	System.out.println(d);
    }



输出

FrontControl.java修改后

package tiny;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;

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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//@WebFilter(urlPatterns = { "/ty" }, asyncSupported = true)
@WebFilter(urlPatterns = { "/ty/*" })
public class FrontControl implements Filter{
	
	private AtomicBoolean initialized = new AtomicBoolean();
	private ServletContext servletContext;

	@Override
    public void init(final FilterConfig config) throws ServletException{
        try {
            if (initialized.compareAndSet(false, true)) {
            	this.servletContext = config.getServletContext();
                Container.init();
                BindingAop.init();
            }
        }
        catch (Exception e) {
            throw new ServletException("FrontControl init failed.", e);
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws ServletException, IOException{
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        ContextUtil.setActionContext(servletContext, req, res);
        try {
            String[] routes = valid(req);
            if(routes == null){
            	chain.doFilter(request, response);
            	return;
            }
            Object o = Container.getCls(routes[0]);
            if(o == null){
            	chain.doFilter(request, response);
            	return;
            }
            
            Map<String,Object> args = this.converter(req.getParameterMap());
            
            String key = UUID.randomUUID().toString();
            
            Container.inject(o);
            
            this.before(routes,args,key);
            
			Object result = o.getClass().getMethod(routes[1],Map.class).invoke(o,args);
			
			this.after(args,key);
			
			Container.clearReqAops(key);
			
	        if (result==null){
	            return;
	        }
	        if (result instanceof Renderer) {
	            Renderer r = (Renderer) result;
	            r.render(this.servletContext, req, res);
	            return;
	        }
	        if (result instanceof String) {
	            String s = (String) result;
	            if (s.startsWith("/")) {
	                request.getRequestDispatcher(s).forward(request, response);
	                return;
	            }else{
	            	response.getWriter().print(result);
	            }
	        }
			
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
    private Map<String,Object> converter(Map<String,String[]> args){
    	if(args == null){
    		return null;
    	}
        Map<String, Object> params = new TinyMap();
        for(String key : args.keySet()){
        	params.put(key, Arrays.toString(args.get(key)).replaceAll("[\\[\\]\\s,]", ""));
        }
        return params;
    }
    private String[] valid(HttpServletRequest req){
        String uri = req.getRequestURI();
        String path = req.getContextPath();
        if (path != null){
        	uri = uri.substring(path.length());
        }else{
        	return null;
        }
        String[] routes = uri.substring(uri.indexOf("/ty/")+4).split("/");
        if(routes == null || routes.length<2){
        	return null;
        }
        return routes;
    }
    //aop before
    private void before(String[] route,Map<String,Object> args,String key) throws InstantiationException, IllegalAccessException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
    	Aop[] aops = Container.getBeforeBinding(route, key);
    	if(aops != null){
    		for(int a=0;a<aops.length;a++){
    			aops[a].getClass().getMethod("before",Map.class).invoke(aops[a],args);
    		}
    	}
    }
    //aop after
    private void after(Map<String,Object> args,String key) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
    	Aop[] aops = Container.getAfterBinding(key);
    	if(aops != null){
    		for(int a=0;a<aops.length;a++){
    			aops[a].getClass().getMethod("after",Map.class).invoke(aops[a],args);
    		}
    	}
    }
    
    @Override
    public void destroy() {
    }
}





Aop.java

package tiny;

import java.util.Map;

public interface Aop {
    void before(Map<String,Object> args);
    void after(Map<String,Object> args);
    //void before(TinyMap args);
    //void after(TinyMap args);
} 



可以选择,是否使用TinyMap


写Action时同样选择是否使用TinyMap,如下Action中hello方法是用来TinyMap,其他则为Map接口

package web;

import java.util.Map;

import tiny.ContextUtil;
import tiny.JspRenderer;
import tiny.Renderer;
import tiny.TinyMap;

public class TinyTestAction {
	public UserModel user;
	public void hello(TinyMap args){
		
		System.out.println("aa:"+args.getString("aa"));
		System.out.println("访问时间1:"+System.currentTimeMillis());
		//ContextUtil.getContext().getXXX;
	}
	
	public String hello2(Map<String,String> args){
		return "/index.jsp";
	}
	
	public Renderer hello3(Map<String,String> args){
		//数据库
		Map<String,Object> data = user.outStr(args);
		return new JspRenderer("/index.jsp",data);
	}
}



今天不写总结了,本来想写写泛型的,太累了,出差真是辛苦


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!