400错误代码,当使用RestTemplate进行Rest API时。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了400错误代码,当使用RestTemplate进行Rest API时。相关的知识,希望对你有一定的参考价值。

我有一个REST API要调用,我用rest模板写了客户端。当执行时,我得到400状态代码。同样的REST API在使用POSTMAN时也能正常工作。以下是API和调用者的代码片段。如果有人抓住了什么,请让我知道。

REST API的POST方法-

@ApiOperation(value = "Download repository as zip")
    @ApiResponses({@ApiResponse(code = 200, message = ""), @ApiResponse(code = 400, message = "")})
    @PostMapping(value = "/download", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
    public ResponseEntity<StreamingResponseBody> downloadRepository(
            @RequestBody @Validated final RepositoriesRequest repositoriesRequest) {

        final Situation situation = this.situationsService.getSituationId(repositoriesRequest);
        if (isNull(situation)) {
            return ResponseEntity.notFound().build();
        } else {
            final ExtractionRequest extractionRequest = new ExtractionRequest(repositoriesRequest.getType(), situation,
                    repositoriesRequest.getDatabase());

            if (!this.validateRequest(extractionRequest)) {
                return ResponseEntity.badRequest().build();
            }
            final ExtractionResponse response = this.extractService.extractRepository(extractionRequest);

            if (null == response) {
                return ResponseEntity.notFound().build();
            }
            final InputStream inputStream = this.extractService.getFileFromS3(response.getRepositoryPath());

            if (null == inputStream) {
                return ResponseEntity.noContent().build();
            }

            final StreamingResponseBody bodyWriter = this.bodyWriter(inputStream);

            return ResponseEntity.ok()
                    .header("Content-Type", "application/zip")
                    .header(CONTENT_DISPOSITION, "attachment; filename="repository-" + situation.getId() + ".zip"")
                    .body(bodyWriter);
        }
    }

使用REST模板的REST CLIENT,并将auth token和请求体作为输入。

HttpEntity<MultiValueMap<String, Object>> buildLoadRepoRequest(
            final SimulationContext context,
            final List<String> tablesName,
            final String simulationId,
            final Integer offset) {
        final Token token = this.authenticateOkoye(simulationId, offset);
        LOGGER.info("Token Run: {}", token.getAccessToken());
        final String database = this.getDatabaseForEnvironment();

        final HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(APPLICATION_JSON_UTF8);
        httpHeaders.set(AUTHORIZATION, "Bearer " + token.getAccessToken());

        final MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("database", database);
        body.add("monthlyClosingMonth", context.getMonthlyClosingDate());
        body.add("repositorySnapshot", context.getRepository());
        body.add("situationId", context.getSituationId());
        body.add("tableNames", tablesName);
        body.add("type", context.getRunType());

        return new HttpEntity<>(body, httpHeaders);
    }

异常处理程序 -

    @Override
    @ExceptionHandler(HttpClientErrorException.class)
    public void loadRepository(
            final SimulationContext context,
            final List<String> tablesName,
            final String simulationId,
            final Integer offset,
            final Path repositoryPath) throws IOException {
        LOGGER.info("[{}] [{}] repository tablesName: {}", simulationId, offset, tablesName);
        this.restTemplate.setRequestFactory(this.getClientHttpRequestFactory());
        final ClientHttpResponse response = this.restTemplate.postForObject(
                this.repositoriesUrl,
                this.buildLoadRepoRequest(context, tablesName, simulationId, offset),
                ClientHttpResponse.class);

        if (response != null && HttpStatus.OK == response.getStatusCode()) {
            LOGGER.info(
                    "response status on simulation : {}  - Context: {} - status: {}",
                    simulationId,
                    offset,
                    response.getStatusCode());
            //this.helper.copy(response.getBody(), repositoryPath);
        } else if (response != null && HttpStatus.NO_CONTENT != response.getStatusCode()) {
            throw new JarvisException(
                    "Can't retrieve RWA repository on simulation " + simulationId + " Context:" + offset);
        }
    }

从昨天开始,我们一直在研究这个问题,但仍然没有任何线索。到目前为止,我们已经尝试了postForEntity、exchange、将头文件改为适当的setter方法,并尝试将参数作为对象传递。但都没有成功。

我有一种强烈的感觉,就是在调用API时,头信息层面出了问题。

答案

你有没有尝试使用 httpHeaders.setContentType(MediaType.APPLICATION_JSON)

或者在@PostMapping注解中添加消费,并加上APPLICATION_JSON_UTF8的值。

以上是关于400错误代码,当使用RestTemplate进行Rest API时。的主要内容,如果未能解决你的问题,请参考以下文章

RestTemplate GET 请求抛出 400 Bad Request

restTemplate 调用异常处理,处理http协议层的错误状态40*,30*等

SpringBoot 使用 RestTemplate 调用exchange方法 显示错误信息

HTTP 400 错误是啥原因

Spring Resttemplate 异常处理

webSocket 握手期间的错误意外响应代码:400