Java - 422 无法使用 RestTemplate 处理的实体

Java - 422 Unprocessable Entity using RestTemplate

我有两个服务,正在尝试从服务 A 发送 GET 请求,让服务 B 向 Redmine 服务器发送 Post 请求。

正在422 Unprocessable Entity: "{"errors":["Name cannot be blank","Identifier cannot be blank"]}"

这是我已经尝试过的方法:

String url = "http://localhost:3001/projects.json"; //Redmine local server
RestTemplate restTemplate = new RestTemplate();
JSONObject object = new JSONObject();   //Json object that will need to be sent to redmine
object.put("name", "dummyName");        // Should look like this
object.put("identifier", "dummyId");    // {"project":{"identifier":"dummyId","name":"dummyName"}}
JSONObject body = new JSONObject();     
body.put("project", object);            
String plainCreds = "user:bitnami1"; // default basic auth encoding
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds); 
headers.add("Content-Type", "application/json");
RequestEntity<JSONObject> requestEntity = RequestEntity
                .post(new URI(url))
                .accept(MediaType.APPLICATION_JSON)
                .headers(headers)
                .body(body);
ResponseEntity<String> r = restTemplate.exchange(requestEntity, String.class);

这样我得到了同样的错误,422 Unprocessable Entity: "{"errors":["Name cannot be blank", "Identifier cannot be blank"]}" 当我尝试 log.info 请求实体进行检查时,它看起来正常

<POST http://localhost:3001/projects.json,{"project":{"identifier":"dummyId","name":"dummyName"}},[Accept:"application/json", Authorization:"Basic dXNlcjpiaXRuYW1pMQ==", Content-Type:"application/json"]>

然后我尝试了entity,如下

String url = "http://localhost:3001/projects.json"; //Redmine local server
RestTemplate restTemplate = new RestTemplate();
JSONObject object = new JSONObject();   //Json object that will need to be sent to redmine
object.put("name", "dummyName");        // Should look like this
object.put("identifier", "dummyId");    // {"project":{"identifier":"dummyId","name":"dummyName"}}
JSONObject body = new JSONObject();     
body.put("project", object);            
String plainCreds = "user:bitnami1"; // default basic auth encoding
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds); 
headers.add("Content-Type", "application/json");
HttpEntity<Object> entity = new HttpEntity<Object>(body, headers);
ResponseEntity<String> result = restTemplate.exchange("http://localhost:3001/projects.json",
                HttpMethod.POST,
                entity,
                String.class);

与之前相同的结果,当我 log.info 实体主体时,我得到以下内容

<{"project":{"identifier":"dummyId","name":"dummyName"}},[Authorization:"Basic dXNlcjpiaXRuYW1pMQ==", Content-Type:"application/json"]>

尝试使用 NetCat 捕获正在发送的内容,在这两种方式中我都没有收到 restTemplate.exchange 的任何正文。

调试时,错误似乎来自RestTemplate.doExecute,我不明白为什么。

----编辑----

正在尝试连接到 Redmine API 以创建新项目,可以找到更多信息 here 这是成功创建新项目的 curl 命令

curl --location --request POST 'localhost:3001/projects.json' \
--header 'Authorization: Basic dXNlcjpiaXRuYW1pMQ==' \
--header 'Content-Type: application/json' \
--data-raw '{"project":{"identifier":"dummyId","name":"dummyName"}}'

我想做的是从服务 A 向我的服务 B 发送一个请求,这样这个请求就会被转发到 redmine 服务器。 为了简单起见,我在上面的代码(服务 B)中硬编码了信息,只是为了确保我可以映射这个 curl 请求,但是它不起作用。

对于这种情况有什么建议的解决方案吗?也许另一种方法?任何建议都会有所帮助。

由于您的方法会接受一个对象节点作为输入,因此您可以这样做:

String url = "http://localhost:3001/projects.json"; 
 RestTemplate restTemplate = new RestTemplate();

然后你可以这样设置HttpEntity

HttpEntity<ObjectNode> entity = new HttpEntity<>(node, headers);

然后调用exchange:

ResponseEntity<String> result = restTemplate.exchange("http://localhost:3001/projects.json",
            HttpMethod.POST,
            entity,
            String.class);

我想这会让你的生活更轻松。