2012-11-15 175 views
0

我正在研究我的json服務器的I/O方面,並且有一種方法我無法正確理解。 首先,我會給出錯誤,然後介紹代碼和數據類型以及之後的一些關於該問題的評論。JSON解析錯誤

("X-Response-Body-Start","<!DOCTYPE html>\n<html><head><title>Invalid Arguments</title></head><body><h1>Invalid Arguments</h1><ul><li>when expecting a unit constructor (U1), encountered String instead</li></ul></body></html>")

期待單元構造器?

好的,這裏有一些相關的代碼。讓我們看看我們是否能夠看到我走到哪裏錯了 from Datatypes.hs

data JobID = JobID Project Int deriving Generic 

data Project = BNAP deriving (Show,Generic) -- one day to be an ADT 

instance ToJSON Project where 
    toJSON = toJSON . show 

instance FromJSON Project 

instance FromJSON JobID 
instance ToJSON JobID 

測試代碼

testReadR :: IO Value 
testReadR = do 
    req <- parseUrl readURI 
    manager <- newManager def 
    pBody <- runResourceT $ do 
       reqBody <- readObject 
       liftIO $ print reqBody 
       Response _ _ _ body <- http (buildReq req reqBody) manager 
       pBody <- body $$+- sinkParser json 
       return pBody -- (return wraps it up) 
    closeManager manager 
    return pBody 

buildReq :: forall a (m :: * -> *) (t :: * -> *). 
      ToJSON a => 
      Request t -> a -> Request m 
buildReq req reqBody = 
    let reqBodyBS = Data.Aeson.encode reqBody 
     rHeaders = [(hContentType,pack "application/json")] 
    in req {method = fromString "POST" 
      , requestBody = RequestBodyLBS reqBodyBS 
      ,requestHeaders=rHeaders 
      } 
readObject :: ResourceT IO Value 
readObject = do -- I took a bunch out because I thought simplifiying would help me 
       -- solve this 
    return $ Data.Aeson.toJSON $ JobID BNAP 306 

的處理器

postReadR :: Handler RepJson 
postReadR = do 
    conf <- parseJsonBody_ :: Handler JobID   
    liftIO $ print conf 
    testJ <- jsonToRepJson $ toJSON $ JobID BNAP 305 
    jValue <- jsonToRepJson conf -- to be replaced with 
           -- Either ErrorReport Response 
           -- (or something like that) 
    return jValue 

當我改變行至 conf <- parseJsonBody_ :: Handler Value

print conf收益率 Array (fromList [String "BNAP",Number 306])

所以它似乎問題在於字符串「BNAP」,但我不知道爲什麼。關於如何解決這個問題的任何想法?有沒有明顯的答案,我沒有看到?

更新:我有一個新的錯誤。我敢肯定,我已經對FromJSON實例進行了分析。

test: ResponseTimeout 

instance FromJSON Project where 
    parseJSON (String p) = parseJSON $ toJSON p 
    parseJSON _ = mzero 

這裏的挑戰是Project是一元類型。我研究的例子似乎都沒有解決這個問題。但我知道p是Text,toJSON可以使Value出來,parseJSONParserValue。所以這一切都很好?那麼,我仍然得到上面的錯誤,根本沒有提供信息。有任何想法嗎?

+0

更新我的回答有什麼,我相信你修復當前的問題。 –

回答

2
instance ToJSON Project where 
    toJSON = toJSON . show 

instance FromJSON Project 

實例不能一起工作。通用FromJSON實例需要通用單元構造函數U1,但ToJSON實例會生成String "BNAP"

如果你有一個手寫ToJSON情況下,你還需要一個手寫FromJSON實例。


instance FromJSON Project where 
    parseJSON (String p) = parseJSON $ toJSON p 
    parseJSON _ = mzero 

pText,我們有

instance ToJSON Text where 
    toJSON = String 

因此上述實例Project循環,因爲它擴展parseJSON (String p) = parseJSON (String p)

對於因爲就目前的類型,如果你啓用了OverloadedStrings

instance FromJSON Project where 
    parseJSON (String "BNAP") = return BNAP 
    parseJSON _    = mzero 

應該工作,如果沒有,

instance FromJSON Project where 
    parseJSON (String p) 
     | p == pack "BNAP" = return BNAP 
    parseJSON _   = mzero 
+0

謝謝,它確實解決了它。 –