2017-03-07 86 views
-1

我想用一個簡單的Go(go1.8 darwin/amd64)程序打一個Java Spring Boot應用程序提供的REST端點。我試圖打在2種獨立的方式:403製作Golang POST時禁止

const (
    LOCAL_BASE   = "http://localhost:11400" 
    ADD_FUNDS_ENDPOINT = "/sub-accounts/%d/add-funds" 
) 

type InputArgumentsJson struct { 
    Amount   float64 `json:"amount"` 
    BufferAmount  float64 `json:"bufferAmount"` 
    FromSubAccountID int  `json:"fromSubAccountId"` 
} 

... 

// set up json body 
inputArguments := &InputArgumentsJson{Amount: 1100, BufferAmount: 0, 
    FromSubAccountID: spendFundId} 
bytes := new(bytes.Buffer) 
json.NewEncoder(bytes).Encode(inputArguments) 

// set up the url to call 
endpoint := fmt.Sprintf(ADD_FUNDS_ENDPOINT, billSetAsideId) 
url := LOCAL_BASE + endpoint 

client := &http.Client{} 

req, err := http.NewRequest("POST", url, bytes) 
if err != nil { 
    fmt.Println("ERROR WHILE BUILDING REQUEST") 
    fmt.Println(err) 
} 

req.Header.Add("Content-Type", "application/json") 
resp, err := client.Do(req) 
if err != nil { 
    fmt.Println("ERROR WHILE MAKING REQUEST") 
    fmt.Println(err) 
} 
fmt.Println(resp) 

和:

resp, err := http.Post(url, "application/json; charset=utf-8", bytes) 
if err != nil { 
    fmt.Println("ERROR WHILE MAKING REQUEST") 
    fmt.Println(err) 
} 
fmt.Println(resp) 

我增加了打印出來,看看URL和JSON的身體是正確的,他們似乎是:

fmt.Printf("\nMaking request to %s with:\n %s\n", url, bytes) 

打印出來

Making request to http://localhost:11400/sub-accounts/167/add-funds with: 
{"amount":1100,"bufferAmount":0,"fromSubAccountId":166} 

,但運行時我得到了403禁止。

我可以打這個端點沒有失敗同時使用郵差和下面的curl命令:

curl -H "Content-Type: application/json" -X POST -d '{"amount":1100,"bufferAmount":0,"fromSubAccountId":166}' http://localhost:11400/sub-accounts/167/add-funds

有沒有人有什麼我可以在這裏失蹤的任何想法?爲了進一步增加趣味,我可以成功地從Go程序中創建不同的GET端點。

在此先感謝!

編輯以表明我捕捉錯誤和周圍的邏輯創建URL和JSON身體

+0

嘗試在您的請求和響應中首先發現錯誤'resp,err:= client.Do(req)'。 – Elad

+0

我實際上是這樣捕捉它們,然後用'if er!= nil'來打印出來,但沒有任何東西被捕獲。爲了簡潔起見,我把它留下了,因爲服務器明顯在響應,但是有一個403. –

回答

0

你沒有表現出什麼bytes是但這是最有可能的問題:既NewRequestPost採取io.Reader並從該閱讀器讀取身體。這種閱讀通常只能發生一次(想想一個流)。當您打印fmt.Printf("%s")io.Reader時,此打印將消耗內容(最可能通過調用String()方法),並且實際請求通過空的正文完成。

總是顯示整個代碼。並且不要嘗試從io.Reader讀取兩次。

+0

這是一個很好的想法,但它是否打印字節。我編輯了我的代碼以顯示一切。 –

0

我假設有2個Go應用程序並在不同的主機上運行,​​這會導致CORS問題。考慮在您的客戶的主機上添加Access-Control-Allow-Origin服務。

w.Header().Set("Access-Control-Allow-Origin", "*")

您可以指定主機名,您的客戶端應用程序運行時改變*

+0

服務器實際上是一個Java Spring Boot App。奇怪的是,當它位於本地主機上時,或者將Spring Boot應用程序部署到AWS時,我得到的結果相同。在任何一種情況下,Go應用程序在本地運行都會得到403,而Curl和Postman可以成功擊中端點,而不管它從哪裏運行。 CORS問題也不會在GET請求和POST請求中出現嗎?我可以用我的Go程序成功完成GET,而不是POST。 –

+0

您是否可以使用Go和Curl來記錄請求/響應標題? –

+0

這不是一個CORS問題,但您的回答讓我更仔細地查看發現問題的服務器。我的Go應用程序一直都很好,但Java應用程序有點怪異。 –

0

OMG ....我剛發現這個問題。事實證明,這是失敗的(正如我所期待的),但它錯誤地將它歸爲403而不是400.呃...有時,當你長時間注視某些東西時,這些明顯的事情完全沒有注意到。