Issue
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
Solution
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 (i.e. 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.
Answered By - Bogdan
Answer Checked By - Marilyn (JavaFixing Volunteer)