MVC丶 (未完待续······)

package cn.sm.servlet;  

import java.io.IOException;  
import java.io.PrintWriter;  

import javax.servlet.ServletConfig;  
import javax.servlet.ServletException;  
import javax.servlet.annotation.MultipartConfig;  
import javax.servlet.annotation.WebInitParam;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

import cn.sm.action.Action;  
import cn.sm.action.ActionResult;  
import cn.sm.action.ResultContent;  
import cn.sm.util.CommonUtil;  

/** 
 * 前端控制器(门面模式[提供用户请求的门面]) 
 * @author 微冷的风 
 * 
 */  
@WebServlet(urlPatterns = { "*.do" }, loadOnStartup = 0,   
        initParams = {   
            @WebInitParam(name = "packagePrefix", value = "cn.sm.action."),  
            @WebInitParam(name = "jspPrefix", value = "/WEB-INF/jsp/"),  
            @WebInitParam(name = "actionSuffix", value = "Action")  
        }  
)  
@MultipartConfig  
public class FrontController extends HttpServlet {  
    private static final long serialVersionUID = 1L;  

    private static final String DEFAULT_PACKAGE_NAME = "cn.sm.action.";  
    private static final String DEFAULT_JSP_PATH = "/WEB-INF/content/";  
    private static final String DEFAULT_ACTION_NAME = "Action";  

    private String packagePrefix = null;        // 包名的前缀  
    private String jspPrefix = null;            // JSP页面路径的前缀  
    private String actionSuffix = null;         // Action类名的后缀  

    @Override  
    public void init(ServletConfig config) throws ServletException {  
        String initParam = config.getInitParameter("packagePrefix");  
        packagePrefix = initParam != null ? initParam :  DEFAULT_PACKAGE_NAME;  
        initParam = config.getInitParameter("jspPrefix");  
        jspPrefix = initParam != null ? initParam : DEFAULT_JSP_PATH;  
        initParam = config.getInitParameter("actionSuffix");  
        actionSuffix = initParam != null ? initParam : DEFAULT_ACTION_NAME;  
    }  

    @Override  
    protected void service(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        String contextPath = req.getContextPath() + "/";  
        String servletPath = req.getServletPath();  

        try {  
            Action action = (Action) Class.forName(getFullActionName(servletPath)).newInstance();  
            ActionResult actionResult = action.execute(req, resp);  
            ResultContent resultContent = actionResult.getResultContent();  
            switch(actionResult.getResultType()) {  
            case Redirect:  
                resp.sendRedirect(contextPath + resultContent.getUrl());  
                break;  
            case Forward:  
                req.getRequestDispatcher(getFullJspPath(servletPath) + resultContent.getUrl())  
                        .forward(req, resp);  
                break;  
            case Ajax:  
                PrintWriter pw = resp.getWriter();  
                pw.println(resultContent.getJson());  
                pw.close();  
                break;  
            case Chain:  
                req.getRequestDispatcher(contextPath + resultContent.getUrl())  
                        .forward(req, resp);  
                break;  
            case RedirectChain:  
                resp.sendRedirect(contextPath + resultContent.getUrl());  
                break;  
            default:  
            }  
        }   
        catch (Exception e) {  
            e.printStackTrace();  
            resp.sendRedirect("error.html");  
        }  
    }  

    // 根据请求的小服务路径获得对应的Action类的名字  
    private String getFullActionName(String servletPath) {  
        int start = servletPath.lastIndexOf("/") + 1;  
        int end = servletPath.lastIndexOf(".do");  
        return packagePrefix + getSubPackage(servletPath) + CommonUtil.capitalize(servletPath.substring(start, end)) + actionSuffix;  
    }  

    // 根据请求的小服务路径获得对应的完整的JSP页面路径  
    private String getFullJspPath(String servletPath) {  
        return jspPrefix + getSubJspPath(servletPath);  
    }  

    // 根据请求的小服务路径获得子级包名  
    private String getSubPackage(String servletPath) {  
        return getSubJspPath(servletPath).replaceAll("\\/", ".");  
    }  

    // 根据请求的小服务路径获得JSP页面的子级路径  
    private String getSubJspPath(String servletPath) {  
        int start = 1;  
        int end = servletPath.lastIndexOf("/");  
        return end > start ? servletPath.substring(start, end > 0 ? end + 1 : 0) : "";  
    }  

}  

定义Action类的接口

package cn.sm.util;  


/** 
 * 数据库会话工厂 
 * @author 微冷的风
 * 
 */  
public class DbSessionFactory {  
    private static final ThreadLocal<DbSession> threadLocal = new ThreadLocal<DbSession>();  

    private DbSessionFactory() {  
        throw new AssertionError();  
    }  

    /** 
     * 打开会话 
     * @return DbSession对象 
     */  
    public static DbSession openSession() {  
        DbSession session = threadLocal.get();  

        if(session == null) {  
            session = new DbSession();  
            threadLocal.set(session);  
        }  

        session.open();  

        return session;  
    }  

    /** 
     * 关闭会话 
     */  
    public static void closeSession() {  
        DbSession session = threadLocal.get();  
        threadLocal.set(null);  

        if(session != null) {  
            session.close();  
        }  
    }  

}  

         
 现在,前端控制器还不可知支撑文件上传。Java Web应用之文书上传在Servlet
3.0正经在此以前,需自己编排代码在Servlet中经分析输入流来找到上传文件的数额,虽有第三正工具(如commons-fileupload)经封装了这么些操作,一Web规范着并未公文上传的API是不是怪抓笑?好当Servlet
3.0挨爆发矣@MultiConfig注明可以为Servlet提供文件上传的匡助,而且通过请对象的getPart或getParts方法而收获上传的数码,这样处理文件上传就卓殊有益了。

package cn.sm.action;  

import javax.servlet.http.Part;  

/** 
 * 支持文件上传的接口 
 * @author 微冷的风
 * 
 */  
public interface Uploadable {  

    /** 
     * 设置文件名 
     * @param filenames 文件名的数组 
     */  
    public void setFilenames(String[] filenames);  

    /** 
     * 设置上传的附件 
     * @param parts 附件的数组 
     */  
    public void setParts(Part[] parts);  

}  

 

 

再也写一个家伙类来封装常用的工具方法

package cn.sm.util;  

public interface TypeConverter {  

    public Object convert(Class<?> elemType, String value) throws Exception;  
} 

package cn.sm.util;  

import java.lang.reflect.Constructor;  
import java.lang.reflect.Field;  
import java.lang.reflect.Modifier;  
import java.util.ArrayList;  
import java.util.List;  

/** 
 * 反射工具类 
 * @author 微冷的风 
 * 
 */  
public class ReflectionUtil {  

    private ReflectionUtil() {  
        throw new AssertionError();  
    }  

    /** 
     * 根据字段名查找字段的类型 
     * @param target 目标对象 
     * @param fieldName 字段名 
     * @return 字段的类型 
     */  
    public static Class<?> getFieldType(Object target, String fieldName) {  
        Class<?> clazz = target.getClass();  
        String[] fs = fieldName.split("\\.");  

        try {  
            for(int i = 0; i < fs.length - 1; i++) {  
                Field f = clazz.getDeclaredField(fs[i]);  
                target = f.getType().newInstance();  
                clazz = target.getClass();  
            }  
            return clazz.getDeclaredField(fs[fs.length - 1]).getType();  
        }  
        catch(Exception e) {  
                // throw new RuntimeException(e);  
        }  
        return null;  
    }  

    /** 
     * 获取对象所有字段的名字 
     * @param obj 目标对象 
     * @return 字段名字的数组 
     */  
    public static String[] getFieldNames(Object obj) {  
        Class<?> clazz = obj.getClass();  
        Field[] fields = clazz.getDeclaredFields();  
        List<String> fieldNames = new ArrayList<>();  
        for(int i = 0; i < fields.length; i++) {  
            if((fields[i].getModifiers() & Modifier.STATIC) == 0) {  
                fieldNames.add(fields[i].getName());  
            }  
        }  
        return fieldNames.toArray(new String[fieldNames.size()]);  
    }  

    /** 
     * 通过反射取对象指定字段(属性)的值 
     * @param target 目标对象 
     * @param fieldName 字段的名字 
     * @throws 如果取不到对象指定字段的值则抛出异常 
     * @return 字段的值 
     */  
    public static Object getValue(Object target, String fieldName) {  
        Class<?> clazz = target.getClass();  
        String[] fs = fieldName.split("\\.");  

        try {  
            for(int i = 0; i < fs.length - 1; i++) {  
                Field f = clazz.getDeclaredField(fs[i]);  
                f.setAccessible(true);  
                target = f.get(target);  
                clazz = target.getClass();  
            }  

            Field f = clazz.getDeclaredField(fs[fs.length - 1]);  
            f.setAccessible(true);  
            return f.get(target);  
        }  
        catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * 通过反射给对象的指定字段赋值 
     * @param target 目标对象 
     * @param fieldName 字段的名称 
     * @param value 值 
     */  
    public static void setValue(Object target, String fieldName, Object value) {  
        Class<?> clazz = target.getClass();  
        String[] fs = fieldName.split("\\.");  
        try {  
            for(int i = 0; i < fs.length - 1; i++) {  
                Field f = clazz.getDeclaredField(fs[i]);  
                f.setAccessible(true);  
                Object val = f.get(target);  
                if(val == null) {  
                    Constructor<?> c = f.getType().getDeclaredConstructor();  
                    c.setAccessible(true);  
                    val = c.newInstance();  
                    f.set(target, val);  
                }  
                target = val;  
                clazz = target.getClass();  
            }  

            Field f = clazz.getDeclaredField(fs[fs.length - 1]);  
            f.setAccessible(true);  
            f.set(target, value);  
        }  
        catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  

}  

                       
                                                                       
                                     

                  
 梦想而看了是小随 能够兑现自己之MVC框架   

 ActionResult类中之ResultType代表了针对用户请求处理后怎样为浏览器暴发响应,是一个枚举类型,代码如下所示。

 

 

         
让前者控制器在条分缕析用户请求的略劳路径时,将请求路径和Action类的包和JSP页面的路子对应起来,如用户要的小劳路径是/user/order/save.do,对应的Action类的完全限定名就是cn.sm.action.user.order.SaveAction,如需要过反到ok.jsp页面,这JSP页面的默认路径是/WEB-INF/jsp/user/order/ok.jsp。这样做才会满意对项目模块举行私分的求,而休是拿装有的Action类都放在一个包中,把有的JSP页面都位居一个路子下。

 

   
业务逻辑对象的厂子类,仍是用约定优于配备的章程,代码如下。

package cn.sm.servlet;  

import java.io.IOException;  

import javax.servlet.ServletException;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

@WebServlet("*.do")  
public class FrontController extends HttpServlet {  
    private static final long serialVersionUID = 1L;  

    private static final String DEFAULT_PACKAGE_NAME = "cn.sm.action.";// 这里默认的Action类的包名前缀  
    private static final String DEFAULT_ACTION_NAME = "Action";// 这里默认的Action类的类名后缀  

    @Override  
    protected void service(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        // 这里获得请求的小服务路径  
        String servletPath = req.getServletPath();  
        // 这里从servletPath中去掉开头的斜杠和末尾的.do就是要执行的动作(Action)的名字  
        int start = 1;  // 这里去掉第一个字符斜杠从第二个字符开始  
        int end = servletPath.lastIndexOf(".do");   // 这里找到请求路径的后缀.do的位置  
        String actionName = end > start ? servletPath.substring(start, end) + DEFAULT_ACTION_NAME : "";  
        String actionClassName = DEFAULT_PACKAGE_NAME + actionName.substring(0, 1).toUpperCase() + actionName.substring(1);  
        // 这里接下来可以通过反射来创建Action对象并调用  
        System.out.println(actionClassName);  
    }  
}  
package cn.sm.action;  

/** 
 * Action执行结果类型 
 * @author 微冷的风 
 * 
 */  
public enum ResultType {  
    // 重定向 
    Redirect,   
    //转发 
    Forward,   
    //异步请求  
    Ajax,  
    // 数据流 
    Stream,  
    // 跳转到向下一个控制器
    Chain,  
    //重定向到下一个控制器 
    RedirectChain  
}  

 

                                                             
   也祝所有的程序员身体健康一切有惊无险          

         在前者控制器中设置的几乎独常量(默认的Action类的包名前缀、默认的Action类的类名后缀以及默认的JSP文件的门道)算硬代码,可以用那作一种植约定,约定好Action类的名字跟路线,JSP页面的名以及路线可以节省很多底配备,甚至可以得零配置,叫做约定优于配备(CoC,Convenient
over
Configuration)。符合约定的组成部分可省配置,不合符约定的部分据此配备文件或者阐明加以评释。继续修改前端控制器,如下。

package cn.sm.biz;  

import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  

import cn.sm.exception.DbSessionException;  
import cn.sm.util.DbSession;  
import cn.sm.util.DbSessionFactory;  

/** 
 * 业务逻辑代理对象(对非get开头的方法都启用事务) 
 * @author 微冷的风 
 * 
 */  
public class ServiceProxy implements InvocationHandler {  
    private Object target;  

    public ServiceProxy(Object target) {  
        this.target = target;  
    }  

    public static Object getProxyInstance(Object target) {  
        Class<?> clazz = target.getClass();  

        return Proxy.newProxyInstance(clazz.getClassLoader(),   
                clazz.getInterfaces(), new ServiceProxy(target));  
    }  

    @Override  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        Object retValue = null;  
        DbSession session = DbSessionFactory.openSession();  
        boolean isTxNeeded = !method.getName().startsWith("get");  
        try {  
            if(isTxNeeded) session.beginTx();  
            retValue = method.invoke(target, args);  
            if(isTxNeeded) session.commitTx();  
        }  
        catch(DbSessionException ex) {  
            ex.printStackTrace();  
            if(isTxNeeded) session.rollbackTx();  
        }  
        finally {  
            DbSessionFactory.closeSession();  
        }  
        return retValue;  
    }  
}
package cn.sm.action;  

/** 
 * Action执行结果 
 * @author 微冷的风 
 * 
 */  
public class ActionResult {  
    private ResultContent resultContent;  
    private ResultType resultType;  

    public ActionResult(ResultContent resultContent) {  
        this(resultContent, ResultType.Forward);  
    }  

    public ActionResult(ResultContent resultContent, ResultType type) {  
        this.resultContent = resultContent;  
        this.resultType = type;  
    }  

    /** 
     * 获得执行结果的内容 
     */  
    public ResultContent getResultContent() {  
        return resultContent;  
    }  

    /** 
     * 获得执行结果的类型 
     */  
    public ResultType getResultType() {  
        return resultType;  
    }  

}  
package cn.sm.biz;  

import java.util.HashMap;  
import java.util.Map;  

import cn.sm.util.CommonUtil;  

/** 
 * 创建业务逻辑代理对象的工厂 (登记式单例模式) 
 * @author 微冷的风
 * 
 */  
public class ServiceFactory {  
    private static final String DEFAULT_IMPL_PACKAGE_NAME = "impl";  

    private static Map<Class<?>, Object> map = new HashMap<>();  

    /** 
     * 工厂方法 
     * @param type 业务逻辑对象的类型 
     * @return 业务逻辑对象的代理对象 
     */  
    public static synchronized Object factory(Class<?> type) {  
        if(map.containsKey(type)) {  
            return map.get(type);  
        }  
        else {  
            try {  
                Object serviceObj = Class.forName(  
                        type.getPackage().getName() + "." + DEFAULT_IMPL_PACKAGE_NAME + "."   
                        + type.getSimpleName() + CommonUtil.capitalize(DEFAULT_IMPL_PACKAGE_NAME)).newInstance();  
                map.put(type, ServiceProxy.getProxyInstance(serviceObj));  
                return serviceObj;  
            } catch (Exception e) {  
                throw new RuntimeException(e);  
            }  
        }  
    }  
}  

                         
                                                                       
   

 

         
前端控制器写到此地还无好,如每个Action都要描写多少之req.getParameter(String)从呼吁被取得请参数还组装对象要继调用工作逻辑层的代码,那样Action实现类似中就会晤生出成千上万还的范代码,解决就等同题材之方案以是反光,通过反射可以以Action需要的参数注入及Action类中。需小心的是,反射虽只是帮忙大家刻画通用性很强的代码,但反射出啊不得视而不见,自定义MVC框架来好多而优化的地点,先解决要参数的流入问题。

 

   
可选取工厂类来创制工作逻辑对象,其实DAO实现类对象的创始为欠付工厂完成

 

package cn.sm.util;  

import java.sql.Connection;  
import java.sql.PreparedStatement;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
import java.sql.Statement;  
import java.io.Serializable;  

import cn.sm.exception.DbSessionException;  

/** 
 * 数据库会话(尚未提供批处理操作) 
 * @author 微冷的风
 * 
 */  
public class DbSession {  
    private Connection con = null;  
    private PreparedStatement stmt = null;  
    private ResultSet rs = null;  

    /** 
     * 开启数据库会话 
     */  
    public void open() {  
        if(con == null) {  
            try {  
                con = DbResourceManager.getConnection();  
            }  
            catch (Exception e) {  
                throw new DbSessionException("创建会话失败!", e);  
            }  
        }  
    }  

    /** 
     * 获得与数据库会话绑定的连接 
     */  
    public Connection getConnection() {  
        return con;  
    }  

    /** 
     * 关闭数据库会话 
     */  
    public void close() {  
        try {  
            DbResourceManager.close(rs);  
            rs = null;  
            DbResourceManager.close(stmt);  
            stmt = null;  
            DbResourceManager.close(con);  
            con = null;  
        }  
        catch (SQLException e) {  
            throw new DbSessionException("关闭会话失败!", e);  
        }  
    }  

    /** 
     * 开启事务 
     * @throws 无法开启事务时将抛出异常 
     */  
    public void beginTx() {  
        try {  
            if(con != null && !con.isClosed()) {  
                con.setAutoCommit(false);  
            }  
        }  
        catch (SQLException e) {  
            throw new RuntimeException("开启事务失败!", e);  
        }  
    }  

    /** 
     * 提交事务 
     * @throws 无法提交事务时将抛出异常 
     */  
    public void commitTx() {  
        try {  
            if(con != null && !con.isClosed()) {  
                con.commit();  
            }  
        }  
        catch (SQLException e) {  
            throw new DbSessionException("提交事务失败!", e);  
        }  
    }  

    /** 
     * 回滚事务 
     * @throws 无法回滚事务时将抛出异常 
     */  
    public void rollbackTx() {  
        try {  
            if(con != null && !con.isClosed()) {  
                con.rollback();  
            }  
        }  
        catch (SQLException e) {  
            throw new DbSessionException("回滚事务失败!", e);  
        }  
    }  

    /** 
     * 执行更新语句 
     * @param sql SQL语句 
     * @param params 替换SQL语句中占位符的参数 
     * @return 多少行受影响 
     */  
    public DbResult executeUpdate(String sql, Object... params) {  
        try {  
            boolean isInsert = sql.trim().startsWith("insert");  
            if(isInsert) {  
                stmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);  
            }  
            else {  
                stmt = con.prepareStatement(sql);  
            }  
            for(int i = 0; i < params.length; i++) {  
                stmt.setObject(i + 1, params[i]);  
            }  
            int affectedRows = stmt.executeUpdate();  
            Serializable generatedKey = null;  
            if(isInsert) {  
                rs = stmt.getGeneratedKeys();  
                generatedKey = rs.next()? (Serializable) rs.getObject(1) : generatedKey;  
            }  
            return new DbResult(affectedRows, generatedKey);  
        }  
        catch (SQLException e) {  
            throw new DbSessionException(e);  
        }  
    }  

    /** 
     * 执行查询语句 
     * @param sql SQL语句 
     * @param params 替换SQL语句中占位符的参数 
     * @return 结果集(游标) 
     */  
    public ResultSet executeQuery(String sql, Object... params) {  
        try {  
            stmt = con.prepareStatement(sql);  
            for(int i = 0; i < params.length; i++) {  
                stmt.setObject(i + 1, params[i]);  
            }  
            rs = stmt.executeQuery();  
        }  
        catch (SQLException e) {  
            throw new DbSessionException(e);  
        }  

        return rs;  
    }  

}  

package cn.sm.util;  

import java.io.Serializable;  

/** 
 * 数据库操作的结果 
 * @author 微冷的风
 * 
 */  
public class DbResult {  
    private int affectedRows;       // 受影响的行数  
    private Serializable generatedKey;  // 生成的主键  

    public DbResult(int affectedRows, Serializable generatedKey) {  
        this.affectedRows = affectedRows;  
        this.generatedKey = generatedKey;  
    }  

    public int getAffectedRows() {  
        return affectedRows;  
    }  

    public Serializable getGeneratedKey() {  
        return generatedKey;  
    }  

}  

 

       
 ActionResult类中的ResultContent代表了Action对用户要举行拍卖后拿到的情,可以储存一个字符串表示只要跨越反或重定向到的资源的URL,也得以储存一个目的来保存对用户请求举行拍卖后获的数据(模型),为了帮助Ajax操作,将之目的处理成JSON格式的字符串。

 

             就家伙类吃查封装了季只点子,通过此家伙类可让目标指定字段赋值,也可取得对象指定字段值和种,对目的有只字段又是一个靶的情况,下面的工具类可以分外好的拍卖,如person对象关系了car对象,car对象关系了producer对象,producer对象有name属性,可用ReflectionUtil.get(person,
“car.producer.name”)获取name属性的价值。有是家伙类,可继承写前端控制器了,代码如下

          数据库会话工厂的代码如下,使用ThreadLocal将数据库会话和线程绑定。

写了Action接口及相关类后,再变动写写前端控制器的代码,如下

         前端控制器已基本可用,下边用自定义之MVC框架做同动“Student管理体系”。由于要举行数据库操作,可对操作数据库的JDBC代码举办简单的包并引入DAO(数据看对象)情势。DAO(Data
Access
Object)是吗数据库或其余持久化机制提供了抽象接口的靶子,在匪显露底层持久化方案实现细节的前提,提供各种数码看操作。实际开支中,应将所有对数据源的看操作举办抽象化后封装于一个公共API中。用程设语言来说,就是成立一个接口,接口中定义了是应用程序大校会晤为此到的有事务方法。在那么些应用程序中,当用和数据源举行互相的时即便用这接口,并且编写一个独的类似来落实之接口,在逻辑上该类对应一个一定的数据存储。DAO情势实际上包含了少单模式,一凡Data
Accessor(数据访问器),二凡Data
Object(数据对象),一个是若缓解哪些看数的题材,二单比方化解的凡何许用对象封装数据。

 

 

package cn.sm.action;  

import cn.google.gson.Gson;  

/** 
 * Action执行结束产生的内容 
 * @author 微冷的风 
 * 
 */  
public class ResultContent {  
    private String url;  
    private Object obj;  

    public ResultContent(String url) {  
        this.url = url;  
    }  

    public ResultContent(Object obj) {  
        this.obj = obj;  
    }  

    public String getUrl() {  
        return url;  
    }  

    public String getJson() {  
        return new Gson().toJson(obj);// 这里使用了Google的JSON工具类gson  
    }  
}  

         
 FrontController类中之所以@WebServlet注明对该小服务做了照,只若是后缀为.do的请,都会面经过这有些劳,所以她是一个一级的前端控制器(当然,你吗可以当web.xml中采纳<servlet>和<servlet-mapping>标签对有些劳拓展映射,使用声前些天常是以提高开发功用,但得小心的凡表明也是同栽耦合,配置文件于解耦合上肯定是还好的挑选,如若如若利用注解,最好是如Spring
3这样可以因程序配置使用,其余,使用声明配置Servlet需要你的服务器襄助Servlet
3业内)。假设以Tomcat作为服务器(使用默认设置),项目之部署名也sm,接下去好浏览器地址栏输入http://localhost:8080/sm/login.do,Tomcat的控制台会输出cn.sm.action.LoginAction。

package cn.sm.action;  

import java.io.IOException;  

import javax.servlet.ServletException;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

/** 
 *  处理用户请求的控制器接口 
 * @author 微冷的风 
 * 
 */  
public interface Action {  

    public ActionResult execute(HttpServletRequest req, HttpServletResponse resp)   
            throws ServletException, IOException;  
}  
package cn.sm.servlet;  

import java.io.IOException;  
import java.io.PrintWriter;  

import javax.servlet.ServletException;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

import cn.sm.action.Action;  
import cn.sm.action.ActionResult;  
import cn.sm.action.ResultContent;  
import cn.sm.action.ResultType;  

@WebServlet("*.do")  
public class FrontController extends HttpServlet {  
    private static final long serialVersionUID = 1L;  

    private static final String DEFAULT_PACKAGE_NAME = "cn.sm.action.";      // 这里默认的Action类的包名前缀  
    private static final String DEFAULT_ACTION_NAME = "Action";       // 默认的Action类的类名后缀  
    private static final String DEFAULT_JSP_PATH = "/WEB-INF/jsp";          // 默认的JSP文件的路径  

    @Override  
    protected void service(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        String contextPath = req.getContextPath() + "/";  
        // 获得请求的小服务路径  
        String servletPath = req.getServletPath();  
        // 从servletPath中去掉开头的斜杠和末尾的.do就是要执行的动作(Action)的名字  
        int start = 1;  // 去掉第一个字符斜杠从第二个字符开始  
        int end = servletPath.lastIndexOf(".do");   // 找到请求路径的后缀.do的位置  
        String actionName = end > start ? servletPath.substring(start, end) + DEFAULT_ACTION_NAME : "";  
        String actionClassName = DEFAULT_PACKAGE_NAME + actionName.substring(0, 1).toUpperCase() + actionName.substring(1);  
        try {  
            // 通过反射来创建Action对象并调用  
            Action action = (Action) Class.forName(actionClassName).newInstance();  
            // 执行多态方法execute得到ActionResult  
            ActionResult result = action.execute(req, resp);  
            ResultType resultType = result.getResultType();// 结果类型  
            ResultContent resultContent = result.getResultContent();// 结果内容  
            // 根据ResultType决定如何处理  
            switch (resultType) {  
            case Forward: // 跳转  
                req.getRequestDispatcher(  
                        DEFAULT_JSP_PATH + resultContent.getUrl()).forward(req,  
                        resp);  
                break;  
            case Redirect: // 重定向  
                resp.sendRedirect(resultContent.getUrl());  
                break;  
            case Ajax: // Ajax  
                PrintWriter pw = resp.getWriter();  
                pw.println(resultContent.getJson());  
                pw.close();  
                break;  
            case Chain:  
                req.getRequestDispatcher(contextPath + resultContent.getUrl())  
                        .forward(req, resp);  
                break;  
            case RedirectChain:  
                resp.sendRedirect(contextPath + resultContent.getUrl());  
                break;  
            default:  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
            throw new ServletException(e);  
        }  
    }  
}  

       
1.**
嘿是前者控制器(font
controller)。Java
Web中以前端控制器是以的外衣,简单的游说富有的呼吁都谋面透过这前端控制器,由前端控制器依照请求的情节来支配哪些处理并以拍卖的结果重回给浏览器。这虽好于许多供销社还生一个前台,这里平日站着几乎各项面貌姣好的仙子,你若到这家店铺拍卖任何的作业要约见任何人都得和她们说,她们会基于你而召开呀知会相应的单位依然个人来处理,那样做的利益是明确的,集团内系统运转可能很复杂,可是那些对于外部的客户的话应该是晶莹剔透底,通过前台,客户可以抱他们期待该店铺呢这提供的服务要无欲领悟公司的内贯彻。这里说往日台就是商店中系统的一个伪装,它简化了客户之操作。前端控制器的观点就是是GoF设计格局)中Ajax,伪装情势(外观情势)每当Web项目中的实际上运用。SUN公司吗Java
Web开发概念了点滴种模型,Model 1和Model 2。Model
2是基于MVC(Model-View-Controller,模型-视图-控制)架构模式的,平日以略劳(Servlet)或过滤器(Filter)作为控制器,其意图是接受用户请求并取得模型数据然后跳反至视图;将JSP页面作为视图,用来呈现用户操作的结果;模型当然是POJO(Plain
Old Java Object),它是分别为EJB(Enterprise
JavaBean)的平日Java对象,不落实任何其余框架的接口也无装任何的角色,而是负责承接数据,可以当作VO(Value
Object)或DTO(Data Transfer
Object)来用。当然,倘诺您对这一个概念不领会,能够为此百度或者维基百科查看一下,想要浓厚之垂询那一个内容引进阅读大师MartinFowler的《公司应用架构情势》(英文名叫:Patterns of Enterprise Application
Architecture)。**

         
先定义一个接口让Action帮助文件上传,凡要处理公事上传的Action类都得实现这接口,然后经过接口注入的办法,将上传文件的数额和达传文书之文书称注入及Action类中,这样Action类中便可平素处理上传的公文了。

package cn.sm.util;  

import java.sql.Connection;  
import java.sql.Driver;  
import java.sql.DriverManager;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
import java.sql.Statement;  
import java.util.Properties;  

/** 
 * 数据库资源管理器 
 * @author 微冷的风 
 * 
 */  
public class DbResourceManager {  
    // 最好的做法是将配置保存到配置文件中(可以用properteis文件或XML文件)  
    private static final String JDBC_DRV = "cn.mysql.jdbc.Driver";  
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/sm";  
    private static final String JDBC_UID = "sm";  
    private static final String JDBC_PWD = "123456";  

    private static Driver driver = null;  
    private static Properties info = new Properties();  

    private DbResourceManager() {  
        throw new AssertionError();  
    }  

    static {      
        try {  
            loadDriver();   // 通过静态代码块加载数据库驱动  
            info.setProperty("user", JDBC_UID);  
            info.setProperty("password", JDBC_PWD);  
        }  
        catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  

    public static void setDriver(Driver _driver) {  
        driver = _driver;  
    }  

    // 加载驱动程序  
    private static void loadDriver() throws Exception {  
        driver = (Driver) Class.forName(JDBC_DRV).newInstance();  
        DriverManager.registerDriver(driver);  
    }  

    /** 
     * 打开连接 
     * @return 连接对象 
     * @throws Exception 无法加载驱动或无法建立连接时将抛出异常 
     */  
    public static Connection getConnection() throws Exception {  
        if(driver == null) {  
            loadDriver();  
        }  
        return driver.connect(JDBC_URL, info);  
    }  

    /** 
     * 关闭游标 
     */  
    public static void close(ResultSet rs) {  
        try {  
            if(rs != null && !rs.isClosed()) {  
                rs.close();  
            }  
        }  
        catch (SQLException e) {  
            e.printStackTrace();  
        }  
    }  

    /** 
     * 关闭语句 
     */  
    public static void close(Statement stmt) throws SQLException {  
        try {  
            if(stmt != null && !stmt.isClosed()) {  
                stmt.close();  
            }  
        }  
        catch (SQLException e) {  
            e.printStackTrace();  
        }  
    }  

    /** 
     * 关闭连接 
     */  
    public static void close(Connection con) {  
        try {  
            if(con != null && !con.isClosed()) {  
                con.close();  
            }  
        }  
        catch (SQLException e) {  
            e.printStackTrace();  
        }  
    }  

    /** 
     * 注销驱动 
     * @throws SQLException 
     */  
    public static void unloadDriver() throws SQLException {  
        if(driver != null) {  
            DriverManager.deregisterDriver(driver);  
            driver = null;  
        }  
    }  

}  

 

数据库资源管理器的代码如下。

 

 

package cn.sm.servlet;  

import java.io.IOException;  
import java.io.PrintWriter;  
import java.lang.reflect.Array;  
import java.util.ArrayList;  
import java.util.Enumeration;  
import java.util.List;  

import javax.servlet.ServletConfig;  
import javax.servlet.ServletException;  
import javax.servlet.annotation.MultipartConfig;  
import javax.servlet.annotation.WebInitParam;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.Part;  

import cn.sm.action.Action;  
import cn.sm.action.ActionResult;  
import cn.sm.action.ResultContent;  
import cn.sm.action.ResultType;  
import cn.sm.action.Uploadable;  
import cn.sm.util.CommonUtil;  
import cn.sm.util.ReflectionUtil;  

/** 
 * 前端控制器(门面模式[提供用户请求的门面]) 
 * @author 微冷的风 
 * 
 */  
@WebServlet(urlPatterns = { "*.do" }, loadOnStartup = 0,   
        initParams = {   
            @WebInitParam(name = "packagePrefix", value = "cn.sm.action."),  
            @WebInitParam(name = "jspPrefix", value = "/WEB-INF/jsp/"),  
            @WebInitParam(name = "actionSuffix", value = "Action")  
        }  
)  
@MultipartConfig  
public class FrontController extends HttpServlet {  
    private static final long serialVersionUID = 1L;  

    private static final String DEFAULT_PACKAGE_NAME = "cn.sm.action.";  
    private static final String DEFAULT_JSP_PATH = "/WEB-INF/content/";  
    private static final String DEFAULT_ACTION_NAME = "Action";  

    private String packagePrefix = null;        // 包名的前缀  
    private String jspPrefix = null;            // JSP页面路径的前缀  
    private String actionSuffix = null;         // Action类名的后缀  

    @Override  
    public void init(ServletConfig config) throws ServletException {  
        String initParam = config.getInitParameter("packagePrefix");  
        packagePrefix = initParam != null ? initParam :  DEFAULT_PACKAGE_NAME;  
        initParam = config.getInitParameter("jspPrefix");  
        jspPrefix = initParam != null ? initParam : DEFAULT_JSP_PATH;  
        initParam = config.getInitParameter("actionSuffix");  
        actionSuffix = initParam != null ? initParam : DEFAULT_ACTION_NAME;  
    }  

    @Override  
    protected void service(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        String contextPath = req.getContextPath() + "/";  
        String servletPath = req.getServletPath();  

        try {  
            Action action = (Action) Class.forName(getFullActionName(servletPath)).newInstance();  
            try {  
                injectProperties(action, req);  
            } catch (Exception e) {  
            }  
            if(action instanceof Uploadable) {  // 通过接口向实现了接口的类注入属性(接口注入)  
                List<Part> fileparts = new ArrayList<>();  
                List<String> filenames = new ArrayList<>();  
                for(Part part : req.getParts()) {  
                    String cd = part.getHeader("Content-Disposition");  
                    if(cd.indexOf("filename") >= 0) {  
                        fileparts.add(part);  
                        filenames.add(cd.substring(cd.lastIndexOf("=") + 1).replaceAll("\\\"", ""));  
                    }  
                }  
                ((Uploadable) action).setParts(fileparts.toArray(new Part[fileparts.size()]));  
                ((Uploadable) action).setFilenames(filenames.toArray(new String[filenames.size()]));  
            }  
            ActionResult actionResult = action.execute(req, resp);  
            if(actionResult != null) {  
                ResultContent resultContent = actionResult.getResultContent();  
                ResultType resultType = actionResult.getResultType();  
                switch(resultType) {  
                case Redirect:  
                    resp.sendRedirect(contextPath + resultContent.getUrl());  
                    break;  
                case Forward:  
                    req.getRequestDispatcher(getFullJspPath(servletPath) + resultContent.getUrl()).forward(req, resp);  
                    break;  
                case Ajax:  
                    PrintWriter pw = resp.getWriter();  
                    pw.println(resultContent.getJson());  
                    pw.close();  
                    break;  
                case Chain:  
                    req.getRequestDispatcher(contextPath + resultContent.getUrl()).forward(req, resp);  
                    break;  
                case RedirectChain:  
                    resp.sendRedirect(contextPath + resultContent.getUrl());  
                    break;  
                default:  
                }  
            }  
        }   
        catch (Exception e) {  
            e.printStackTrace();  
            resp.sendRedirect("error.html");  
        }  
    }  

    // 根据请求的小服务路径获得对应的Action类的名字  
    private String getFullActionName(String servletPath) {  
        int start = servletPath.lastIndexOf("/") + 1;  
        int end = servletPath.lastIndexOf(".do");  
        return packagePrefix + getSubPackage(servletPath) + CommonUtil.capitalize(servletPath.substring(start, end)) + actionSuffix;  
    }  

    // 根据请求的小服务路径获得对应的完整的JSP页面路径  
    private String getFullJspPath(String servletPath) {  
        return jspPrefix + getSubJspPath(servletPath);  
    }  

    // 根据请求的小服务路径获得子级包名  
    private String getSubPackage(String servletPath) {  
        return getSubJspPath(servletPath).replaceAll("\\/", ".");  
    }  

    // 根据请求的小服务路径获得JSP页面的子级路径  
    private String getSubJspPath(String servletPath) {  
        int start = 1;  
        int end = servletPath.lastIndexOf("/");  
        return end > start ? servletPath.substring(start, end > 0 ? end + 1 : 0) : "";  
    }  

    // 向Action对象中注入属性  
    private void injectProperties(Action action, HttpServletRequest req) throws Exception {  
        Enumeration<String> paramNamesEnum =  req.getParameterNames();  
        while(paramNamesEnum.hasMoreElements()) {  
            String paramName = paramNamesEnum.nextElement();  
            Class<?> fieldType = ReflectionUtil.getFieldType(action, paramName.replaceAll("\\[|\\]", ""));  
            if(fieldType != null) {  
                Object paramValue = null;  
                if(fieldType.isArray()) {   // 如果属性是数组类型  
                    Class<?> elemType = fieldType.getComponentType(); // 获得数组元素类型  
                    String[] values = req.getParameterValues(paramName);  
                    paramValue = Array.newInstance(elemType, values.length);    // 通过反射创建数组对象  
                    for(int i = 0; i < values.length; i++) {  
                        Object tempObj = CommonUtil.changeStringToObject(elemType, values[i]);  
                        Array.set(paramValue, i, tempObj);  
                    }  
                }  
                else {  // 非数组类型的属性  
                    paramValue = CommonUtil.changeStringToObject(fieldType, req.getParameter(paramName));  
                }  
                ReflectionUtil.setValue(action, paramName.replaceAll("\\[|\\]", ""), paramValue);  
            }  
        }  
    }  
}  

       要是用基于事务脚本格局的分段开发,可当业务逻辑层设置工作之鄂,但随即会导致有的工作逻辑方式被都要处理事务,可以应用代理情势吧业务逻辑对象好成代理,如工作逻辑层有宏图接口,这可用Java中的动态代理来完成业务逻辑代理对象的成立,代码如下。

Ajax 1Ajax 2

package cn.sm.servlet;  

import java.io.IOException;  
import java.io.PrintWriter;  
import java.lang.reflect.Array;  
import java.util.Enumeration;  

import javax.servlet.ServletConfig;  
import javax.servlet.ServletException;  
import javax.servlet.annotation.MultipartConfig;  
import javax.servlet.annotation.WebInitParam;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

import cn.sm.action.Action;  
import cn.sm.action.ActionResult;  
import cn.sm.action.ResultContent;  
import cn.sm.util.CommonUtil;  
import cn.sm.util.ReflectionUtil;  

/** 
 * 前端控制器(门面模式[提供用户请求的门面]) 
 * @author 微冷的风
 * 
 */  
@WebServlet(urlPatterns = { "*.do" }, loadOnStartup = 0,   
        initParams = {   
            @WebInitParam(name = "packagePrefix", value = "cn.sm.action."),  
            @WebInitParam(name = "jspPrefix", value = "/WEB-INF/jsp/"),  
            @WebInitParam(name = "actionSuffix", value = "Action")  
        }  
)  
@MultipartConfig  
public class FrontController extends HttpServlet {  
    private static final long serialVersionUID = 1L;  

    private static final String DEFAULT_PACKAGE_NAME = "cn.sm.action.";  
    private static final String DEFAULT_JSP_PATH = "/WEB-INF/content/";  
    private static final String DEFAULT_ACTION_NAME = "Action";  

    private String packagePrefix = null;        // 包名的前缀  
    private String jspPrefix = null;            // JSP页面路径的前缀  
    private String actionSuffix = null;         // Action类名的后缀  

    @Override  
    public void init(ServletConfig config) throws ServletException {  
        String initParam = config.getInitParameter("packagePrefix");  
        packagePrefix = initParam != null ? initParam :  DEFAULT_PACKAGE_NAME;  
        initParam = config.getInitParameter("jspPrefix");  
        jspPrefix = initParam != null ? initParam : DEFAULT_JSP_PATH;  
        initParam = config.getInitParameter("actionSuffix");  
        actionSuffix = initParam != null ? initParam : DEFAULT_ACTION_NAME;  
    }  

    @Override  
    protected void service(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        String contextPath = req.getContextPath() + "/";  
        String servletPath = req.getServletPath();  
        try {  
            Action action = (Action) Class.forName(getFullActionName(servletPath)).newInstance();  
            injectProperties(action, req);// 向Action对象中注入请求参数  
            ActionResult actionResult = action.execute(req, resp);  
            ResultContent resultContent = actionResult.getResultContent();  
            switch (actionResult.getResultType()) {  
            case Redirect:  
                resp.sendRedirect(contextPath + resultContent.getUrl());  
                break;  
            case Forward:  
                req.getRequestDispatcher(  
                        getFullJspPath(servletPath) + resultContent.getUrl())  
                        .forward(req, resp);  
                break;  
            case Ajax:  
                PrintWriter pw = resp.getWriter();  
                pw.println(resultContent.getJson());  
                pw.close();  
                break;  
            case Chain:  
                req.getRequestDispatcher(contextPath + resultContent.getUrl())  
                        .forward(req, resp);  
                break;  
            case RedirectChain:  
                resp.sendRedirect(contextPath + resultContent.getUrl());  
                break;  
            default:  
            }  
        }  
        catch (Exception e) {  
            e.printStackTrace();  
            resp.sendRedirect("error.html");  
        }  
    }  

    // 根据请求的小服务路径获得对应的Action类的名字  
    private String getFullActionName(String servletPath) {  
        int start = servletPath.lastIndexOf("/") + 1;  
        int end = servletPath.lastIndexOf(".do");  
        return packagePrefix + getSubPackage(servletPath) + CommonUtil.capitalize(servletPath.substring(start, end)) + actionSuffix;  
    }  

    // 根据请求的小服务路径获得对应的完整的JSP页面路径  
    private String getFullJspPath(String servletPath) {  
        return jspPrefix + getSubJspPath(servletPath);  
    }  

    // 根据请求的小服务路径获得子级包名  
    private String getSubPackage(String servletPath) {  
        return getSubJspPath(servletPath).replaceAll("\\/", ".");  
    }  

    // 根据请求的小服务路径获得JSP页面的子级路径  
    private String getSubJspPath(String servletPath) {  
        int start = 1;  
        int end = servletPath.lastIndexOf("/");  
        return end > start ? servletPath.substring(start, end > 0 ? end + 1 : 0) : "";  
    }  

    // 向Action对象中注入属性  
    private void injectProperties(Action action, HttpServletRequest req) throws Exception {  
        Enumeration<String> paramNamesEnum =  req.getParameterNames();  
        while(paramNamesEnum.hasMoreElements()) {  
            String paramName = paramNamesEnum.nextElement();  
            Class<?> fieldType = ReflectionUtil.getFieldType(action, paramName.replaceAll("\\[|\\]", ""));  
            if(fieldType != null) {  
                Object paramValue = null;  
                if(fieldType.isArray()) {   // 如果属性是数组类型  
                    Class<?> elemType = fieldType.getComponentType(); // 获得数组元素类型  
                    String[] values = req.getParameterValues(paramName);  
                    paramValue = Array.newInstance(elemType, values.length);    // 通过反射创建数组对象  
                    for(int i = 0; i < values.length; i++) {  
                        Object tempObj = CommonUtil.changeStringToObject(elemType, values[i]);  
                        Array.set(paramValue, i, tempObj);  
                    }  
                }  
                else {  // 非数组类型的属性  
                    paramValue = CommonUtil.changeStringToObject(fieldType, req.getParameter(paramName));  
                }  
                ReflectionUtil.setValue(action, paramName.replaceAll("\\[|\\]", ""), paramValue);  
            }  
        }  
    }  
}  

 

包装一个照的工具类,代码如下

 

     未完待续··· ···    
    

支撑文件上传的接口代码如下。

 

package cn.sm.util;  

import java.awt.Color;  
import java.text.DateFormat;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.ArrayList;  
import java.util.Date;  
import java.util.List;  

/** 
 * 通用工具类 
 * @author 微冷的风
 * 
 */  
public final class CommonUtil {  
    private static final List<String> patterns = new ArrayList<>();  
    private static final List<TypeConverter> converters = new ArrayList<>();  

    static {  
        patterns.add("yyyy-MM-dd");  
        patterns.add("yyyy-MM-dd HH:mm:ss");  
    }  

    private CommonUtil() {  
        throw new AssertionError();  
    }  

    /** 
     * 将字符串的首字母大写 
     */  
    public static String capitalize(String str) {  
        StringBuilder sb = new StringBuilder();  
        if (str != null && str.length() > 0) {  
            sb.append(str.substring(0, 1).toUpperCase());  
            if (str.length() > 1) {  
                sb.append(str.substring(1));  
            }  
            return sb.toString();  
        }  
        return str;  
    }  

    /** 
     * 生成随机颜色 
     */  
    public static Color getRandomColor() {  
        int r = (int) (Math.random() * 256);  
        int g = (int) (Math.random() * 256);  
        int b = (int) (Math.random() * 256);  
        return new Color(r, g, b);  
    }  

    /** 
     * 添加时间日期样式 
     * @param pattern 时间日期样式 
     */  
    public static void registerDateTimePattern(String pattern) {  
        patterns.add(pattern);  
    }  

    /** 
    * 取消时间日期样式 
    * @param pattern 时间日期样式 
    */  
    public static void unRegisterDateTimePattern(String pattern) {  
        patterns.remove(pattern);  
    }  

    /** 
     * 添加类型转换器 
     * @param converter 类型转换器对象 
     */  
    public static void registerTypeConverter(TypeConverter converter) {  
        converters.add(converter);  
    }  

    /** 
     * 取消类型转换器 
     * @param converter 类型转换器对象 
     */  
    public static void unRegisterTypeConverter(TypeConverter converter) {  
        converters.remove(converter);  
    }  

    /** 
     * 将字符串转换成时间日期类型 
     * @param str 时间日期字符串  
     */  
    public static Date convertStringToDateTime(String str) {  
        if (str != null) {  
            for (String pattern : patterns) {  
                Date date = tryConvertStringToDate(str, pattern);  

                if (date != null) {  
                    return date;  
                }  
            }  
        }  

        return null;  
    }  

    /** 
     * 按照指定样式将时间日期转换成字符串 
     * @param date 时间日期对象 
     * @param pattern 样式字符串 
     * @return 时间日期的字符串形式 
     */  
    public static String convertDateTimeToString(Date date, String pattern) {  
         return new SimpleDateFormat(pattern).format(date);  
    }  

    private static Date tryConvertStringToDate(String str, String pattern) {  
         DateFormat dateFormat = new SimpleDateFormat(pattern);   
         dateFormat.setLenient(false);  // 不允许将不符合样式的字符串转换成时间日期  

         try {  
             return dateFormat.parse(str);  
         }   
         catch (ParseException ex) {  
         }  

         return null;  
    }  

    /** 
     * 将字符串值按指定的类型转换成转换成对象 
     * @param elemType 类型 
     * @param value 字符串值 
     */  
    public static Object changeStringToObject(Class<?> elemType, String value) {  
        Object tempObj = null;  

        if(elemType == byte.class || elemType == Byte.class) {  
            tempObj = Byte.parseByte(value);  
        }  
        else if(elemType == short.class || elemType == Short.class) {  
            tempObj = Short.parseShort(value);  
        }  
        else if(elemType == int.class || elemType == Integer.class) {  
            tempObj = Integer.parseInt(value);  
        }  
        else if(elemType == long.class || elemType == Long.class) {  
            tempObj = Long.parseLong(value);  
        }  
        else if(elemType == double.class || elemType == Double.class) {  
            tempObj = Double.parseDouble(value);  
        }  
        else if(elemType == float.class || elemType == Float.class) {  
            tempObj = Float.parseFloat(value);  
        }  
        else if(elemType == boolean.class || elemType == Boolean.class) {  
            tempObj = Boolean.parseBoolean(value);  
        }  
        else if(elemType == java.util.Date.class) {  
            tempObj = convertStringToDateTime(value);  
        }  
        else if(elemType == java.lang.String.class) {  
            tempObj = value;  
        }  
        else {  
            for(TypeConverter converter : converters) {  
                try {  
                    tempObj = converter.convert(elemType, value);  
                    if(tempObj != null) {  
                        return tempObj;  
                    }  
                }   
                catch (Exception e) {  
                }  
            }  
        }  

        return tempObj;  
    }  

    /** 
     * 获取文件后缀名 
     * @param filename 文件名 
     * @return 文件的后缀名以.开头 
     */  
    public static String getFileSuffix(String filename) {  
        int index = filename.lastIndexOf(".");  
        return index > 0 ? filename.substring(index) : "";  
    }
}

 

   
数据库会话代码如下,封装了进行查询及进行增删改之方法减重复代码。

         接口中的execute方法是拍卖用户要的章程,它的鲜独参数分别是HttpServletRequest和HttpServletResponse对象,在前者控制着经反射成立Action,并调用execute方法,不同的Action子类通过再写针对性execute方法被起了不同的贯彻版本,该办法是一个多态方法。execute方法的重回值是一个ActionResult对象,实现代码如下。

形容一个通用的前端控制器
 用几近态
 先定义一个Action接口并定义一个架空方法,不同之Action子类会对拖欠方法开展重写,用Action的援引用不同的Action子类对象,调用子类重写了之法,执行不同的表现。

 

 

     修改后前端控制器

 

相关文章