我正在创建一个micronaut HttpClient接口来使用外部端点。

基本上我需要发送一个Content-Type:application / x-www-form-urlencoded的帖子

这是我的界面

@Client("${keycloak.base-url}/")
public interface IKeycloakClient {

    @Post(value="/auth/realms/master/protocol/openid-connect/token", processes = { MediaType.APPLICATION_JSON,MediaType.APPLICATION_FORM_URLENCODED })
    public AuthenticationData getToken(@Body Map<String,String> body);
    public void createUser();

    public class AuthenticationData {
        private String accessToken;

        public String getAccessToken() {
            return this.accessToken;
        }

        public void setAccessToken(String accessToken) {
            this.accessToken = accessToken;
        }
    }
}


我通过以下方式创建身体

HashMap<String, String> body = new HashMap<>();
body.put("client_id", "admin-cli");
body.put("grant_type", "password");
body.put("username", kConfiguration.getAdminUser());
body.put("password", kConfiguration.getAdminSecret());
IKeycloakClient.AuthenticationData token = kc.getToken(body);


当我调用方法kc.getToken(body)时,我可以看到跟踪调用:

DEBUG i.m.http.client.DefaultHttpClient - Sending HTTP Request: POST /auth/realms/master/protocol/openid-connect/token
DEBUG i.m.http.client.DefaultHttpClient - Chosen Server: keycloakserver(-1)
TRACE i.m.http.client.DefaultHttpClient - host: keycloakserver
TRACE i.m.http.client.DefaultHttpClient - connection: close
TRACE i.m.http.client.DefaultHttpClient - content-type: application/json
TRACE i.m.http.client.DefaultHttpClient - content-length: 87
TRACE i.m.http.client.DefaultHttpClient - Request Body
TRACE i.m.http.client.DefaultHttpClient - ----
TRACE i.m.http.client.DefaultHttpClient - {"password":"admin","grant_type":"password","client_id":"admin-cli","username":"admin"}
TRACE i.m.http.client.DefaultHttpClient - ----
TRACE i.m.http.client.DefaultHttpClient - HTTP Client Response Received for Request: POST /auth/realms/master/protocol/openid-connect/token
TRACE i.m.http.client.DefaultHttpClient - Status Code: 400 Bad Request
TRACE i.m.http.client.DefaultHttpClient - Content-Type: application/json
TRACE i.m.http.client.DefaultHttpClient - Date: Tue, 02 Oct 2018 22:47:01 GMT
TRACE i.m.http.client.DefaultHttpClient - Server: nginx/1.15.2
TRACE i.m.http.client.DefaultHttpClient - Content-Length: 84
TRACE i.m.http.client.DefaultHttpClient - Connection: Close
TRACE i.m.http.client.DefaultHttpClient - Response Body
TRACE i.m.http.client.DefaultHttpClient - ----
TRACE i.m.http.client.DefaultHttpClient - {"error":"invalid_request","error_description":"Missing form parameter: grant_type"}


读取错误后,我可以确定问题出在Content-Type: application/json上,我已经使用邮递员测试了端点,并且application/x-www-form-urlencoded可以正常工作。

这是邮递员的要求:

POST /auth/realms/master/protocol/openid-connect/token HTTP/1.1
Host: keycloakserver
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache


我需要任何帮助来解决此问题。

提前致谢

最佳答案

首先,您不应该使用像IKeycloakClient.AuthenticationData这样的嵌套类

根据您的示例。您可以直接致电http客户

例如:

RxHttpClient client = RxHttpClient.create( new URL("${keycloak.base-url}/"));
HashMap<String,String> data = new HashMap<>();
data.put("client_id","admin-cli");
data.put("grant_type","password");
data.put("username", kConfiguration.getAdminUser());
data.put("password", kConfiguration.getAdminSecret());
MutableHttpRequest<HashMap<String, String>> request = HttpRequest
        .POST("/auth/realms/master/protocol/openid-connect/token", data)
        .contentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE);
HttpResponse<AuthenticationData> response = client.exchange(request, AuthenticationData.class)
        .blockingFirst();

关于java - 无法在Micronaut中为HttpClient设置ContentType,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52617588/

10-11 06:53