前面我说的实现一个自动转型功能的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);
}
写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);
}
}
来源:oschina
链接:https://my.oschina.net/u/933274/blog/223261