英文:
Getting a Bad response - 422 from the server while sending a POST request in GO
问题
我正在尝试使用以下函数发送POST请求:
func (Client *Client) doModify(method string, url string, createObj interface{}, respObject interface{}) error {
bodyContent, err := json.Marshal(createObj)
if err != nil {
return err
}
client := Client.newHttpClient()
req, err := http.NewRequest(method, url, bytes.NewBuffer(bodyContent))
if err != nil {
return err
}
Client.setupRequest(req)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Content-Length", string(len(bodyContent)))
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
return errors.New(fmt.Sprintf("Bad response from [%s], go [%d]", url, resp.StatusCode))
}
byteContent, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return json.Unmarshal(byteContent, respObject)
}
我像这样调用我的函数:
func TestContainerCreate(t *testing.T) {
client := newClient(t)
container, err := client.Container.Create(&Container{
Name: "name",
ImageUuid: "xyz",
})
if err != nil {
t.Fatal(err)
}
defer client.Container.Delete(container)
}
Create函数内部调用了doCreate函数,而doCreate函数又调用了顶部粘贴的doModify函数。
func (self *ContainerClient) Create(container *Container) (*Container, error) {
resp := &Container{}
err := self.Client.doCreate(container_TYPE, container, resp)
return resp, err
}
func (Client *Client) doCreate(schemaType string, createObj interface{}, respObject interface{}) error {
if createObj == nil {
createObj = map[string]string{}
}
schema, ok := Client.Types[schemaType]
if !ok {
return errors.New("Unknown schema type [" + schemaType + "]")
}
return Client.doModify("POST", collectionUrl, createObj, respObject)
}
这给我返回了一个422错误响应。进一步研究后发现,当使用小写字母作为"name"和"imageUuid"的首字母时,使用CURL进行请求会返回201创建状态,但是当传递大写字母作为"Name"和"ImageUuid"的首字母时,会返回422错误响应。可能是容器的JSON结构定义有问题,或者这些实体的大小写定义有问题,或者其他原因导致的吗?
curl -X POST -v -s http://localhost:8080/v1/containers -H 'Content-Type: application/json' -d '{"name" : "demo", "imageUuid" : "docker:nginx"}' | python -m 'json.tool'
Container结构的定义如下:
type Container struct {
Resource
ImageId string `json:"ImageId,omitempty"`
ImageUuid string `json:"ImageUuid,omitempty"`
MemoryMb int `json:"MemoryMb,omitempty"`
Name string `json:"Name,omitempty"`
}
type ContainerCollection struct {
Collection
Data []Container `json:"data,omitempty"`
}
请注意,我只是翻译了你提供的代码和问题,没有回答你的问题。
英文:
I am trying to send a POST request using this function -
{
func (Client *Client) doModify(method string, url string, createObj interface{}, respObject interface{}) error {
bodyContent, err := json.Marshal(createObj)
if err != nil {
return err
}
client := Client.newHttpClient()
req, err := http.NewRequest(method, url, bytes.NewBuffer(bodyContent))
if err != nil {
return err
}
Client.setupRequest(req)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Content-Length", string(len(bodyContent)))
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
return errors.New(fmt.Sprintf("Bad response from [%s], go [%d]", url, resp.StatusCode))
}
byteContent, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return json.Unmarshal(byteContent, respObject)
}
}
I am calling my function like this -
{
func TestContainerCreate(t *testing.T) {
client := newClient(t)
container, err := client.Container.Create(&Container{
Name: "name",
ImageUuid: "xyz",
})
if err != nil {
t.Fatal(err)
}
defer client.Container.Delete(container)
}
}
The Create function calls internally calls the doCreate function which calls the doModify function pasted on the top .
{
func (self *ContainerClient) Create(container *Container) (*Container, error) {
resp := &Container{}
err := self.Client.doCreate(container_TYPE, container, resp)
return resp, err
}
}
{
func (Client *Client) doCreate(schemaType string, createObj interface{}, respObject interface{}) error {
if createObj == nil {
createObj = map[string]string{}
}
schema, ok := Client.Types[schemaType]
if !ok {
return errors.New("Unknown schema type [" + schemaType + "]")
}
return Client.doModify("POST", collectionUrl, createObj, respObject)
}
}
This gives me a 422 bad response.On doing further research, When doing a CURL, with "name" and "imageUuid" first letter as small case, gives a 201 created status but when passing "Name" and "ImageUuid" first letter as capital gives 422 bad response. Could there be issue with the json struct defined for container, or case of these entities being defined or something else?
{
curl -X POST -v -s http://localhost:8080/v1/containers -H 'Content-Type: application/json' -d '{"name" : "demo", "imageUuid" : "docker:nginx"}' | python -m 'json.tool'
}
Container struct definition looks like this -
{
type Container struct {
Resource
ImageId string `json:"ImageId,omitempty"`
ImageUuid string `json:"ImageUuid,omitempty"`
MemoryMb int `json:"MemoryMb,omitempty"`
Name string `json:"Name,omitempty"`
}
type ContainerCollection struct {
Collection
Data []Container `json:"data,omitempty"`
}
}
答案1
得分: 3
string(len(bodyContent))
并不是你想象中的那样工作。你正在将一个单独的整数转换为UTF-8字符串。你应该使用strconv
包来获取数值表示。
另外,请注意你不能对整数使用omitempty
,因为0
是一个有效的值。
英文:
string(len(bodyContent))
isn't doing what you think it is. You're converting a single int to a utf-8 string. You want to use the strconv
package to get the numerical representation.
Also note that you can't omitempty
an int, since 0
is a valid value.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论