gpt4 book ai didi

java - 如何在不读取整个请求的情况下发送响应?

转载 作者:太空宇宙 更新时间:2023-11-04 12:58:47 24 4
gpt4 key购买 nike

我正在创建基于 Tomcat Servlet 和 NIO 的服务。输入时有大的 XML 请求(~100 MB),通过 HTML POST 方法发送。我只想传输前 8 KiB,然后立即向客户端发送响应。

public class A extends HttpServlet {
@Override
protected void service(HttpServletRequest rq, HttpServletResponse rs) {
byte[] buffer = new byte[1024*8];
try {
rq.getInputStream().read(buffer);
rs.setContentType("text/plain");
rs.getOutputStream().write("Some Response".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}

当我尝试发送小请求(内容中的几行)时没有问题,套接字工作正常。

2016-02-01 10:44:52 Http11NioProtocol [DEBUG] Socket: [org.apache.tomcat.util.net.NioEndpoint$KeyAttachment@74f19fed:org.apache.tomcat.util.net.NioChannel@c478210:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:63943]], Status in: [OPEN_READ], State out: [OPEN]

但是,如果我尝试发送更大的请求(超过 100 MB),客户端将没有响应。

2016-02-01 10:48:42 Http11NioProtocol [DEBUG] Socket: [org.apache.tomcat.util.net.NioEndpoint$KeyAttachment@2b36c88f:org.apache.tomcat.util.net.NioChannel@25f12241:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:64079]], Status in: [OPEN_READ], State out: [CLOSED]

2016-02-01 10:48:42 LimitLatch [DEBUG] Counting down[http-nio-8080-exec-3] latch=1

在我读取整个输入流请求之前,Tomcat 不想打开套接字(状态输出:已关闭)。

是否可以在不读取整个请求的情况下将响应发送到客户端?根据规范,我能够在请求的前 8 KiB 上找到我感兴趣的信息。

最佳答案

您的代码仅读取请求的一部分,

您可以使用此方法将 Stream 转换为 String

private static String convertStreamToString(InputStream is) throws IOException{
int i = 0;
byte[] buff = new byte[1024];
StringBuilder sb = new StringBuilder();
while (i != -1) {
i = is.read(buff);
if(i != -1){
sb.append(new String(buff,0,i));
}
}
return sb.toString();
}

所以,在你的代码中它将是

public class A extends HttpServlet {
@Override
protected void service(HttpServletRequest rq, HttpServletResponse rs) {

try {
String response = convertStreamToString(rq.getInputStream());
rs.getOutputStream().write(response.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
private static String convertStreamToString(InputStream is) throws IOException{
int i = 0;
byte[] buff = new byte[1024];
StringBuilder sb = new StringBuilder();
while (i != -1) {
i = is.read(buff);
if(i != -1){
sb.append(new String(buff,0,i));
}
}
return sb.toString();
}

}

或者您可以使用Scanner直接将您的 Stream 转换为 String

    Scanner scanner = new Scanner(inputStream);
StringBuilder sb = new StringBuilder();
while (scanner.hasNext()) {
sb.append(scanner.next());
}

所以,在你的代码中它应该是

public class A extends HttpServlet {
@Override
protected void service(HttpServletRequest rq, HttpServletResponse rs) {

try {
Scanner scanner = new Scanner(rq.getInputStream());
StringBuilder sb = new StringBuilder();
while (scanner.hasNext()) {
sb.append(scanner.next());
}
rs.getOutputStream().write(sb.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}

}

这段代码

byte[] buffer = new byte[1024*8];
rq.getInputStream().read(buffer);

只读取1024字节请求并将其存储到缓冲区数组(1024字节),方法read将返回读取了多少字节,因为根本不会读取1024字节,如果请求仅发送200字节,则824字节将无用。所以,如果请求只发送 200 字节

int x = rq.getInputStream().read(buffer);

这个 x 将为 200,因此要完整阅读,您需要进行循环

// integer to read
int bytesRead = 0;
// loop until bytesRead is -1 (end of request), -1 means there are no bytes to read, so it will read until there are no bytes to read
while(bytesRead != -1){
bytesRead = rq.getInputStream().read(buffer);
if(bytesRead != -1){
// process the bytes here , but only process bytes from 0 to bytesRead
}
}

关于java - 如何在不读取整个请求的情况下发送响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35127474/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com