为什么 HttpServletResponse 主体总是空的?

Why is HttpServletResponse body always empty?

我的客户端正在使用提取 api 与控制器方法进行交互,该方法将解密密码并将解密的密码以纯文本形式发送回客户端。但是,响应正文从不包含密码。它还继续将内容类型设置为 basic,即使我将其设置为 text/plain。我做错了什么?

客户

            function showCredentialModal(credentialId, url, username, password) {
                $('#credential-id').val(credentialId ? credentialId : '');
                $('#credential-url').val(url ? url : '');
                $('#credential-username').val(username ? username : '');

                // Display encrypted password if the current user is not the owner of the credential
                if (password) {
                    fetch('/credentials/decrypt?credentialId=' + credentialId)
                        .then(response =>
                            console.log(response))
                        .catch(() =>
                            $('#credential-password').val('error'));
                } else {
                    $('#credential-password').val('');
                }

                $('#credentialModal').modal('show');
            }

控制器

    @GetMapping("/decrypt")
    public void doGet(HttpServletResponse response,Authentication authentication,
                                     @ModelAttribute Credential credential) throws IOException {
        User user = getCurrentUser(authentication);
        credential = credentialService.getCredential(credential.getCredentialId());

        boolean result = validationService.validate(credential, user);
        if (result) {
            String decryptedPassword = credentialService.decryptPassword(credential);

            response.setContentType("text/plain");
            response.setCharacterEncoding("UTF-8");
            try (PrintWriter out = response.getWriter()) {
                out.print(decryptedPassword);
                out.flush();
            }
        }
    }

回复:

Response {type: "basic", url: "http://localhost:8080/credentials/decrypt?credentialId=1", redirected: false, status: 200, ok: true, …}
body: ReadableStream
locked: false
__proto__: ReadableStream
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: ""
type: "basic"
url: "http://localhost:8080/credentials/decrypt?credentialId=1"
__proto__: Response

尝试调试。其实上面写的东西很难看懂。这可能是某些情况,但请确保“结果”returns 始终为假。 一些调试问题:

  1. 方法 getCurrentUser() 可以使用 null 吗?
  2. credentialId;它使用您在 fetch 方法中传递的 URL 个参数。

我建议使用 Spring 文档中的示例重写此代码。 现在您似乎从不同的指南中复制了一些片段。

您的客户端只是将响应打印到控制台:

.then(response => console.log(response))

它显示了 ReadableStream 未被消耗的正文的响应:

body: ReadableStream
...
bodyUsed: false

您需要读取该流的内容以获取 servlet 返回的内容。参见示例:

现在你只是将 Response 转储到控制台,它的字符串表示不是你期望的那样(即它不是内容而是它的包装)。您的 servlet 代码看起来不错,这是您的 JavaScript 客户端需要修改以从响应中读取内容。