Servlet之动作框架

参考: Java Servlet 技术简介

概述

动作框架,是指编写一个Servlet(请求入口),解析请求的URI得到动作名称,调用处理用户请求的动作类,完成请求访问。当动作执行完毕后,返回一个指向表示结果的JSP的URL(也可以用模板引擎)。
学习过MVC的同学可以在这里一一对应。Servlet通过调用ActionFactory起到路由的作用,处理用户的动作类即是Controller,Controller会调用Model完成任务处理,处理完毕后,返回的URI指向的JSP就是用于表示的View。

大致框架图如下:

详述

在这,会具体把实现动作框架所需部件的功能及构成详细叙述一遍,已达到每一部分都尽量清楚的目的。

Servlet

“唯一”的Servlet。所有请求的入口,继承自HttpServlet,解析出动作名称,然后通过动作工厂ActionFactory得到具体的动作对象,执行动作的perform方法,最后转发请求到返回的URL。
示例:

package com.example;

import java.io.IOException;
import javax.servlet.ServletException;

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

import com.example.actions.Action;

public class actionServlet extends HttpServlet {
    private ActionFactory factory = ActionFactory.getSingleton();

    // public void init(ServletConfig config) throws ServletException { ... }

    public void service(HttpServletRequest req, HttpServletResponse res) 
            throws ServletException, IOException {
        // 获得动作的名称
        String actionName = getActionName(req);
        // 通过动作工厂生成actionName的实例对象
        Action action = factory.create(actionName);
        // 执行动作,得到返回的URL
        String url = action.perform(req, res);
        // 通过url显示结果
        if (url != null)
            getServletContext().getRequestDispatcher(url).forward(req, res);
    }

    // public void destroy() { ... }

    private String getActionName(HttpServletRequest req) {
        String path = req.getServletPath();
        return path.substring(path.lastIndexOf('/'),  path.lastIndexOf('.'));
    }
}

ActionFactory

记录所有动作,通过Servlet发出的动作名称得到动作类,然后对该类实例化,并返回实例对象。
起到存储所有动作、查找指定动作的目的。
示例:

package com.example;

import com.example.actions.*;

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

public class ActionFactory {
    private Map actionsMap = defaultMap();
    private static ActionFactory singleton;

    public static ActionFactory getSingleton() {
        if (singleton == null)
            singleton = new ActionFactory();
        return singleton;
    }

    public Action create(String actionName) {
        Class klass = (Class)map.get(actionName);
        if (klass == null) {
            throw new RuntimeException(getClass() + " was unable to find an action named '" + actionName + "'.");
        }
        Action actionInstance = null;
        try {
            actionInstance = (Action)kalss.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return actionInstance;
    }

    private Map defaultMap() {
        Map map = new HashMap();

        map.put("example1", example1Action.class);
        map.put("example2", example2Action.class);
        // ...

        return map;
 }

Action

动作类,继承Action接口,完成请求的各项动作。通过调用其他类来完成请求任务,并返回显示结果的jsp的URL。
Action接口

package com.example.actions;

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

public interface Action {
    public String perform(HttpServletRequest request, HttpServletResponse response);
}

示例:

package com.example.actions;

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

// import ...

public class exampleAction implements Action {
    @Override
    public String perform(HttpServletRequest req, HttpServletResponse res) {
        // do something ...
        return "/example.jsp"
    }
}

web.xml

配置当某类url到达服务器时,执行哪个servlet。比如,在这里,我们把所有以.perform为后缀的url都用咱们前面创建的com.example.exampleServlet来处理。



<web-app>
    <servlet>
        <servlet-name>exampleservlet-name>
        <servlet-class>com.example.exampleServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>exampleservlet-name>
        <url-pattern>*.performurl-pattern>
    servlet-mapping>
    <servlet-mapping>
        <servlet-name>exampleservlet-name>
        <url-pattern>index.htmlurl-pattern>
    servlet-mapping>
web-app>

体会

  • 通过动作框架,可以只编写一个的Servlet来总括系统的构建,这个Servlet为入口,解析url,通过ActionFactory得到动作,然后开始执行动作,最后返回显示结果,就完成了简单的请求访问。
  • 在构建过程中,要对动作的编写分门别类,以达到清晰明了、易于维护的目的。
  • 业务与逻辑不混合原则。专注于逻辑的实现,但不是用servlet来实现,而是用单纯的java来实现,servlet直接或间接的调用。

题外话

  • 文章开头的参考文章写的很好,有一个具体的Demo,请大家一定去看看。
  • 糙汉子,写的不好不对的地方还请您能够予以指正,感激。
  • 记得用IDE,刚开始想用Sublime来试一试,最后崩了。大神请无视。

你可能感兴趣的:(Java,Web,动作标签,Servlet)