我正在基于Tomcat servlet和NIO创建服务。输入时有大的XML请求(约100 MB),通过HTML POST方法发送。我只想流前8千磅,然后立即发送响应到客户端。
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]套接字:[org.apache.tomcat.util.net.NioEndpoint$KeyAttachment@74f19fed:组织。阿帕奇。公猫util。网NioChannel@c478210:java。nio。频道。SocketChannel[connected local=/0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:0:1:63943]],状态为:[OPEN\u READ],状态为:[OPEN]
但,若我尝试发送更大的请求(超过100MB),客户端并没有响应。
2016-02-01 10:48:42 Http11NioProtocol[DEBUG]套接字:[org.apache.tomcat.util.net.NioEndpoint$KeyAttachment@2b36c88f:组织。阿帕奇。公猫util。网NioChannel@25f12241:java。nio。频道。SocketChannel[connected local=/0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:0:1:64079]],状态为in:[OPEN\u READ],状态为out:[CLOSED]
2016-02-01 10:48:42超文本传输协议-Nio-8080-exec-3
在我读取整个输入流请求之前,Tomcat不想打开套接字(State out: CLOSED)。
是否可以在不读取整个请求的情况下将响应发送到客户端?根据规范,我能够在请求的前8 KiB上找到有趣的me信息。
你的代码只是请求的一部分,
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直接将流转换为字符串
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个字节),方法读取将返回读取的字节数,因为根本不会读取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
}
}
问题内容: 是否有一种隐藏的方法可以在 不 读取整行的 情况下 从文件或类似文件的对象读取令牌?我立即拥有的应用程序(其他人的问题,不是我的问题)正在将具有几个非常长的行的大型矩阵转置,本质上是对选择单个列元素的迭代器执行操作。这个想法不是在迭代过程中将整个文件存储在内存中。 这些行是用空格分隔的ASCII十进制数字。 对于Java的Scanner类,问题可能很简单,但我没有在Python标准库中
(Java版本8) 我需要在过滤器中处理请求正文。使用下面的代码,我读取了正文。 问题是如果请求正文发布的参数的内容类型为“Application/x-www-form-urlencoded”,那么这些参数在读取正文后将不可用。如果我不读取正文,它们可以使用request.getParameter()获取。 此外,我尝试使用以下代码包装请求并提供正文,这样解决方案的其余部分(例如servlet)就
我正在建立一个应用程序,用户将把他们的测试和作业和任何东西。我想知道我的应用程序是否有可能在测试前一周和一天发出通知? 我看到的到处都是firebase通知和push通知。 我不想要这些在线通知,我将需要应用程序发送他们自己离线。这可能吗?
问题内容: 我有一个实现接口的类型,该接口在其方法中检查传入的HTTP请求,采取某些措施,然后将请求转发到反向代理处理程序()。 只要我仅检查基本的请求属性(例如URL或标头),此方法就可以正常工作。 当我想检查传入的POST请求的主体(例如,通过调用然后使用属性)时,将请求传递到反向代理后,就会遇到错误: 我认为发生这种情况是因为查看HTTP请求的正文会导致流被耗尽,这意味着代理处理程序无法再次
null 但是,当与HTTP1建立连接时,最后调用。 http1ExchangeCodeC.FixedLengthSource::Close 然后,方法读取所有响应体源,如下所示。
问题内容: 我只是想知道是否可以在不将Outlook安装在服务器上且不使用COM Interop的情况下向人们发送会议请求(我不惜一切代价避免在服务器上使用)。 我们在Windows 2003域中拥有Exchange 2003,并且所有用户都是域用户。我想我可以发送’round iCal / vCal之类的东西,但是我想知道是否存在通过Exchange在不使用Outlook的情况下发送会议请求的适