为什么应该升级到Struts 1.1?

Struts 1.1 final已发布,新特性包括支持多子应用、DynaBean和BeanUtil、声明式异常处理、Validator等。文章分析了从Struts 1.0迁移到1.1对现有项目的影响,并针对不同规模项目给出是否升级到Struts 1.1的建议。

Struts 1.1 final终于发布了。新特性包括对多个子应用程序的支持、DynaBean和BeanUtil、声明式异常处理、Validator等。熟悉Struts的人肯定早已在用Struts 1.1,下面这篇文章是给不熟悉的人看的。

——————————————————

Introduction

Since the release of Struts 1.0, Struts has gradually become a de facto standard for MVC (a.k.a. Model-2) implementation for developing medium-to-large scale web-based applications on the Java platform. Struts fits nicely in the J2EE technology stack and fills the gap which is not addressed neither by the Servlet/JSP standard or the EJB standard. Giants like IBM and Oracle have started embracing and supporting Struts in their product set.

Built on the success of Struts 1.0, Struts 1.1 beta was released in March this year and showcased at JavaOne 2002 and the latest Struts 1.1 beta-2 was released just two weeks ago. The immediate question existing Struts users or evaluators will have is "Should I now consider to migrate my existing applications to Struts 1.1 and start to develop my new project on Struts 1.1?"

To answer this question, we need to consider what important new features are offered in 1.1 and examine what impacts there are on existing projects to migrate from 1.0 to 1.1.


New Features

Instead of overwhelming you with the full list of all the new features, I will go through the most significant enhancements in Struts 1.1 in this section.


Multiple Sub-applications

One of the shortcomings in Struts 1.0 is manageability of the configuration file (commonly known as struts-config.xml) when the development of the application involves a sizable team. This problem arises because a Struts-based application must run under one controller servlet, the ActionServlet, and the ActionServlet can use only one struts-config.xml. It is not an issue when the project is relatively small and the team consists of a couple of developers; however, when the project size becomes significant and the project involves a large number of developers, maintaining all the mapping information in a single file becomes increasingly problematic.

Struts 1.1 solves this problem nicely by introducing multiple sub-applications. In Struts 1.1, each sub-application has its own struts-config.xml file. A large Struts-based application can thus be easily partitioned into largely independent modules, i.e. sub-applications, and each sub-team can maintain their struts-config.xml independently.

The sub-application scheme is a natural extension of the servlet context mapping scheme of the URI paths used by servlet containers. According to the Servlet standard, when the servlet container receives a request with a URL, the servlet container will try to match the prefix of the URI path to a deployed web-application in the container. What Struts 1.1 does is it maps the second prefix of the path to a sub-application. In effect, this prefix mapping scheme creates another level of namespace for each sub-application. For example, for the URI,


http://some-host.com/myApp/module2/editSubscription.do


/myApp is the context path for a web-application called "myApp" and /module2 is the sub-app prefix for a Struts sub-application called "module2".


DynaBean and BeanUtils

Another major complaint usually heard amongst Struts 1.0 users is the extensive effort involved in writing the FormBean (a.k.a. ActionForm) classes.

Struts provides two-way automatic population between HTML forms and Java objects, the FormBeans. To take advantage of this however, you have to write one FormBean per HTML form. (In some use cases, a FormBean can actually be shared between multiple HTML forms. But those are specific cases.) Struts' FormBean standard follows faithfully the verbose JavaBean standard to define and access properties. Besides, to encourage a maintainable architecture, Struts enforces a pattern such that it is very difficult to 'reuse' a model-layer object (e.g. a ValueObject from the EJB tier) as a FormBean. Combining all these factors, a developer has to spend a significant amount of time to write tedious getters/setters for all the FormBean classes.

Struts 1.1 offers an alternative, Dynamic ActionForms, which are based on DynaBeans. Simply put, DynaBeans are type-safe name-value pairs (think HashMaps) but behave like normal JavaBeans with the help of the BeanUtils library. (Both the DynaBeans and the BeanUtils library were found to be useful and generic enough that they have been 'promoted' into Jakarta's Commons project.) With Dynamic ActionForms, instead of coding the tedious setters/getters, developers can declare the required properties in the struts-config.xml files. Struts will instantiate and initialize Dynamic ActionForm objects with the appropriate metadata. From then onwards, The Dynamic ActionForm instance is treated as if it is an ordinary JavaBean by Struts and the BeanUtils library.


Declarative Exception Handling

If you have developed web applications long enough, you will realize a recurring pattern emerges: when the backend (e.g. the EJB tier) throws you an exception, you nearly always need to display an error page corresponding to the type of that exception. Sooner or later, you will come up with a mechanism to use a lookup table (e.g. an HashMap) to lookup an error page from the exception class.

Struts 1.1 now provides a similar but more powerful mechanism to declare exception handling. In Struts 1.1, you can declare in the struts-config.xml the associations between an exception class and an exception handler. Using the default exception handler included in Struts, you can also specify the path of the error pages. With this information, Struts will automatically forward to the specified pages when an uncaught exception is thrown from an Action.

Like other facilities in Struts, the exception handlers are pluggable. You can write and define your own handler classes if needed.


Validator

The Validator is not exactly a new feature. The Validator has been in the contrib package in the distribution since Struts 1.0.1. Since then, part of it has now been refactored and moved into the Jakarta-Commons subproject and renamed the Commons-Validator and the Struts specific portion is now called the Struts-Validator. However, since it is in the contrib package, people may overlook it and it is worthwhile to mention it here.

The Validator provides an extensible framework to define validation rules to validate user inputs in forms. What is appealing in the Validator is that it generates both the server-side validation code and the client-side validation code (i.e. Javascript) from the same set of validation rules defined in an XML configuration file. The Validator performs the validation based on regular-expression pattern matching. While a handful of commonly used validators are shipped with the framework (e.g. date validator, range validator), you can always define your own ones to suit your need.


Impact

Having gone through the list of exciting new features, it is time to examine the potentially negative impact of these enchacements. One of the highest priorities of the Struts' developer community when developing Struts 1.1 has been to achieve maximum backward compatibility with 1.0. Struts' developers have definitely done a good job in this regard; however, there are still some issues you need to be aware of.


Default Sub-application

To maintain backward compatibility, Struts 1.1 allows one default sub-application per application. The URI of the resources (i.e. JSPs, HTMLs, etc) in the default sub-application will have an empty sub-app prefix. This means when an existing 1.0 application is "dropped" into Struts 1.1, theoretically, it will automatically become the default sub-application.


Direct Requests to JSPs

To take the full advantage of sub-application support, Struts 1.1 stipulates the requirement that all requests must flow through the controller servlet, i.e. the ActionServlet. Effectively, this means all JSPs must be fronted by Actions. Instead of allowing direct requests to any of the JSPs, all requests must go through an Action and let the Action forward to the appropriate JSP.

This is perhaps the biggest impact of migration to Struts 1.1 if you have not followed this idiom in your applications. This restriction is required because without going through the ActionServlet, Struts navigation taglibs (e.g. <html:form> and <html:link>) used in the JSPs will not have the correct sub-app context to work with.


ActionServlet Configurations

With the introduction of sub-applications, a more flexible way is introduced to configure each sub-application independently. Many of the configuration entries (e.g. resource bundle location, maximum upload file size, etc) that used to be defined in web.xml have now been moved to struts-config.xml. The original entries in web.xml are deprecated but will still be effective.


Path-mapped Actions

Both extension-mapped (e.g. *.do) and path-mapped (e.g. /do/*) Actions are supported in Struts 1.0. However, at the time of writing (August 2002), mulitple sub-applications will not work with path-mapped Actions. It is likely this issue will be resolved in the final release of Struts 1.1.


Action.execute() and Action.getResources()

In Struts 1.0, request handling logic is coded in Action.perform(); however, Action.perform() throws only IOException and SevletException. To facilitate the new declarative exception handling , the request handling method needs to throw Exception, the superclass of all the checked exceptions. Therefore, to both maintain backward compatibility and facilitate declarative exception handling, Action.perform() is now deprecated in favour of Action.execute().

You also have to be careful if you use DispatchAction in your existing applications. At the time of writing, the DispatchAction in Struts 1.1 beta has not yet been updated to use execute(). (A bug report has been filed in Struts' bug database.) Therefore, without modifying the DispatchAction class yourself, declarative exception handling will not work with DispatchAction subclasses.

In addition, Action.getResources() is now deprecated. Instead, you should call Action.getResources(HttpServletRequest) instead. This allows Struts to return to you the sub-application specific message resources. Otherwise, the message resources for the default sub-app will be used.


Library Dependency

Struts 1.1 now depends on a handful of libraries from other Jakarta subprojects (e.g. Commons-Logging, Commons-Collections, etc.). Some of these libraries may cause classloading conflicts in some servlet containers. So far, people have reported in the mailing list the classloading problem of commons-digester/jaxp1.1, and commons-logging causing deployment difficulties in Struts 1.1 applications running on Weblogic 6.0. (The problems have been corrected in Weblogic 6.1 and 7.0.)


Resources under WEB-INF

According to the Servlet specification, resources (e.g. JSP files) stored under WEB-INF are protected and cannot be accessed directly by the browsers. One design idiom for Struts 1.0 is to put all the JSP files under WEB-INF and front them by Actions so that clients cannot illegally access the JSPs.

With the introduction of sub-application prefixes in Struts 1.1, mapping resources under WEB-INF gets complicated. Extra configuration steps utilizing the pagePattern and forwardPattern attributes of the <controller> element in struts-config.xml is required to inform Struts to construct the paths correctly. More specifically, you need to set these attributes to the pattern "/WEB-INF/$A$P".


Miscellenous issues for advanced users

The following issues are relevant to you if you are a power Struts user and make use of some advanced features in Struts:

  • If your application depends on the ActionFormBeans, ActionForwards or ActionMappings servlet context attributes, you have to get the information they need from the ApplicationConfig object instead.

  • If you subclass ActionServlet, you may have to retrofit it back to that of Struts 1.1 or the new RequestProcessor class as ActionServlet has been refactored.


Conclusion

So, "Should I consider upgrading to Struts 1.1?" Here are my recommendations.


For Existing Small Projects

If you have a relatively small project and are happy with what Struts 1.0 currently offers, it makes sense to stay with Struts 1.0.


For Existing Medium-to-Large Projects

If you have a large project, the multiple sub-application feature is definitely the overriding factor in influencing your decision. The litmus test is to ask yourself this question: "Is the existing struts-config.xml file getting very difficult to manage due to its sheer file size?" If the answer is yes, you should consider doing a pilot trial to replace Struts 1.0 with Struts 1.1 in your development environment without partitioning your application into sub-applications first.

Since Struts 1.1 can treat your existing application simply as the default sub-application, the replacement should be straightforward. However, to test if your application is actually Struts 1.1 compliant, you should configure it as a sub-application with a non-empty prefix and go through some representative use cases to test and see if the application works as it used to be. Before you embark onto the pilot trial, you have to make sure all of your developers are aware of the issues listed in the previous section, particularly the requirement that all requests must go through the controller servlet as it is quite likely that that may not the case in your application. You need their input to decide if the migration is feasible or not.

Once the pilot trial is successful and you decide to migrate to Struts 1.1, you can start to work out how to partition the application into sub-applications with adequate granularity. Being able to partition the application into sub-applications, you may also want to consider reorganizing your team structure and the project structure of your source code control to align with the partitioning.


For New Projects

If your project is a new one, the decision to use Struts 1.1 mainly depends on the amount of risk your project can take. Struts 1.0 is a proven technology but Struts 1.1 is still in beta. Besides, migrating backwards is always more difficult than migrating forwards. Once you start with Struts 1.1, it will involve a lot of hard work to go back to Struts 1.0. While the extra risk in using Struts 1.1 is generally very low (as the quality of work from Apache's developer community has been consistently very good), it is still a non-negligible factor you have to consider.



About the Author

John Yu is the co-founder and chief scientist at Scioworks Technologies, an enterprise software consulting and products company based in Singapore. He is the primary designer of Scioworks Camino, a visual modelling tool for developing Struts applications. John's J2EE/EJB experience dates back to a pilot project he led implemented on Tengah, what Weblogic AppServer was called before Weblogic was acquired by BEA, when he was a designer/architect working in Australia. John holds a Masters degree of Computing from Monash University, Australia and a Postgraduate Diploma in Management from Melbourne Business School, Australia. He was awarded the Telstra Research Fellowship and the Australia Postgraduate Award.

内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值