web-dev-qa-db-fra.com

Printemps REST Le contrôleur ne répond pas à Angular demande

J'ai une application pour créer des demandes de certificat de serveur, comme si on utilisait le keytool Java ou quelque chose du genre. J'essaie de renvoyer la demande de certificat créée et la clé dans un fichier Zip, mais je ne peux pas permettre à mon contrôleur REST de répondre à la demande http. CORRECTION: le contrôleur répond, mais le code de la méthode n'est jamais exécuté.

Le serveur reçoit la demande, car mon filtre CORS est exécuté. Mais j'ai un ensemble de débogage dans la méthode du contrôleur, et il n'est jamais déclenché. La signature de la méthode est-elle correcte? J'ai besoin d'un autre regard, s'il vous plaît?

Voici mon code de contrôleur:

@RequestMapping(method = RequestMethod.POST, value = "/generateCert/")
public ResponseEntity<InputStreamResource> generateCert(@RequestBody CertInfo certInfo) {
    System.out.println("Received request to generate CSR...");

    byte[] responseBytes = commonDataService.generateCsr(certInfo);
    InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(responseBytes));

    System.out.println("Generated CSR with length of " + responseBytes.length);
    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=certificate.Zip")
            .contentType(MediaType.parseMediaType("application/Zip"))
            .contentLength(responseBytes.length)
            .body(resource);
}

Et voici la requête Angular:

generateCertificate(reqBody: GenerateCert) {
   let headers = new Headers();
   headers.append('Content-Type', 'application/json');

   this.http.post(this.urlGenerateCert, JSON.stringify(reqBody), {headers: headers}).subscribe(
    (data) => {
        let dataType = data.type;
        let binaryData = [];
        binaryData.Push(data);
        this.certBlob = new Blob(binaryData);
    });
    return this.certBlob;
 }

Et enfin, les en-têtes de demande et de réponse que j'ai copiés à partir du panneau de réseau:

Response
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, Authorization, Accept, X-Requested-With, remember-me
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Thu, 27 Dec 2018 22:48:00 GMT
Expires: 0
Location: http://localhost:8102/login
Pragma: no-cache
Set-Cookie: JSESSIONID=EDACE17328628D579670AD0FB53A6F35; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

Request
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 205
Content-Type: application/json
Host: localhost:8102
Origin: http://localhost:4200
Referer: http://localhost:4200/generateCerts
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36

J'ai vraiment eu du mal à faire fonctionner la SCRO, alors peut-être que cela interfère avec la demande? Je déteste publier tout ce code sauf si absolument nécessaire. Quelqu'un a des idées?

5
user1660256

Merci à tous ceux qui ont contribué. J'ai découvert que l'erreur était due aux en-têtes de ma méthode de contrôleur. Après les avoir modifiées, la méthode a été invoquée correctement. C'est ce qui a fonctionné:

@RequestMapping(method = RequestMethod.POST, path = "/generateCert", 
    produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE}, consumes = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<byte[]> generateCert(@RequestBody CertInfo certInfo) {
    byte[] responseBytes = commonDataService.generateCsr(certInfo);    
    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
            .contentLength(responseBytes.length)
            .body(responseBytes);
}
0
user1660256

La liste des en-têtes de demande/réponse manque d'informations sur l'URL, la méthode et le code de statut de réponse le plus important.

En voyant Location: http://localhost:8102/login parmi les en-têtes de réponse, je peux deviner qu'il pourrait s'agir de 401 Unauthorized ou de tout autre élément redirigeant vers la page de connexion. Par conséquent, s’il existe un filtre d’authentification dans la chaîne de filtrage, il peut s’agir d’un coupable.

Les en-têtes de requête suivants

Host: localhost:8102
Origin: http://localhost:4200

suggère que vous utilisez CORS et que le filtre CORS peut effectivement être impliqué et répondre avant que la demande ne soit acheminée vers le contrôleur. Je suggère de définir un point d'arrêt dans le filtre CORS (et dans d'autres, le cas échéant) et de le déboguer au point où la réponse est renvoyée.

1
Oleg Kurbatov

définir un proxy.conf.json  

{
"/login*": {
    "target":"http://localhost:8080",
    "secure":false,
    "logLevel":"debug"
    }
} 

maintenant dans votre package.json  

"scripts": {
    "start":"ng serve --proxy-config proxy.config.json"
}

Je pense qu'il y a un problème lors de la connexion dans les deux applications webapp.please.

0
this_is_om_vm

Quand Angular rencontre cette déclaration 

this.http.post(url,body).subscribe(data => # some code
);

Il revient immédiatement pour exécuter le reste du code pendant que le service continue à s'exécuter. Tout comme Future en Java.

Ici si vous

return this.cert;

Vous n'obtiendrez pas la valeur pouvant éventuellement être renseignée par le service this.http. Depuis la page a déjà été rendue et le code exécuté. Vous pouvez le vérifier en incluant ceci à l'intérieur et à l'extérieur de l'Observable.

console.log(“Inside/outside observable” + new Date().toLocalTimeString());
0
Nikhil