-
有关Servlet的HttpServletRequest对象及其属性inputStream的疑问5
目前遇到这样一个问题,点击页面的一个按钮,然后组装查询报表参数,去发送一个请求到cognos报表服务器。由于生产环境不允许客户端直接去访问cognos服务器,所以做了一个转发:
在web服务器与cognos服务器中间用了一个Filter进行拦截,将参数请求重新组装,通过URLConnection的方式向cognos服务器发送请求,然后接收报表服务器的响应,并向客户端展示报表页面。
但是现在遇到一个问题,当查询数据量过大时,报表查询出错,报“RSV-BBP-0022 绝对亲和力请求“asynchWait_Request”失败,所请求的会话不存在。”的错误,不过我在测试时不用转发,直接发送请求到cognos,在相同的查询条件,相同的报表数据时,报表查询是正常的。因此感觉就是在转发时出的错(过滤了部分信息),打算用socket方式直接获取客户端ServletRequest发送过来的InputStream,这样就避免请求数据丢失。InputStream inputstream = request.getInputStream(); OutputStream os = socket.getOutputStream(); byte[] buffer = new byte[512]; while(true){ ind x = inputstream.read(); if(x==-1){ break; } os.write(buffer); }
可是第一次读到的x就是-1,就没法继续请求cognos,但是request.getMethod();request.getRequestURI();request.getParameterMap();等都是有值的,就是inputstream没信息,这个inputstream中到底存放的是http报文中的哪部分信息,与get或post方式有没有关系,想请教一下大家,对于request/response和http报文的关系,servlet中的InputStream和OutputStream的内容。
另:查询报表的按钮的事件为window.open(URL+?参数1&参数2&...&参数n,'newWindow');2012年12月21日 15:08
2个答案 按时间排序 按投票排序
-
一般情况下,request的inputStream是一次性读取,不能reset的。而request.getParameterMap()会把inputStream消费掉。因此如果你在filter里先使用了request.getParameterMap()或者其他与parameter有关的方法,然后再用URLConnection直接转发inputStream时,inputStream已经读到末尾了,自然转发出去的body是空的。
解决方法是在filter里取parameter之前,就把request的inputStream缓存到一个ByteArrayInputStream里。当然这时你再去取parameter就取不到post上来的参数了(URL上的参数还能取到)。如果你需要取body中的参数,那就要自己解释ByteArrayInputStream里的内容(做两次字符串split即可),解释完后记得调用ByteArrayInputStream上的reset方法,然后再把这个ByteArrayInputStream转发出去。
另外,request.inputStream不包括header部分,自然也不包括cookie,这可能是导致你会话丢失的原因。这部分你要自行复制。建议用Apache的HttpClient,比直接用URLConnection要方便。
另外,你做这种转发相当于是做一个反向代理,网上有个现成的可以参考 http://j2ep.sourceforge.net/ 。不过如果你在它之前加入自己filter并且取了request的parameter,同样有inputStream被消费无法正确转发的问题。你要在你的filter里把request换成一个基于ByteArrayInputStream的实现然后再往下传。2012年12月24日 21:30
-
request.getInputStream()是从request的body取数据,如果你的请求是get方式,那么是没有body部分的,所以inputstream.read()读不出数据是正常的,因为本来body就没有数据。
2012年12月21日 15:38
相关推荐
在自定义的`ServletInputStream`中实现`isReady()`、`setReadListener(ReadListener)`等相关方法以保持兼容性。 最后,为了在Spring Boot中使用这个自定义的`HttpServletRequestWrapper`,我们需要在适当的拦截器或...
javax.servlet.ServletInputStream javax.servlet.ServletContextEvent javax.servlet.ServletOutputStream javax.servlet.ServletRequestEvent javax.servlet.http.NoBodyResponse javax.servlet....
javax.servlet.ServletInputStream.class javax.servlet.ServletOutputStream.class javax.servlet.FilterChain.class javax.servlet.ServletRequestEvent.class javax.servlet.Filter.class javax.servlet....
Called by the servlet container to indicate to a servlet that the servlet is being taken out of service. destroy() - Method in class javax.servlet.GenericServlet Called by the servlet container to ...
如果是二进制数据,可以通过getInputStream方法获取ServletInputStream对象,获取数据。 HttpServletResponse对象提供了返回数据给用户的两个方法:一种是使用getWriter方法获取PrintWriter对象,用于返回文本数据...
### j2ee 九大内置对象及其方法详细说明 在J2EE(Java 2 Platform, Enterprise Edition)开发中,为了简化编程过程并提高代码的可维护性和可读性,引入了九大内置对象。这些对象自动地由容器创建,并提供给开发者...
Servlet利用HttpServletRequest对象的getPart方法来获取上传的文件。文件存储通常涉及到文件流操作,例如使用InputStream和OutputStream。完成文件保存后,Servlet可以通过HttpServletResponse向Flex客户端返回一个...
Servlet可以通过ServletInputStream对象读取请求信息。 ServletResponse接口允许Servlet建立响应头和状态代码。通过执行这个接口,Servlet有权使用ServletOutputStream类来向客户端返回数据。 多线程和映射\r 在多...
Servlet实例化过程中,Servlet容器会传递一个`ServletConfig`对象,这个对象包含了Servlet的配置信息,可以通过`getServletConfig()`方法获取。`ServletConfig`接口提供了获取初始化参数和其他上下文信息的方法。 `...
Java Servlet API 说明文档是一份关于Java Servlet技术的权威文档,涵盖了servlet容器中各个接口及其方法的详细解释。Servlet API是Java EE(Java Platform, Enterprise Edition)规范的一部分,主要用于开发基于...
对于文件上传,Java Web开发中常常使用Servlet技术,结合HttpServletRequest对象,可以接收客户端上传的文件。服务器端创建一个Servlet,重写doPost方法,通过request对象的getPart或getParts方法来获取上传的文件。...
在`doPost`中,我们可以遍历`HttpServletRequest`的`Part`对象集合,获取每个上传文件的信息。以下是一个基本示例: ```java @Override protected void doPost(HttpServletRequest request, HttpServletResponse ...
通过理解和熟练使用这些Servlet相关的概念和技术,开发者能够构建出强大的Web应用程序,提供动态网页内容和服务。Servlet是Java EE平台的核心组成部分,对于构建企业级Web应用来说至关重要。学习并掌握Servlet有助于...
在Servlet中,我们可以使用`HttpServletRequest`对象的`getPart`或`getParts`方法来获取上传的文件部分。 例如: ```java protected void doPost(HttpServletRequest request, HttpServletResponse response) { ...
初始化阶段,Servlet容器通过调用`init()`方法来初始化Servlet实例,并传递一个`ServletConfig`对象,这个对象包含了Servlet的配置信息。服务阶段,每次有请求到达,Servlet容器会调用`service()`方法,根据请求类型...
我们可以通过`HttpServletRequest`对象的`getParts()`方法获取所有上传的部分。然后,我们可以通过`Part`对象的方法如`write()`、`getInputStream()`等来处理文件内容。 对于进度条的实现,我们需要在客户端和...
类 ServletConfig ServletOutputStream ServletContext ServletInputStream ServletResponse GenericServlet ServletRequest Servlet <br>javax.servlet.http<br>接口 类 HttpSession Cookie...
【Jsp_Servlet_中文API档】主要涵盖了Java Servlet API中的关键接口和类,这些组件是构建基于Java的Web应用程序的基础。以下是对这些接口和类的详细解释: **一、RequestDispatcher接口** RequestDispatcher接口是...
Servlet技术广泛应用于文件上传和下载的功能实现,因为它们可以方便地与客户端交互并处理数据流。在本例中,我们将深入探讨如何使用Servlet来实现文件上传和下载功能。 首先,让我们了解文件上传的基本流程。当用户...
InputStream in = filePart.getInputStream(); // 保存文件到服务器 File saveFile = new File(savePath + filename); try (FileOutputStream out = new FileOutputStream(saveFile)) { byte[] buffer = new ...