简体   繁体   中英

Why is HttpServletResponse body always empty?

My client is using the fetch api to interact with a Controller method that will decrypt a password and send the decrypted password back to the client as plain text. However, the response body never contains the password. It also continues to set the content type as basic even though I am setting it to text/plain . What am I doing wrong?

Client

            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');
            }

Controller

    @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:

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

Try to debug. Actually what is wrote over very difficult to understand. Here could be some cases, but sure that "result" returns always false. Some question for debugging:

  1. Could method getCurrentUser() be consumed with null?
  2. credentialId; It consumed from URL parameters that you pass in fetch method.

My suggestion to rewrite this code using samples in Spring Documentation. Now it looks like you copied some snippets from different guides.

Your client just prints the response to console:

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

which shows a response with a ReadableStream body that isn't consumed:

body: ReadableStream
...
bodyUsed: false

You need to read the content of that stream to get the content the servlet returned. See for example:

Right now you are just dumping the Response to console and its string representation isn't what you expect it to be (ie it's not the content but a wrapper for it). Your servlet code seems fine, it's your JavaScript client needs to be modified to read the content from within the response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM