从单体服务到微服务:多模式 Web 应用开发记录<三>预初始化属性

相关文章:

  • 多模式 Web 应用开发记录<一>背景&全局变量优化
  • 多模式 Web 应用开发记录<二>自己动手写一个 Struts

开头先看一个简单的例子,这是 ftl 文件的一个表单:

<form id="validateForm" action="#" method="post">  
		<div style="padding: 10px 0;" class="ft14">处理信息:</div>  
		    <table class="inputTable">
				<tr> 
		   			<th>
						备注:
					</th>
					<td>  
						 <textarea cols="10" rows="3"  name="repairVO.remark" class="formTextarea" ></textarea>
					</td>
			    </tr>
			</table>
			<div  class="buttonArea" id="option">
			    <input class="btn btn-big" action="doProcess.action" type="submit" value="处理"/>
			    <input class="btn btn-big" action="doCancel.action" type="submit" value="取消"/>
			    <input type="hidden" name="bizId" value="${(bizId)!}"></input>
			</div>
		</form>

单看这个表单,只会传递两个参数:bizIdrepairVO.remark。所以后端 Struts 的 Action 的成员属性会接收 remark

private RepairVO repairVO;

	public String doProcess() {
		try {
			logger.info("repairVO:{}" , JsonUtils.toJsonString(repairVO));
			//...其他业务处理
			return SUCCESS;
		} catch (Exception e) {
			return ERROR;
		}
	}

正常来说这里的 repairVO 应该只有 remark 属性有数据,可我这里调试发现 repairVO 居然还有其他的属性也有值。

经过排查发现是因为 Action 里面对于 repairVO 有个特殊的 setter 方法:

	public void setRepairVO(RepairVO repairVO) {
		if(repairVO==null){
			repairVO = new RepairVO();
		}
		if(repairVO.getId()==null){
			repairVO.setId(this.getBizId());
		}
		repairVO.setOrgId(this.getAdmin().getOrgId());
		repairVO.setOperateTime(new Date());
		repairVO.setOperatorId(this.getAdmin().getId());
		repairVO.setOperatorName(this.getAdmin().getUsername());
		this.repairVO = repairVO;
	}

这是因为在 Struts2 中,当一个 Action 被调用时,Struts2 会尝试将 HTTP 请求的参数绑定到 Action 的属性。这个过程是通过调用 Action 的 setter 方法完成的。相当于这里对 repairVO 进行了预初始化属性。

这个原理其实也很容易理解,在多模式 Web 应用开发记录<二>自己动手写一个 Struts中实现的 Struts 中是通过反射直接对属性进行赋值,从而进行参数绑定:

   @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);
            }
        }
    }

这里完全可以改成基于 setter 方法进行参数绑定,那么就可以实现跟 Struts2 类似的“预初始化属性”机制。

那么在 Spring MVC 中如何实现呢,可以直接使用 @ModelAttribute 注解:

    @ModelAttribute("repairVO")
    public RepairParam setup() {
        RepairParam repairVO = new RepairParam();
        User currentUser = getCurrentUser();
        repairVO.setOrgId(currentUser.getOrgId());
        repairVO.setOperateTime(new Date());
        repairVO.setOperatorId(currentUser.getId());
        repairVO.setOperatorName(currentUser.getUsername());
        return repairVO;
    }

		    @RequestMapping("doProcess.action")
    public String doProcess(@RequestParam("bizId") String bizId, @ModelAttribute("repairVO") RepairParam repairVO, Model model) {
        //...其他业务逻辑
    }

这里 doProcess 函数的 repairVO 对象就包括 setup 函数的预初始化属性和请求中的 repairVO.xxx 属性。也就实现了预初始化属性的设置。

欢迎关注公众号:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/417905.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【程序员是如何看待“祖传代码”的?】《代码的遗产:探索程序员眼中的“祖传代码”》

程序员是如何看待“祖传代码”的&#xff1f; 在程序员的世界里&#xff0c;代码不仅仅是构建软件的基石&#xff0c;它们也承载着历史、智慧和技术的演变。在我的编程生涯中&#xff0c;我遇到过许多神奇而独特的“祖传代码”&#xff0c;这些代码如同古老的魔法书&#xff0…

【C语言】三子棋

前言&#xff1a; 三子棋是一种民间传统游戏&#xff0c;又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏规则是双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#xff0c;率先将自己的三个棋子走成一条线就视为胜利。但因棋盘太小&#xff0c;三子棋在很多时候会出现和…

C++面试常见八股分享

1.unordered_set和set&#xff0c;unordered_map和map的区别 set 和 map 是 C STL 中的两种关联容器&#xff0c;而 unordered_set 和 unordered_map 是 C11 新增的基于哈希表的关联容器。它们之间的主要区别在于底层的数据结构和操作复杂度。 set 和 unordered_set&#xff1…

黑马程序员——接口测试——day05——Request库、Cookie、Session、UnitTest框架

目录&#xff1a; Requests库 Requests库安装和简介设置http请求语法应用案例 案例1案例2案例3案例4Cookie Cookie简介CookieSession认证方式案例5-看演示&#xff0c;此代码不需实现Session Session简介Session自动管理Cookie案例6面试题Cookie和Session区别获取指定响应数据…

云原生架构技术揭秘:探索容器技术的奥秘

云原生的概念和演进都是围绕云计算的核心价值展开的&#xff0c;比如弹性、自动化、韧性&#xff0c;所以云原生所涵盖的技术领域非常丰富。 随着云计算技术的不断发展&#xff0c;云原生架构已经成为了新一代软件开发的重要趋势。本文将为您介绍云原生架构的相关技术&#xf…

单片机精进之路-9ds18b20温度传感器

ds18b20复位时序图&#xff0c;先将b20的数据引脚拉低至少480us&#xff0c;然后再将数据引脚拉高15-60us&#xff0c;再去将测传感器的数据引脚是不是变低电平并保持60-240us&#xff0c;如果是&#xff0c;则说明检测到温度传感器&#xff0c;并正常工作。需要在240us后才能检…

鸿蒙真有前景吗?是真是假?

直到“纯血鸿蒙”发布&#xff0c;才看清华为真正的布局&#xff0c;这一招实在是高明&#xff01; “纯血鸿蒙”发布之前&#xff0c;国内大批人唱衰华为&#xff0c;唱衰鸿蒙系统的生态&#xff0c;认为大概率会走诺基亚和微软的老路&#xff0c;没想到“纯血鸿蒙”一经推出…

高质 智能 绿色低碳棒线材轧制 智能测径仪等亦起关键作用

第十一届棒线材会议围绕推动轧钢装备数字化、智能化、绿色化转型升级&#xff0c;实现高质量发展&#xff0c;高质量、智能化、绿色低碳主题&#xff0c;将于4月22-24日在贵州省六盘水市召开。这也是轧钢生产近几年的发展趋势。 在线棒材生产中&#xff0c;蓝鹏测控可提供三种类…

每天十条linux知识点-24-0226(1)

文章目录 1.在哪下载linux内核源码&#xff1f;2.linux文件夹都有哪些文件&#xff1f;arch&#xff1a;包含和硬件体系结构相关的代码&#xff0c;每种平台占一个相应的目录&#xff0c;如i386、arm、arm64、powerpc、mips等。block&#xff1a;块设备驱动程序I/O调度。certs&…

又降价啦!2024年腾讯云服务器优惠价格表,不看后悔!

腾讯云服务器多少钱一年&#xff1f;62元一年起&#xff0c;2核2G3M配置&#xff0c;腾讯云2核4G5M轻量应用服务器218元一年、756元3年&#xff0c;4核16G12M服务器32元1个月、312元一年&#xff0c;8核32G22M服务器115元1个月、345元3个月&#xff0c;腾讯云服务器网txyfwq.co…

高级语言期末2010级B卷(软件学院)

1.编写程序根据如下公式计算X的值&#xff08;精确到1e-5&#xff09;。 #include <stdio.h>int main(){int i1;double flag1.0/(2*i-1)*2.0*i/(2*i-1);double sum0;while(flag>1e-5){sumflag;i;flag1.0/(2*i-1)*2.0*i/(2*i-1);}printf("%lf",sum);return 0…

千兆单口(百兆双口)小体积 24PIN 网络变压器 H82409S 特点

Hqst华轩盛(石门盈盛)电子导读&#xff1a;千兆单口&#xff08;百兆双口&#xff09;小体积 24PIN 网络变压器 H82409S 特点 大家好&#xff0c;石门盈盛电子科技有限公司工程盛先生&#xff0c;今天向大家介绍石门盈盛电子科技有限公司的一款优势产品 - 千兆单口&#xff08;…

Docker(第四部分)

Docker微服务实战 通过IDEA新建一个普通微服务模块 把包放到linux机器里 pwd 通过dockerfile发布微服务部署到docker容器 dockerfile的内容 防火墙 Docker网络 网络主机 是什么&#xff1f; 网桥virbr0 常用基本命令 能干嘛 网络模式 最后都和u3一样了 结论&#xff1a;doc…

【Java程序设计】【C00329】基于Springboot的高校实习管理系统(有论文)

基于Springboot的高校实习管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的高校实习管理系统&#xff0c;本系统有管理员、公司、老师和学生四种角色&#xff1b; 管理员&#xff1a;个人中心、公司管理、…

故障排除:Failed to load SQL Modules into database Cluster

PostgreSQL 安装和故障排除 重新安装前的准备工作 在重新安装 PostgreSQL 之前&#xff0c;确保完成以下步骤&#xff1a; 重新卸载 PostgreSQL 并重启电脑。 删除以下目录&#xff1a; C:\Program Files\PostgreSQL\13C:\Users\admin\AppData\Roaming\pgadmin 重启安装过…

CentOS7——主机动态地址修改为静态地址

目录 1、查看本机的网络配置&#xff08;vmnet8网关&#xff09; 2、修改虚拟机主机网络信息配置文件 3、重启network服务使生效 4、测试 1、查看本机的网络配置&#xff08;vmnet8网关&#xff09; windows&#xff1a;“网络图标”——>“属性”——>“网络和共享中…

认识内部类

成员内部类 静态内部类 局部内部类 匿名内部类&#xff01;&#xff01;&#xff01;&#xff08;重点&#xff09; 匿名内部类在开发中常见的使用场景&#xff1a;通常作为一个参数传输给方法。

推荐系统经典模型YouTubeDNN代码

文章目录 前言数据预处理部分模型训练预测部分总结与问答 前言 上一篇讲到过YouTubeDNN论文部分内容&#xff0c;但是没有代码部分。最近网上教学视频里看到一段关于YouTubeDNN召回算法的代码&#xff0c;现在我分享一下给大家参考看一下&#xff0c;并附上一些我对代码的理解…

微信小程序真机调试:连接局域网失败ws://********:8001/失败,已切换回广域网模式的解决方式

这个问题大多数是由于系统上安装了虚拟网卡造成&#xff0c;只要禁用虚拟网卡即可查询方式&#xff1a;windx - 选择设备管理器 - 查看网络适配器&#xff0c;找到虚拟网卡禁用 重新勾选局域网模式进行调试即可

Go 互斥锁的实现原理?

Go sync包提供了两种锁类型&#xff1a;互斥锁sync.Mutex 和 读写互斥锁sync.RWMutex&#xff0c;都属于悲观锁。 概念 Mutex是互斥锁&#xff0c;当一个 goroutine 获得了锁后&#xff0c;其他 goroutine 不能获取锁&#xff08;只能存在一个写者或读者&#xff0c;不能同时…