多模式 Web 应用开发记录<二>自己动手写一个 Struts

相关文章:

相关源码地址:

  • • https://github.com/dongguabai/dongguabai-struts

背景

前文也提到过,由于服务的拆分,后续会将我们现在的 Web 应用改造成结合了静态页面渲染和动态数据交互的多模式 Web 应用,也就是存在从 Spring + FreeMarker + Struts2 迁移到 Spring Boot + Spring Web MVC + FreeMarker 的技术栈迁移。既然要迁移,那必然要对 Struts2 和 FreeMarker 这样的技术有一定的了解。

不过在 Spring Boot 大行其道的今天,以及越来越多的前后端分离开发模式,SSH 早已风光不再,很多年轻的同学甚至都不知道 Struts2,如果快速的了解 Struts2 和 FreeMarker 这种模版引擎呢?

正如我在自己动手写一个 Arthas 在线诊断工具&系列说明表达的观点,通过自己动手实现一个,从而抓大放小,快速理解框架的设计原理和工作机制,从而对框架有一个基本的认知

实现

本文实现了一个非常简单的 Struts,支持简单的参数绑定和 JSP 页面的渲染。实现也非常的简单,总共只有 2 个核心类。

首先定义一个抽象的 Action

/**
 * @author Dongguabai
 * @description
 * @date 2024-02-28 10:18
 */

public interface Action {

    String execute(HttpServletRequest request, HttpServletResponse response);
}

定义一个 Servlet 负责分发请求,和参数绑定:

/**
 * @author dongguabai
 * @date 2024-02-28 12:05
 */

public class ActionServlet extends HttpServlet {

    private Map<String, Class<? extends Action>> actions = new HashMap<>();

    @Override
    public void init() throws ServletException {
        //读取配置或者扫描上下问都行
        actions.put("/hello", HelloWorldAction.class);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String actionPath = req.getPathInfo();
        if (actionPath.endsWith(".jsp")) {
            req.getServletContext().getNamedDispatcher("jsp").forward(req, resp);
        } else {
            Class<? extends Action> clazz = actions.get(actionPath);
            if (clazz != null) {
                Action action = null;
                try {
                    action = clazz.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
                Map<String, String[]> paramMap = req.getParameterMap();
                for (String paramName : paramMap.keySet()) {
                    String[] paramValues = paramMap.get(paramName);
                    for (String paramValue : paramValues) {
                        Field field;
                        try {
                            field = clazz.getDeclaredField(paramName);
                            if (field != null) {
                                field.setAccessible(true);
                                field.set(action, paramValue);
                            }
                        } catch (Exception e) {
                        }
                    }
                }
                String view = action.execute(req, resp);
                req.getRequestDispatcher(view).forward(req, resp);
            } else {
                resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            }
        }
    }
}

定义业务 Action

/**
 * @author dongguabai
 * @date 2024-02-28 10:18
 */

public class HelloWorldAction implements Action {

    // message 参数绑定
    private String message;

    @Override
    public String execute(HttpServletRequest request, HttpServletResponse response) {
        //将前端的参数反转专递给前端
        request.setAttribute("message"new StringBuilder(message).reverse().toString());
        return "/hello.jsp";
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

业务的 JSP 页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Hello</title>
</head>
<body>
<h1>下面是Message的内容:</h1>
<h1>${message}</h1>
</body>
</html>

我这里使用的内嵌 Tomcat:

/**
 * @author dongguabai
 * @date 2024-02-28 12:05
 */

public class StartUp {

    public static void main(String[] args) throws LifecycleException {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(Integer.getInteger("port"8080));
        tomcat.getConnector();
        String webappDirLocation = "target/classes/";
        Context context = tomcat.addWebapp(""new File(webappDirLocation).getAbsolutePath());
        Wrapper jspServlet = Tomcat.addServlet(context, "jsp"new JspServlet());
        jspServlet.addInitParameter("development""true");
        jspServlet.addInitParameter("org.apache.jasper.compiler.Parser.EL_IGNORE""false");
        context.addServletMappingDecoded("*.jsp""jsp");
        Tomcat.addServlet(context, "dispatcherServlet"new ActionServlet());
        context.addServletMappingDecoded("/*""dispatcherServlet");
        tomcat.start();
        tomcat.getServer().await();
    }
}

启动后在浏览器访问:

多模式 Web 应用开发记录<二>自己动手写一个 Struts

可以看到传递的“hello”参数被反转了,实现的 Struts 运行成功!

原文始发于微信公众号(冬瓜白):多模式 Web 应用开发记录<二>自己动手写一个 Struts

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/222821.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!