论坛首页 入门技术论坛

jsp + javabean + servlet写的MVC

浏览 4088 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-03-12  

首先设置 web.xml 让所有请求扩展名为.do 的都通过ControllerFilter.java来解析

<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
    id="WebApp_ID" version="2.5">  
    <display-name>mvc</display-name>  
  
    <filter>  
        <filter-name>controllerFilter</filter-name>  
        <filter-class>com.mvc.cms.ControllerFilter</filter-class>  
        <init-param>  
            <param-name>ERROR_PAGE</param-name>  
            <param-value>error.jsp</param-value>  
        </init-param>  
           
        <init-param>  
            <param-name>OBJECT_NAME</param-name>  
            <param-value>loginBean</param-value>  
        </init-param>  
    </filter>    
  
    <filter-mapping>  
        <filter-name>controllerFilter</filter-name>  
        <url-pattern>*.do</url-pattern>  
    </filter-mapping>  
  
    <welcome-file-list>  
        <welcome-file>index.html</welcome-file>  
        <welcome-file>index.htm</welcome-file>  
        <welcome-file>index.jsp</welcome-file>  
        <welcome-file>default.html</welcome-file>  
        <welcome-file>default.htm</welcome-file>  
        <welcome-file>default.jsp</welcome-file>  
    </welcome-file-list>  
</web-app>  


 

 

ControllerFilter.java 控制器

 

public class ControllerFilter implements Filter {   
  
    protected FilterConfig filterConfig;   
    private final Map<String,String> map = new HashMap<String,String>();   
       
    public void init(FilterConfig config) {   
        this.filterConfig = config;   
        String filePath = config.getServletContext().getRealPath("/WEB-INF/web-config.xml");   
        DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();   
        try {   
            DocumentBuilder builder = dbfactory.newDocumentBuilder();   
            InputStream in = new FileInputStream(filePath);   
            Document doc = builder.parse(in);          
            Element root = doc.getDocumentElement();   
            NodeList list = root.getElementsByTagName("action");   
            for (int i = 0; i < list.getLength(); i++) {   
                Element element = (Element) list.item(i);   
                NodeList nameValue = element.getElementsByTagName("name");   
                Element nameElement = (Element) nameValue.item(0);   
                String clazzName = nameElement.getFirstChild().getNodeValue();   
                   
                NodeList clazz= element.getElementsByTagName("clazz");   
                Element clazzElement = (Element) clazz.item(0);   
                String  clazzValue = clazzElement.getFirstChild().getNodeValue();   
                map.put(clazzName, clazzValue);   
            }              
        } catch (SAXException e) {   
            e.printStackTrace();   
        } catch (IOException e) {   
            e.printStackTrace();   
        } catch (ParserConfigurationException e) {   
            e.printStackTrace();   
        }    
    }   
  
    public void destroy() {   
        this.filterConfig = null;   
    }   
  
    public void doFilter(ServletRequest srequest, ServletResponse sresponse,FilterChain filterChain) throws IOException, ServletException {   
        HttpServletRequest request = (HttpServletRequest) srequest;   
        HttpServletResponse response = (HttpServletResponse) sresponse;   
        //验证不通过进行跳转   
        /*if (!passed(request,response)) {  
            String errorPage=this.filterConfig.getInitParameter("ERROR_PAGE");  
            response.sendRedirect(errorPage);  
            return;  
        }*/  
        request.setCharacterEncoding("GBK");   
        String path = (String) request.getRequestURI();   
        String actionString = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));   
        String forwardPage = null;   
        Action actionClazz = null;   
        if (map.containsKey(actionString)) {   
            String clazz = map.get(actionString);   
            actionClazz = getAction(clazz);   
            try {                  
                forwardPage = actionClazz.execute(request, response);   
            } catch (ActionException e) {   
                e.printStackTrace();   
            }   
        }   
        if (forwardPage != null) {   
            filterConfig.getServletContext().getRequestDispatcher(forwardPage).forward(request, response);   
        }   
    }   
       
    //验证权限   
    private boolean passed(ServletRequest request, ServletResponse response)  throws IOException, ServletException {   
        boolean result=false;   
        return result;   
    }   
       
    private Action getAction (String clazz) {   
        ActionFactory factory = ActionFactory.getInstance();   
        return factory.getAction(clazz);   
    }  


 

 

设置一个web-config.xml 来表示某个请求对应的类

<?xml version="1.0" encoding="UTF-8"?>  
<struts>  
    <action>  
        <name>login</name>  
        <clazz>com.mvc.cms.action.testAction</clazz>  
    </action>    
    <action>  
        <name>login2</name>  
        <clazz>com.mvc.cms.action.LoginAction</clazz>  
    </action>    
    <action>  
        <name>login3</name>  
        <clazz>com.mvc.cms.action.testAction3</clazz>  
    </action>    
</struts> 

 

 

写一个接口action

public interface Action {   
       
    /**  
     * excute a certain function  
     * @param request  
     * @param response  
     */  
    public String execute(HttpServletRequest request, HttpServletResponse response)  throws IOException, ServletException,ActionException;   
}  

 

 

让所有的action都实现这个接口,如:

public class LoginAction implements Action {   
  
    @Override  
    public String execute(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException,ActionException {   
        String userName = request.getParameter("userName");   
        if (userName != null) {   
            request.setAttribute("userName", userName);   
            return "/UI/ok.jsp";   
        }else{   
            return "/UI/login.jsp";   
        }   
    }   
  
}  

 

 

一个类工厂,用到了反射

public class ActionFactory {   
    private static final Map<String, Object> factory = new HashMap<String, Object>();   
    private static ActionFactory actionFacory;   
  
    private ActionFactory() {   
  
    }   
  
    public synchronized  static ActionFactory getInstance() {   
        if (actionFacory == null) {   
            actionFacory = new ActionFactory();   
        }   
        return actionFacory;   
    }   
  
    @SuppressWarnings("unchecked")   
    public Action getAction(String clazz) {   
        final String key = clazz;   
        if (!factory.containsKey(key)) {   
            try {   
                Constructor c = Class.forName(clazz).getDeclaredConstructor(new Class[] {});   
                c.setAccessible(true);   
                factory.put(key, c.newInstance(new Object[] {}));   
            } catch (Exception ex) {   
                throw new ExceptionInInitializerError(ex);   
            }   
        }   
        return (Action) factory.get(key);   
    }   
  
}  


 

 

自己胡乱写的,呵呵

   发表时间:2010-03-12  

似乎和Struts1.x相似度极高....


思维不要被束缚了。 加油!!继续努力!!

0 请登录后投票
   发表时间:2010-03-13   最后修改:2010-03-13
解析XML配置文件用的是dom解析,这个在文件大的情况下很占内存,struts1使用的是digester进行解析的吧,lz可以考虑一下SAX解析。
0 请登录后投票
   发表时间:2010-03-13  
asialee 写道
解析XML配置文件用的是dom解析,这个在文件大的情况下很占内存,struts1使用的是digester进行解析的吧,lz可以考虑一下SAX解析。



要考虑场景,解析配置文件会消耗多大的内存呢,SAX太复杂了,不适合LZ。
0 请登录后投票
   发表时间:2010-03-13  
mercyblitz 写道
asialee 写道
解析XML配置文件用的是dom解析,这个在文件大的情况下很占内存,struts1使用的是digester进行解析的吧,lz可以考虑一下SAX解析。



要考虑场景,解析配置文件会消耗多大的内存呢,SAX太复杂了,不适合LZ。


配置文件有时候会很大的,而且配置主要是读取,用SAX最合适。
0 请登录后投票
   发表时间:2010-03-13  
建议楼主将 Action execute()的返回值用ActionForward封装一下,因为不仅仅是 forward 的情况,还有 redirect 的情况,且并且可以为Ajax JSON做准备。
0 请登录后投票
   发表时间:2010-03-13  
String actionString = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));
这句话感觉有问题, path.lastIndexOf(".")不能用在这里,后面传递的参数namevalue
中也可能包含"."符号,可以用".do截取"
0 请登录后投票
   发表时间:2010-03-14  
fenxue 写道
String actionString = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));
这句话感觉有问题, path.lastIndexOf(".")不能用在这里,后面传递的参数namevalue
中也可能包含"."符号,可以用".do截取"

楼主用"."截取没有错,但是需要对path做去冗余的处理,去除"?"之后的东东,或者通过request.getServletPath()获得path,因为servlet中我们不一定非要用.do做匹配,也可以是其他的标识。
0 请登录后投票
   发表时间:2010-03-14  
asialee 写道
mercyblitz 写道
asialee 写道
解析XML配置文件用的是dom解析,这个在文件大的情况下很占内存,struts1使用的是digester进行解析的吧,lz可以考虑一下SAX解析。



要考虑场景,解析配置文件会消耗多大的内存呢,SAX太复杂了,不适合LZ。


配置文件有时候会很大的,而且配置主要是读取,用SAX最合适。


配置文件能有多大?启动之后就GC掉了!
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics