Alamofire - 添加查询参数和正文

Alamofire - add both query parameter and body

我正在尝试发送一个请求,该请求应包含 URL 参数和 JSON 中的请求正文。后端无法识别请求和 returns 400 状态代码。

这就是我尝试解决问题的方法

enum MyRequestsRouter: URLRequestConvertible {

    case RequestA(paramA: String, bodyInJsonString: String),
         RequestB(paramB: String)

    var baseURL: URL {
        URL(string: "http://127.0.0.1:8080")!
    }

    var method: HTTPMethod {
        switch self {
        case .RequestA: return .post
        case .RequestB: return .get
        }
    }

    var path: String {
        switch self {
        case .RequestA: return "/api/a"
        case .RequestB: return "/api/b"
        }
    }

    var parameters: Parameters? {
        switch self {
        case .RequestA(let paramA, let bodyInJsonString):
            return [
                "paramA": paramA
            ]

        case .RequestB(let paramB):
            return ["paramB": paramB]

        default:
            return nil
        }
    }

    func asURLRequest() throws -> URLRequest {
        let url = baseURL.appendingPathComponent(path)
        var request = URLRequest(url: url)
        request.method = method

        switch self {
        case let .RequestA(paramA, bodyInJsonString):
            // here I am specifying `paramA` value
            request = try URLEncoding.default.encode(request, with: parameters)

            // here body is already serialized to Json
            request.httpBody = Data(bodyInJsonString.utf8)
            request.setValue("application/json", "Content-Type")

        case let .RequestB(paramB):
            request = try URLEncoding.default.encode(request, with: parameters)
            
        }

        return request
    }

}

这就是我拨打 API 电话的方式

let json: Data = try JSONEncoder().encode(notSerializedBodyObject)
let jsonString = String(data: json, encoding: .utf8)

AF.request(MyRequestsRouter.RequestA(paramA: "paramA", bodyInJsonString: jsonString!)).response { response in
            print("Request: \(response.request)")
            print("Response: \(response.response)")
            print("Error: \(response.error)")
            
            // etc
            }
            
}

如您所见,请求 URL 应该是
http://127.0.0.1:8080/api/a?paramA=paramA 在 JSON 中加上请求正文。但是响应是 400 Bad request.

如何正确配置Alomofire?

Alamofire 的 URLEncoding 有一个将 destination 作为参数的初始化器。基于文档:

Destination defining where the encoded query string will be applied. .methodDependent by default.

默认情况下 .methodDependent 大小写检查请求的 HTTP 方法,仅在 .get.head.delete请求它在 URL.

中对传递的参数进行编码

鉴于这一事实,您永远不会在请求中看到 paramA(甚至在正文中也看不到),因为您在以下行中覆盖了它:

// here body is already serialized to Json
request.httpBody = Data(bodyInJsonString.utf8)

因此,除了使用 默认 URLEncoding,您还可以简单地调用 URLEncoding 的初始化程序,直接将 destination 作为 .queryString 案例是这样的:

// here I am specifying `paramA` value
request = try URLEncoding(destination: .queryString).encode(request, with: parameters)

// here body is already serialized to Json
request.httpBody = Data(bodyInJsonString.utf8)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")

这样,您将在 URL 中收到带有 paramA 且您的 JSON 作为正文的请求。