我正在使用具有云功能的收据打印机。它与我正在实现的服务器规范通信。它每x秒轮询一个带有POST请求的URL,当POST响应包含特定信息时,打印机会发送GET请求到同一URL获取要打印的信息。
我将打印服务器实现为Spring Boot服务器,并遇到了一些奇怪的POST方法问题,需要一些帮助。
我的问题是来自打印机的POST请求从未到达控制器。然而,我能够从Postman发送一个POST请求到完全相同的URL,并且该请求可以被控制器处理。
URL只是:https://www.[my-domain].com:[port-number]/cloudprint
此外,我已经尝试将控制器方法复制到另一个Spring(非Boot)应用程序中,在Apache后面运行Tomcat实例,那里打印机的POST请求由控制器方法处理。我可以在Apache日志和Tomcat日志中看到它们。当前轮询频率为10秒。
以下是控制器的样子:
package com.[my-domain].[application-name].controller;
[a bunch of imports]
@RestController
@CrossOrigin
public class PrintController {
Logger logger = LoggerFactory.getLogger(PrintController.class);
@RequestMapping(value="/cloudprint", method=RequestMethod.POST,
headers={"Accept=application/json"})
@ResponseStatus(HttpStatus.CREATED)
public @ResponseBody String printPost() {
logger.debug("in printPost");
return "OK";
}
@RequestMapping(value="/cloudprint", method=RequestMethod.GET,
headers={"Accept=application/json"})
@ResponseStatus(HttpStatus.OK)
public @ResponseBody String printGet(HttpServletRequest request) {
logger.debug("in printGet");
return "OK";
}
@RequestMapping(value="/cloudprint", method=RequestMethod.DELETE,
headers={"Accept=application/json"})
@ResponseStatus(HttpStatus.OK)
public @ResponseBody String printDelete() {
logger.debug("in printDelete");
return "OK";
}
}
可能是什么原因导致这个问题?我可以测试什么来解决这个问题?
---2019-06-03 @13:21 cet更新以下信息--- 由于我有一个常规的Spring(非boot)应用程序,可以接受来自打印机的POST请求,因此我可以记录传入请求中的信息。所以我做了这个。
这是来自打印机的一个POST请求,但Spring Boot控制器没有接受它:
auth type: null
content type: application/json
-- HEADERS --
Header: host : dev.[our-domain-name].com
Header: accept : */*
Header: user-agent : Cente HTTPc
Header: content-type : application/json
Header: content-length : 303
Header: connection : keep-alive
QueryString: null
-- PARAMETERS --
END
这是Postman发送到完全相同URL的POST请求之一,Spring boot控制器已接受该请求:
auth type: null
cotent type: application/json
-- HEADERS --
Header: content-type : application/json
Header: cache-control : no-cache
Header: Postman-Token : caf99fa1-4730-4193-aab3-c4874273661d
Header: user-agent : PostmanRuntime/7.6.0
Header: accept : */*
Header: host : dev.[our-domain-name].com
Header: accept-encoding : gzip, deflate
Header: content-length : 0
Header: connection : keep-alive
QueryString: null
-- PARAMETERS --
END
分析:
1. 用户代理标头不同。
2. 内容长度标头不同。
3. Postman请求具有云打印机请求中没有的三个标头。它们是:cache-control、Postman-token和accept-encoding。---以下为2019-06-03 @17:56 cet时添加的信息--- 好的,我找到了如何记录消息正文的方法。这是一个格式良好的JSON结构,确实有303个字符:
{"status": "29 a 0 0 0 0 0 0 0 0 0 0",
"printerMAC": "00:11:62:1b:xx:xx",
"statusCode": "200%20OK",
"printingInProgress": false,
"clientAction": null,
"display": [
{"name": "MainDisplay" ,
"status": {"connected": false}}],
"barcodeReader": [
{"name": "MainBCR" ,
"status": {"connected": false,"claimed": false}}]}
我创建了相应的类,并将Boot应用程序中的POST方法更改为以下内容:
@RequestMapping(value="/cloudprint", method=RequestMethod.POST,
headers={"Accept=application/json"})
@ResponseStatus(HttpStatus.CREATED)
public @ResponseBody String printPost(@RequestBody PrinterPostRequest printerPostRequest,
HttpServletRequest request) {
HttpRequestLogger.log(request);
return "OK";
}
但是,它无法从打印机接收POST请求。它能够接收来自Postman的请求,并将请求体json成功地转换为类。
---2019-06-05@10:16 CET以下补充信息--- 我有一个想法。使用Spring RestTemplate,我发送了一个POST请求到引导应用程序,具有与打印机发送的请求相同的标头和有效负载。我得到了一个org.springframework.web.client.ResourceAccessException错误,其消息为:
I/O error on POST request for "https://boot.[my-domain].com:8443/cloudprint":sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target