2

我有一个接收 JSON 的服务器,如下所示:

{ "foo": "bar", "bono": "bobo",
  "result": { "some": ["complex", "JSON", "structure",...
}

除了“result”之外的所有东西都用于服务器,它将被转发给客户端(Worker --JSON--> Server --value of “result”--> Client)。因此,在用 aeson 解析这个东西时,我想将“结果”的值保留为字符串(或 Text 或诸如此类),这样我就可以将其转发给客户端而不用关心里面的内容。问题是“结果”可以是任何东西(数组、对象等)。所以如果我这样做

data RPCResult = RPCResult { foo :: Text, result :: Text }

aeson的decode函数将返回Nothing,因为“结果”不一定是 JSON 字符串...

我如何告诉 aeson 保持 JSON 对象的部分原样并把它们交给我,这样我就可以用它们做我想做的事了?

4

1 回答 1

3

我似乎有某种解决方案,方法是设置resultbe类型,Data.Aeson.Value然后在对传入的 JSON 执行 a 之后,在转发它之前decode提取result并运行它。encode我不确定这是否是最好的解决方案(因为我没有像问题所说的那样“将其保留为字符串”,而是对其进行解码然后再次对其进行编码......)但它有效:

import Data.Aeson
import Data.Maybe
import Data.ByteString.Lazy (fromStrict, ByteString)
import Data.ByteString.UTF8 (fromString)
import Control.Applicative

data RPCResult = RPCResult { foo :: Text, result :: Value }

instance FromJSON RPCResult where
  parseJSON (Object v) = RPCResult <$> v .: "foo" <*> v .: "result"

-- example just so you get the idea:
toRPCResult :: String -> RPCResult
toRPCResult = fromJust . decode . fromStrict . fromString

getResult :: String -> ByteString
getResult = encode . result . toRPCResult
于 2013-07-15T02:28:51.723 回答