我有一个应用程序可以创建服务器证书请求,就像使用Java密钥工具之类的一样。我正在尝试以zip文件形式返回创建的证书请求和密钥,但是为了我的生命,我无法让我的REST控制器响应http请求。更正:控制器作出响应,但是该方法中的代码从未执行。
服务器确实收到了请求,因为执行了我的CORS筛选器。但是我在控制器方法中设置了一个调试集,并且从未触发过它。方法的签名正确吗?我需要另一只眼睛吗?
这是我的控制器代码:
@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);
}
这是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;
}
最后,我从“网络面板”复制的请求和响应标头:
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
我真的很难让CORS工作,所以这可能会干扰请求?我讨厌发布所有这些代码,除非绝对必要。有人有想法吗?
答案 0 :(得分:1)
请求/响应标头的列表缺少有关URL,方法和最重要的响应状态代码的信息。
看到响应头中有Location: http://localhost:8102/login
,我猜可能是401 Unauthorized
或其他任何重定向到登录页面的内容。因此,如果过滤器链中存在auth过滤器,则可能是罪魁祸首。
以下请求标头
Host: localhost:8102
Origin: http://localhost:4200
建议您正在执行CORS,并且确实可能涉及CORS过滤器,并且在将请求路由到控制器之前会完成响应。我建议在CORS过滤器(以及其他(如果有的话)中)中设置一个断点,并将其调试到返回响应的位置。
答案 1 :(得分:0)
定义 proxy.conf.json
{
"/login*": {
"target":"http://localhost:8080",
"secure":false,
"logLevel":"debug"
}
}
现在在您的 package.json
中"scripts": {
"start":"ng serve --proxy-config proxy.config.json"
}
我认为两个webapp都存在连接问题,请尝试。
答案 2 :(得分:0)
当Angular遇到此语句
$extended = new ReflectionClass('\App\Mail\TestMail1');
$base = new ReflectionClass('\App\Mail\Mailable');
$properties_in = array_diff(
$extended->getProperties(ReflectionProperty::IS_PUBLIC),
$base->getProperties(ReflectionProperty::IS_PUBLIC)
);
dd($properties_in);
当服务继续执行时,它将立即返回以运行其余代码。就像Java中的Future。
如果在这里
this.http.post(url,body).subscribe(data => # some code
);
您将不会获得this.http服务最终可能填充的值。由于页面已经渲染并执行了代码。您可以通过在Observable的内部和外部添加此内容来进行验证。
return this.cert;
答案 3 :(得分:0)
感谢所有贡献者。我发现错误是由于控制器方法的标题引起的。更改它们之后,将正确调用该方法。这是有效的:
@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);
}