相关文章:
相关源码地址:
-
• 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();
}
}
启动后在浏览器访问:
可以看到传递的“hello”参数被反转了,实现的 Struts 运行成功!
原文始发于微信公众号(冬瓜白):多模式 Web 应用开发记录<二>自己动手写一个 Struts
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/222821.html