对 Action 的初步构思

本文介绍如何结合Struct、SpringMVC和REST(JAX-RS)创建简化且实用的Action,包括使用注解配置请求与响应,以及如何处理参数验证和返回结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文是《轻量级 Java Web 框架架构设计》的系列博文。

用过 Struct 的同学们应该都知道 Action 的概念吧?在 Spring MVC 中对应的是 Controller。此外,Spring MVC 也提供了基于注解的配置方式,例如,@Controller、@RequestMapping 等。这些注解给了我们很多帮助,让我们不再编写繁重的 XML 配置了。现在我想做的是一个结合了 Struct 与 Spring MVC 以及现今较为流行的 REST(JAX-RS),打造一个更加简化又更加实用的 Action。由于本框架不打算使用 MVC 架构,所以没有用 Controller 这个术语,而改用更加通俗易懂的 Action。

下面以 ProductAction 为例,展示了如何编写 Action 类,代码如下:

@Action
public class ProductAction {
    @Inject
    private ProductService productService;

    @Request(url = "/product/{id}", method = RequestMethod.GET)
    @Response(ResponseType.JSON)
    public Result getProductById(@PathParam("id") long productId) {
        if (productId == 0) {
            return new Result(ResultError.ERROR_PARAM_INVALID);
        }
        Product product = productService.getProduct(productId);
        if (product != null) {
            return new Result(ResultError.OK, product);
        } else {
            return new Result(ResultError.ERROR_DATA_NULL);
        }
    }
}

想必用过 Spring MVC 的同学都能看得懂,不过还是有必要稍微解释一下:

第1行:使用 @Action 注解用于表明该类是一个 Action,框架会自动加载它。

第3行:使用 @Inject 注解用于注入一个对象,类似于 Spring 中的 @Autowired。

第6行:使用 @Request 注解用于配置请求与 Action 方法之间的映射关系,类似于 Spring 中的 @RequestMapping。

第7行:使用 @Response 注解用于定义该方法的返回值(也就是 Result 对象)将被序列化为哪种类型的数据,可选择 JSON 或 XML,借鉴于 JAX-RS 的 @Produces。

第8行:使用 @PathParam 注解来映射 @Request 注解 url 属性中的路径参数,类似于 Spring 中的 @PathParam,同样 JAX-RS 中也有 @PathParam。此外,还会提供一系列的 @XxxPram 注解,例如,@QueryParam、@FormParam、@HeaderParam等。

第9~11行:验证请求参数,若参数无效,则返回 ResultError.ERROR_PARAM_INVALID。在常量接口 ResultError 中定义了一些列的错误代码,例如:OK 表示正确,值为1;ERROR_PARAM_INVALID 表示参数无效,值为100;ERROR_DATA_NULL 表示数据为空,值为200。这些错误代码可在服务端事先定义好,并直接返回到客户端,而客户端通过错误代码来给出错误提示信息。

第12行:调用服务接口中的方法,并获取返回值。

第13~17行:判断服务接口的返回值是否为空,若非空,则返回正确结果,否则返回错误结果。在正确结果对象 Result 中,包含一个 Object 类型的属性,用于存放返回到客户端的返回值,即 product 对象,而错误结果中无需给定这个属性,该属性的值默认为 null。

请大家对以上构思,给一些评价吧!


补充(2013-09-03)

方案二:

@Request(url = "/product", method = "GET")
public Result getProductById(HttpServletRequest request) {
    long productId = Integer.parseLong(request.getParameter("id"));
    if (productId == 0) {
        return new Result(ResultError.ERROR_PARAM_INVALID);
    }
    Product product = productService.getProduct(productId);
    if (product != null) {
        return new Result(ResultError.OK, product);
    } else {
        return new Result(ResultError.ERROR_DATA_NULL);
    }
}

此方案实现起来最为简单,但需要与 Servlet API 依赖,所有的参数必须通过 Request 对象获取,而且不支持 REST 风格的 URL(只能是 /product?id=1 这样的)。此外,单元测试也比较痛苦,需要 mock 出 Request 对象。

方案三:

@Request("GET:/product/{id}")
public Result getProductById(long productId) {
    if (productId == 0) {
        return new Result(ERROR_PARAM);
    }
    Product product = productService.getProduct(productId);
    if (product != null) {
        return new Result(OK, product);
    } else {
        return new Result(ERROR_DATA);
    }
}
此方案是对方案一的改进,@Request 注解中是提供一个 URL 字符串即可,同时支持占位符。方法参数中,将 URL 的 {id} 匹配 productId。注意:这里是 Spring MVC 注解的简化,在 Spring MVC 中,如果 URL 中的占位符与方法参数命名不一致,则必须使用 @PathParam 注解进行标示,否则无法映射。这里是根据 URL 中占位符出现的顺序自动自动匹配方法参数,若 URL 占位符与方法参数不匹配,则不会执行方法体。此外,简化了常量的使用方法,可定义一个 Action 父类,其中定义一些列的常量,包含:OK、ERROR_PARAM、ERROR_DATA 等,可在应用开发过程中进行扩展。

转载于:https://my.oschina.net/huangyong/blog/158470

### 系统流程图绘制教程 系统流程图是一种用于描述系统内部各组成部分之间关系以及数据流动情况的图形化表达方式。通过绘制系统流程图,可以更清楚地理解系统的运作机制并优化其性能。 #### 常见工具推荐 目前市面上有许多优秀的工具可用于绘制系统流程图,其中包括但不限于以下几种: - **Draw.io**: 这是一款免费且易于使用的在线工具,支持多种平台访问,并提供丰富的图标库来满足不同类型的流程图需求[^1]。 - **MindMaster**: 除了强大的思维导图功能外,它还集成了完善的流程图编辑器,适合初学者快速上手[^2]。 - **AutoCAD**: 对于需要精确度较高的工程类项目来说,利用AutoCAD能够实现复杂而细致的设计方案[^3]。 - **Microsoft Visio**: 作为微软办公套件的一部分,Visio以其专业化程度高著称,在业务分析和技术文档编写领域应用广泛[^4]。 #### 绘制方法概述 无论采用何种具体软件进行操作,一般遵循以下几个原则来进行系统流程图的构建: 1. 明确目标:确定要描绘哪个具体的子系统或者整个大系统; 2. 收集资料:整理出所有必要的输入输出端口及其相互间的关系; 3. 设计草稿:先用手绘形式勾勒大致框架以便后续调整完善; 4. 使用专业工具细化:借助上述提到的各种应用程序将初步构思转化为正式版面布局合理美观大方的作品。 下面给出一段Python伪代码示例演示如何模拟简单的程序逻辑转换成对应的节点连接结构: ```python def create_system_flowchart(): start_node = Node("Start") process_one = ProcessNode("Receive Data") decision_point = DecisionNode("Is Valid?") valid_path = Path(process_one, decision_point) invalid_action = ActionNode("Log Error") end_state = EndNode("End") connect(valid_path, TrueBranch(decision_point), end_state) connect(FalseBranch(decision_point), invalid_action) create_system_flowchart() ``` 此段代码仅作为一个抽象概念模型展示用途,并不代表实际可运行脚本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值