Java中将简单属性转换为字符串的方法

3
使用Java,我需要将一组键值对Map<String, String>编码为一个字符串并存储,然后能够再次解码。这些将存储在数据库列中,并且通常会很短而简单,因此常见情况应该产生一个简单的好看的行,但即使它包含意外字符等,也不会损坏数据。
您会如何选择这样做呢:
  • 编码形式是单个可读的行
  • 不需要大型库或许多上下文来编码/解码
  • 任何分隔符都被正确转义
Url编码?JSON?自己动手?请指定您将使用的任何帮助程序库或方法。
7个回答

5

正如@Uri所说,提供更多上下文会更好。我认为你的主要关注点不在于特定的编码方案,因为对于大多数编码方案而言,为简单的Map<String, String>自己设计编码方案是相当容易的。

一个有趣的问题是:这个中间字符串编码将用于什么?

  • if it's purely internal, an ad-hoc format is fine eg simple concatenation:

    key1|value1|key2|value2
    
  • if humans night read it, a format like Ruby's map declaration is nice:

    { first_key  => first_value, 
      second_key => second_value }
    
  • if the encoding is to send a serialised map over the wire to another application, the XML suggestion makes a lot of sense as it's standard-ish and reasonably self-documenting, at the cost of XML's verbosity.

    <map>
        <entry key='foo' value='bar'/>
        <entry key='this' value='that'/>
    </map>
    
  • if the map is going to be flushed to file and read back later by another Java application, @Cletus' suggestion of the Properties class is a good one, and has the additional benefit of being easy to open and inspect by human beings.


编辑:你已经添加了这是要存储在数据库列中的信息 - 是否有使用单个列而不是以下三个列的原因:

CREATE TABLE StringMaps 
(
    map_id NUMBER   NOT NULL,  -- ditch this if you only store one map...
    key    VARCHAR2 NOT NULL,
    value  VARCHAR2
);

除了让您存储更具语义的数据外,这还将编码/解码更正式地移入了您的数据访问层,并允许其他数据库读取器轻松查看数据,而无需了解您可能使用的任何自定义编码方案。如果需要,您还可以轻松按键或值查询。
再编辑: 你说它确实需要适合单列,那么我会选择以下两种方法之一:
  • 使用第一个管道分隔编码(或您喜欢的任何奇特字符,也许是一些英语中无法打印的Unicode字符)。最简单的方法。或者...
  • 如果您正在使用像Oracle这样的数据库,它将XML识别为真正的类型(因此可以针对其进行XPath评估等),并且需要能够从数据库层面很好地读取数据,请使用XML。编写用于解码的XML解析器从来不是一件有趣的事情,但是对于如此简单的模式,不应该太痛苦。
即使您的数据库不支持本地XML,您也可以将其放入任何旧的类似字符的列类型中...

是的,这是一个外部要求,需要适应单列。 - Dave L.
感谢您的周到回复,如果可以的话我会再次为您点赞,但我认为没有任何东西完全符合所有要求。管道需要转义,而不可打印字符并不是很易读。 - Dave L.
总有XML选项……即使您的数据库不支持它,您也可以将其放入VARCHAR列中。此外,使用Unicode转义序列存在不可打印字符的先例。 - Dan Vinton
这是一个相当冗长的回答,重新发明 java.util.Properties 轮子。 - cletus

3
为什么不直接使用Properties类呢?它可以完全满足你的需求。

好主意,但是你的链接指向 Javadoc 索引(我也常犯这种错误,该死的框架...)。你需要这个链接:http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html - Dan Vinton
谢谢您的建议,不过我正在寻找一种可以编码成单行的东西。 - Dave L.
为什么一行代码很重要?如果你真的想让它成为一行代码,你可以使用属性,然后将URL/Base64/某些内容编码为一个长字符串... 这种方法有点取巧,但是可以实现。 - Martin
在其上下文中,它应该作为单行读取/显示。如果您只是将其URL/Base64/某些编码为长字符串,为什么要使用属性呢? - Dave L.

1

我一直在考虑选择一种通用的表示方式来实现客户端和服务器之间的对话(传输内容)的需要,使用外观模式。我想要一种标准化、人类可读(简洁)、强大、快速的表示方式。我希望它能够轻松实现和运行,易于测试,并且易于“包装”。请注意,我已经根据我的定义和明确意图排除了 XML。

通过“包装”,我指的是我希望支持其他传输内容表示方式,例如 XML、SOAP、可能的 Java 属性或 Windows INI 格式、逗号分隔值(CSV)等,Google 协议缓冲区、自定义二进制格式、专有二进制格式(如 Microsoft Excel 工作簿)以及其他可能出现的格式。我将使用主要外观周围的包装器/装饰器来实现这些次要表示方式。每种次要表示方式都是可取的,特别是在某些情况下与其他系统集成,但由于各种缺点(未能满足上述任一标准),它们都不适合作为主要表示方式。

因此,到目前为止,我选择 JSON 格式作为我的主要传输内容表示方式。我打算在不久的将来详细探讨这个选项。

只有在极端的性能考虑下,我才会跳过翻译底层的传统格式。一个干净的设计的优点包括良好的性能(没有浪费的努力,易于维护),这只需要一个合适的硬件选择作为必要的补充即可。当性能需求变得极端时(例如,每天处理四万个总计四百万交易的传入数据文件),那么一切都必须重新审视。

作为开发人员、数据库管理员、架构师等等,我已经建立了几乎各种规模和描述的系统。我对我的标准选择非常自信,并热切期待其适用性的确认。事实上,我希望将其作为开源实现发布(但不要太急着期待)。

请注意,这个设计讨论忽略了传输媒介(HTTP、SMTP、RMI、.Net Remoting等),这是有意的。我发现将传输媒介和传输内容作为完全独立的设计考虑,比从系统本身出发更加有效。事实上,我的意图是使它们几乎可以“插拔式”的。

因此,我鼓励您强烈考虑使用JSON。祝一切顺利。


0

提供一些问题的额外背景会有所帮助。

如果您将以整个地图粒度进行编码和解码,为什么不直接使用XML呢?


0
如@DanVinton所说,如果您需要在内部使用(我的意思是

仅供我编写的组件使用

),您可以连接密钥和值。我更喜欢在密钥和密钥之间以及密钥和值之间使用不同的分隔符:
而不是
key1+SEPARATOR+value1+SEPARATOR+key2 etc
我编码 < br/> key1+SEPARATOR_KEY_AND_VALUE+value1+SEPARATOR_KEY(n)_AND_KEY(N+1)+key2 etc

如果您必须进行调试,这种方式更清晰(也是按设计而来的)


0

请查看Apache Commons Configuration包。它可以让您将文件读取/保存为XML或属性格式。它还提供了自动将属性更改保存到文件的选项。

Apache配置


0

我知道这是一个旧的“死气沉沉”的帖子,但我有一个之前没有提出过的解决方案,我认为值得一试。

我们将地理要素的“任意”属性(即用户在运行时创建的)以标准XML属性格式存储在数据库中的单个CLOB列中。也就是说:

name="value" name="value" name="value"

创建一个 XML 元素,只需将属性“包装”在 XML 元素中即可。也就是说:
String xmlString += "<arbitraryAttributes" + arbitraryAttributesString + " />"

将Properties实例序列化为xml属性字符串是易如反掌的...只需要十行代码。我们很幸运,可以强制用户遵守所有属性名称必须是有效的xml元素名称的规则;并且我们对每个“值”进行xml转义(即&quote等),以避免值字符串中的双引号和其他问题。
这是有效的、灵活的、快速的(足够)和简单的。
现在,说了这么多...如果我们有时间,我们会通过将完整的未经篡改的未解释的元数据xml文档存储在CLOB中,并使用开源元数据编辑器处理整个混乱来完全与“元数据问题”脱钩。
谢谢。Keith。

除非您还使用某些XML库来格式化/解析它(或最终字符串由其他代码使用/消耗),否则我认为这与垂直条变体没有太大区别。只是单行键值对的另一种格式,但具有非单个分隔符字符。 - Mirvnillith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接