在使用GO发送POST请求时,从服务器收到了一个错误的响应 – 422。

huangapple go评论93阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2014年12月3日 02:50:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/27256766.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定