标记模板字面量_使用模板将Web服务结果转换为标记

标记模板字面量

重要要点

  • HTTP-RPC是用于以Java构建REST服务的开源框架
  • 可以通过单个代码库为Web,移动和桌面客户端提供服务
  • 默认提供JSON响应数据
  • 通过模板支持基于HTML的资源表示
  • 还可以生成XML,CSV等

Web服务是实现可通过HTTP远程访问的应用程序逻辑的一种方式。 它们允许分布式客户端(通常是异构客户端)与服务器端功能进行交互,并且通常用于为移动应用程序提供后端API。 但是,通常使用与应用程序Web前端不同的软件堆栈来实现它们,从而导致额外的开发和维护工作。

模板是一种将数据与表示分离的方法。 它们允许独立于数据本身指定数据结构的最终输出格式,从而促进职责的明确分离。 在MVC术语中,模板表示视图,数据表示模型。 Web服务充当控制器,接受来自调用者的输入,生成模型数据,并将模板应用于模型以产生最终结果。

本文介绍了如何使用CTemplate系统(又名Mustache )编写的模板可用于将使用HTTP-RPC框架实现的Web服务的输出转换为HTML。 这使应用程序可以从单个代码库有效地为Web和移动客户端提供服务,从而大大减少了总体开发工作。

HTTP-RPC

HTTP-RPC是一个开放源代码框架,用于简化基于REST的应用程序的开发。 它允许开发人员使用便捷的类似RPC的隐喻来创建和访问基于HTTP的Web服务,同时保留基本的REST原理,例如无状态和统一资源访问。 有关HTTP-RPC的更多信息,我的前一篇文章提供了广泛的概述。

通过将HTTP动词(例如GET或POST)应用于目标资源来访问HTTP-RPC服务。 目标由表示资源名称的路径指定,并且通常表示为名词,例如/ calendar/ contacts

通过查询字符串或在请求正文中提供参数,例如HTML表单。 尽管服务可以产生任何类型的内容,但是结果通常以JSON返回。 还支持不返回值的操作。

例如,以下请求可能会检索两个数字的和,其值由查询参数“ a”和“ b”指定:

GET /math/sum?a=2&b=4

服务将返回值6作为响应。

示例服务

WebService是HTTP-RPC Web服务的抽象基类。 通过将公共方法添加到具体的服务实现中来定义服务操作。

@RPC批注用于将方法标记为可远程访问。 该注释将HTTP动词和资源路径与该方法相关联。 发布服务后,所有带有公共注释的方法将自动变为可用于远程执行。

例如,以下类可能用于实现上一节中讨论的简单加法运算:

public class MathService extends WebService {
    @RPC(method="GET", path="sum")
    public double getSum(double a, double b) {
        return a + b;
    }
}

作为另一个示例,请考虑以下方法,该方法将计算一组简单的统计值:

@RPC(method="GET", path="statistics")
public Map<String, ?> getStatistics(List<Double> values) {
    int count = values.size();

    double sum = 0;

    for (double value : values) {
        sum += value;
    }

    double average = sum / count;

    return mapOf(
        entry("count", count), 
        entry("sum", sum), 
        entry("average", average)
    );
}

此URL的GET将调用该方法,并传递包含值1、3和5的列表参数:

/math/statistics?values=1&values=3&values=5

结果将返回给调用方,如下所示:

{
  "count": 3, 
  "sum": 9.0,
  "average": 3.0
}

C模板

尽管HTTP-RPC Web服务生成的数据通常以JSON形式返回,但在某些情况下以不同的格式将结果返回给调用者可能更方便。 例如,作为HTML以支持基于浏览器的客户端应用程序。 HTTP-RPC本身提供对使用CTemplate系统定义的模板的支持,从而允许将任意转换应用于方法结果。

CTemplate定义了一组“标记”,在处理模板时,这些标记被“数据字典”提供的值替换:

  • {{_variable_}} -将数据字典中的变量注入到输出中
  • {{#_section_}} ... {{/ _section _}} -定义内容的重复部分
  • {{> include}} -导入另一个模板指定的内容
  • {{!_comment_}} -提供有关模板内容的信息性文本

服务方法返回的值表示数据字典。 通常,这将是java.util.Map的一个实例,其键代表字典提供的值。

下面显示了一个简单的模板,用于将getStatistics()方法的结果显示为网页:

<html>
<head>
    <title>Statistics</title>
</head>
<body>
    <p>Count: {{count}}</p>
    <p>Sum: {{sum}}</p>
    <p>Average: {{average}}</p> 
</body>
</html>

注意变量标记用于“计数”,“和”和“平均值”值。 在执行时,这些标记将被数据字典中的相应值(即方法返回的映射值)替换以产生最终输出。

模板注释

@Template批注用于将模板文档与方法关联。 批注的值表示将应用于结果的模板的名称和类型。 例如:

@RPC(method="GET", path="statistics")
@Template(name="statistics.html", mimeType="text/html")
public Map<String, ?> getStatistics(List<Double> values) { ... }

“名称”元素是指包含模板定义的文件。 它被指定为相对于服务类型的资源路径。

“ contentType”元素指示由命名模板产生的内容的类型。 HTTP-RPC使用它来标识请求的模板。 通过将与所需的MIME类型关联的文件扩展名附加到URL中的服务名称来请求特定的表示形式。

应用注释后,用于statistics.html的GET将调用getStatistics()方法并将模板应用于结果:

<html>
<head>
    <title>Statistics</title>
</head>
<body>
    <p>Count: 3.0</p>
    <p>Sum: 9.0</p>
    <p>Average: 3.0</p> 
</body>
</html>

结果与以下命令的输出相同,该命令使用curl下载原始的JSON响应,然后使用mustache命令应用模板:

curl -s "http://localhost/math/statistics?values=1&values=3&values=5" | mustache - statistics.html

由于HTTP-RPC在服务器上应用了模板,因此不需要客户端处理。 但是,curl是在开发过程中测试模板的好方法。

一个实际的例子

对于一个更实际的示例,请考虑从BIRT示例数据库中获取下表中返回SQL查询结果的Web服务:

CREATE TABLE Products (
  productCode VARCHAR(50) NOT NULL,
  productName VARCHAR(70) NOT NULL,
  productLine VARCHAR(50) NOT NULL,
  productScale VARCHAR(10) NOT NULL,
  productVendor VARCHAR(50) NOT NULL,
  productDescription TEXT NOT NULL,
  quantityInStock SMALLINT NOT NULL,
  buyPrice DOUBLE NOT NULL,
  MSRP DOUBLE NOT NULL,
  PRIMARY KEY (productCode)
);

可以定义返回此表内容的服务方法,如下所示。 ResultSetAdapter类允许从服务方法有效地返回SQL查询的结果。 它实现了List接口,并使JDBC结果集中的每一行都显示为Map的实例,从而呈现了适合序列化为JSON的数据。 HTTP-RPC确保在写入所有数据后关闭结果集:

@RPC(method="GET")
@Template(name="products.html", contentType="text/html")
public ResultSetAdapter getProducts() throws SQLException {
    Statement statement = getConnection().createStatement();
    String sql = "SELECT * FROM Products";

    return new ResultSetAdapter(statement.executeQuery(sql));
}

服务方法的原始JSON输出可能类似于以下内容,可以由移动应用程序轻松使用:

[
  {
    "productCode": "S10_1678",
    "productName": "1969 Harley Davidson Ultimate Chopper",
    "productLine": "Motorcycles",
    "productScale": "1:10",
    "productVendor": "Min Lin Diecast",
    "productDescription": "This replica features working kickstand...",
    "quantityInStock": 7932,
    "buyPrice": 48.81,
    "MSRP": 95.7
  },
  ...
]

以下模板可用于将结果转换为HTML,适合在Web浏览器中呈现。 请注意,该示例使用“ ^ html”修饰符来确保输出已正确进行HTML编码。 修改器在项目文档中进行了更详细的讨论:

<html>
<head>
    <title>Product List</title>
</head>
<body>
    <table>
    {{#.}}<tr>
    <td>{{productCode:^html}}</td>
    <td>{{productName:^html}}</td>
    <td>{{productLine:^html}}</td>
    <td>{{productScale:^html}}</td>
    <td>{{productVendor:^html}}</td>
    <td>{{productDescription:^html}}</td>
    <td>{{quantityInStock}}</td>
    <td>{{buyPrice:format=currency}}</td>
    <td>{{MSRP:format=currency}}</td>
    </tr>{{/.}}
    </table>
</body>
</html>

结果输出可能如下所示:

<html>
<head>
    <title>Product List</title>
</head>
<body>
    <table>
    <tr>
    <td>S10_1678</td>
    <td>1969 Harley Davidson Ultimate Chopper</td>
    <td>Motorcycles</td>
    <td>1:10</td>
    <td>Min Lin Diecast</td>
    <td>This replica features working kickstand...</td>
    <td>7932</td>
    <td>$48.81</td>
    <td>$95.70</td>
    </tr>
    ...
    </table>
</body>
</html>

摘要

本文概述了如何使用模板将REST服务的结果转换为HTML,从而大大减少了通常与支持Web和移动客户端应用程序相关的开发工作。 请注意,模板不限于HTML;模板也可以是HTML。 它们还可用于轻松生成其他数据表示形式,例如XML或CSV。

可以在此处下载最新版本的HTTP-RPC。 有关更多信息,请参见项目README

关于作者

Greg Brown是一位软件工程师,在咨询,产品和开源开发方面拥有20多年的经验。 他目前的重点是移动应用程序和REST服务。

翻译自: https://www.infoq.com/articles/templates-with-http-rpc-java/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

标记模板字面量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值