java - HttpClient和HttpServer之间通信的Java问题
问题描述
这是我在这里的第一个问题,所以如果不是所有需要的信息都在这篇文章中,我深表歉意。
java.net.http.HttpClient 和 HttpServer 之间的通信有问题。我从带有 HttpClient 的应用程序向带有 Httpserver 的应用程序发送请求,后者读取该请求,根据消息中的信息发送邮件并使用 HttpClient 向应用程序发送响应,如果一切正常则成功,如果出现问题则失败。
前几次(随机多少次,有时 2 次有时 24 次)通常正确发送并由服务器正确处理,这导致 httpClient 接收响应“成功”,但突然服务器收到带有正确标头但没有正文的请求,即使它总是请求中的同一条消息,导致“失败”响应。
我的 HttpClient:
private Boolean sendMail(String requestBody) throws IOException, InterruptedException {
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.cookieHandler(CookieHandler.getDefault())
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(this.uri))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
//creating response body handler
HttpResponse.BodyHandler<String> bodyHandler = HttpResponse.BodyHandlers.ofString();
HttpResponse<String> response = client
.send(request, bodyHandler);
String requestOutcome = response.body();
System.out.println(requestOutcome);
我的HttpServer:
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
server.createContext("/mial", new ServerHttpHandler(this.dbHandler, this.mailHandler));
server.setExecutor(threadPoolExecutor);
//Start HttpServer
server.start();
我的自定义 ServerHttpHandler:
public void handle(HttpExchange httpExchange) throws IOException {
String requestParamValue=null;
if("GET".equals(httpExchange.getRequestMethod())) {
requestParamValue = handleGetRequest(httpExchange);
}else if("POST".equals(httpExchange.getRequestMethod())) {
requestParamValue = handlePostRequest(httpExchange);
}
handleResponse(httpExchange,requestParamValue);
}
private String handleGetRequest(HttpExchange httpExchange) {
return httpExchange.
getRequestURI()
.toString()
.split("\\?")[1]
.split("=")[1];
}
private String handlePostRequest(HttpExchange httpExchange){
// get request
Headers reqHeaders = httpExchange.getRequestHeaders();
reqHeaders.forEach((key, value) -> System.out.println(key + ": " + value));
String message = null;
try (InputStream in = httpExchange.getRequestBody()) {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuilder msgbuilder = new StringBuilder();
while (br.ready()) {
msgbuilder.append((char) br.read());
}
message = msgbuilder.toString();
System.out.println("Message: " + message);
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return message;
}
private void handleResponse(HttpExchange httpExchange, String requestParamValue) throws IOException {
boolean success = this.convertMsgAndSendMail(requestParamValue);
String htmlResponse = "failure";
if(success) {
htmlResponse = "success";
}
httpExchange.sendResponseHeaders(200, htmlResponse.length());
OutputStream outputStream = httpExchange.getResponseBody();
outputStream.write(htmlResponse.getBytes());
outputStream.flush();
outputStream.close();
}
错误请求:
Connection: [Upgrade, HTTP1_1-Settings]
Http2-settings: [AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA]
Host: [localhost:587]
Upgrade: [h2c]
User-agent: [Java-http-client/11.0.6]
Content-type: [application/json]
Content-length: [180]
Message:
所以标题每次都是一样的,但这次我没有收到任何消息。由于消息稍后转换为 JSON,我得到的唯一错误是消息不以“{”开头,因此它不是 Json 兼容的。
我搜索了 StackOverflow 和其他网站来解决这个问题,但没有找到任何有用的提示来解决这个问题。你有什么主意吗?
解决方案
这里有几个错误:
- 将字节转换为字符(反之亦然)时,您应该始终指定一个字符集;这不是您的主要问题所在,但您应该考虑它。
- 您的 while 循环是错误的。
你有:
while (br.ready()) {
msgbuilder.append((char) br.read());
}
这样做的作用是,如果一个字符不能立即可用,它将停止阅读;您想要的是在没有更多字符可阅读时停止阅读。这应该是这样的:
int c;
while ((c = br.read()) > -1) {
msgbuilder.append((char) c);
}
推荐阅读
- elasticsearch - 弹性搜索 - 滚动行为
- ruby - 是否可以检查模块是否已包含在 RSpec 配置中?
- python-3.x - 将列表组合成一个网格参数
- r - 如何将 X 轴标签旋转 90 度(beanplot 包)?
- python - 将 Pytorch 4D 张量保存为图像
- go - 检查 json 是否在结构中具有除有效键之外的字段
- ios - 如何在顶部使用菜单创建分页?
- python - 为什么我不能在 OSX 上安装 Rasa?“确认 ssl 证书时出现问题”
- python - Scrapy dupefilter 过滤重定向即使使用 dont_filter=True
- c++ - C++ 中的 Perl 正则表达式替换(将 Perl 翻译打包和解包到 C++)