如何使用Haskell Aeson库遍历JSON生成Java DAO 无需预定义数据类
解决方案
完全可以用Aeson库实现无需预定义数据类的JSON结构遍历,不需要更换其他库。
核心原理
Aeson内置了通用的Value类型,本身就是对JSON结构的直接建模,定义如下:
data Value = Object !Object -- 对应JSON对象,本质是HashMap Text Value | Array !Array -- 对应JSON数组,本质是Vector Value | String !Text -- 对应JSON字符串 | Number !Scientific -- 对应JSON数字 | Bool !Bool -- 对应JSON布尔值 | Null -- 对应JSON空值
你不需要预定义任何和业务JSON结构匹配的自定义类型,直接对Value做模式匹配就可以实现递归遍历,完全对标你Python实现的逻辑。
完整示例代码
1. 依赖引入
你需要在cabal或stack中添加以下依赖:
- aeson
- text
- unordered-containers
- scientific
- bytestring
2. 实现代码
import qualified Data.Aeson as Aeson import qualified Data.Text as T import qualified Data.HashMap.Strict as HM import Data.Scientific (Scientific) import Data.ByteString.Lazy.Char8 (pack) -- 解析JSON字符串为Value类型 parseJson :: String -> Maybe Aeson.Value parseJson = Aeson.decode . pack -- 递归遍历处理JSON,这里示例是打印结构,你可以替换为生成Java DAO代码的逻辑 processJson :: Aeson.Value -> IO () processJson val = case val of Aeson.Object obj -> do putStrLn ">>> 处理JSON对象" -- 遍历所有键值对 HM.traverseWithKey processField obj return () Aeson.Array arr -> do putStrLn ">>> 处理JSON数组" traverse processJson arr return () Aeson.String s -> putStrLn $ "字符串值:" ++ T.unpack s Aeson.Number n -> putStrLn $ "数字值:" ++ show n Aeson.Bool b -> putStrLn $ "布尔值:" ++ show b Aeson.Null -> putStrLn "空值" where processField key value = do putStrLn $ "处理字段名:" ++ T.unpack key processJson value -- 调用示例 main :: IO () main = do let testJson = "{\"name\":\"Dave\",\"age\":2,\"info\":{\"addr\":\"Beijing\",\"tags\":[\"student\",\"male\"]}}" case parseJson testJson of Nothing -> putStrLn "JSON解析失败" Just v -> processJson v
注意事项
- 示例中的
IO返回类型可以按需替换,比如如果你要生成代码,可以返回String或者Builder类型拼接代码片段即可。 - 生产环境不要使用
fromJust处理Maybe结果,用case分支明确处理解析失败的情况更稳妥。 - 你看到的大多数Aeson示例需要预定义数据类,是因为常规业务场景需要把JSON反序列化为业务实体使用,你这种处理任意JSON结构的场景直接操作
Value就是最优方案。
内容的提问来源于stack exchange,提问作者Erik Vesterlund
相关产品推荐
相关产品推荐

