首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HttpClient与HttpServer通信中的Java问题

HttpClient与HttpServer通信中的Java问题
EN

Stack Overflow用户
提问于 2020-11-09 02:06:29
回答 1查看 81关注 0票数 0

这是我在这里的第一个问题,所以我很抱歉,如果不是所有需要的信息都会在这篇文章中出现。

我在java.net.http.HttpClient和HttpServer之间的通信有问题。我用HttpClient从应用程序向Httpserver应用程序发送请求,后者读取,根据消息中的信息发送邮件,并用HttpClient向应用程序发送响应,如果一切正常则成功,如果出现问题则失败。

最初的几次(这是随机的多少次,有时2次,有时24次)通常被服务器正确地发送和处理,这导致httpClient接收响应“成功”,但是突然服务器得到的请求具有正确的头部但没有主体,即使它总是请求中的同一条消息,这导致“失败”响应。

我的HttpClient:

代码语言:javascript
复制
    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:

代码语言:javascript
复制
   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:

代码语言:javascript
复制
 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();
}

错误的请求:

代码语言:javascript
复制
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和其他网站上搜索了这个问题的解决方案,但没有找到任何解决这个问题的有用提示。你有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2020-11-11 00:16:36

这里有几个错误:

  1. 在将字节转换为字符(反之亦然)时,您确实应该始终指定一个字符集;这不是您的主要问题所在,但您应该考虑它。
  2. 您的while循环是错误的。

您必须:

代码语言:javascript
复制
while (br.ready()) {
   msgbuilder.append((char) br.read());
}

这样做的目的是,如果一个字符不能立即可用,它将停止读取;您想要的是,当没有更多的字符可读时停止读取。这应该是这样的:

代码语言:javascript
复制
int c;
while ((c = br.read()) > -1) {
    msgbuilder.append((char) c);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64741454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档