在 ContainerRequestContext entityStream 中读取和设置相同数据后,@FormParameter 数据变为 null
@FormParameter data becomes null after reading and setting the same data in ContainerRequestContext entityStream
我已经实现了过滤器,我已经调用了 ContainerRequestContext 的 getEntityStream 并使用 setEntitystream 设置了准确的值。如果我使用这个过滤器,那么@FormParameter 数据变为空,如果我不使用过滤器,那么一切都会好起来的(因为我没有调用 getEntityStream),我必须使用过滤器来捕获请求数据。
注意:我从 MultivaluedMap formParams 而不是从 @FormParameter 获取表单参数。
环境:- 高枕无忧 API 使用 Jboss Wildfly 8 服务器。
@Provider
@Priority(Priorities.LOGGING)
public class CustomLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter{
final static Logger log = Logger.getLogger(CustomLoggingFilter.class);
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext)
throws IOException {
MDC.put("start-time", String.valueOf(System.currentTimeMillis()));
String entityParameter = readEntityStream(requestContext);
log.info("Entity Parameter :"+entityParameter);
}
private String readEntityStream(ContainerRequestContext requestContext){
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
final InputStream inputStream = requestContext.getEntityStream();
final StringBuilder builder = new StringBuilder();
int read=0;
final byte[] data = new byte[4096];
try {
while ((read = inputStream.read(data)) != -1) {
outStream.write(data, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
}
byte[] requestEntity = outStream.toByteArray();
if (requestEntity.length == 0) {
builder.append("");
} else {
builder.append(new String(requestEntity));
}
requestContext.setEntityStream(new ByteArrayInputStream(requestEntity) );
return builder.toString();
}
return null;
}
}
class customResource
{
//// This code is not working
@POST
@Path("voiceCallBack")
@ApiOperation(value = "Voice call back from Twilio")
public void voiceCallback(@FormParam("param") String param)
{
log.info("param:" + param);
}
// This code is working
@POST
@Path("voiceCallBackMap")
@ApiOperation(value = "Voice call back from Twilio")
public void voiceCallbackMap(final MultivaluedMap<String, String> formParams)
{
String param = formParams.getFirst("param");
}
}
请给我建议解决方案并提前致谢。
我在 运行 期间发现实体流实例(来自 http 请求)的类型为 org.apache.catalina.connector.CoyoteInputStream(我正在使用 jboss-as-7.1.1.Final).但是我们正在使用 java.io.ByteArrayInputStream 的实例设置实体流。所以Resteasy无法绑定单独的formparmeters。
有两种解决方案,您可以使用其中的任何一种:
- 使用这种方法How to read JBoss Resteasy's servlet request twice while maintaing @FormParam binding?
- 像这样获取表单参数:
@POST
@Path("voiceCallBackMap")
@ApiOperation(value = "Voice call back from Twilio")
public void voiceCallbackMap(final MultivaluedMap<String, String> formParams)
{
String param = formParams.getFirst("param");
}
我已经实现了过滤器,我已经调用了 ContainerRequestContext 的 getEntityStream 并使用 setEntitystream 设置了准确的值。如果我使用这个过滤器,那么@FormParameter 数据变为空,如果我不使用过滤器,那么一切都会好起来的(因为我没有调用 getEntityStream),我必须使用过滤器来捕获请求数据。
注意:我从 MultivaluedMap formParams 而不是从 @FormParameter 获取表单参数。
环境:- 高枕无忧 API 使用 Jboss Wildfly 8 服务器。
@Provider
@Priority(Priorities.LOGGING)
public class CustomLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter{
final static Logger log = Logger.getLogger(CustomLoggingFilter.class);
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext)
throws IOException {
MDC.put("start-time", String.valueOf(System.currentTimeMillis()));
String entityParameter = readEntityStream(requestContext);
log.info("Entity Parameter :"+entityParameter);
}
private String readEntityStream(ContainerRequestContext requestContext){
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
final InputStream inputStream = requestContext.getEntityStream();
final StringBuilder builder = new StringBuilder();
int read=0;
final byte[] data = new byte[4096];
try {
while ((read = inputStream.read(data)) != -1) {
outStream.write(data, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
}
byte[] requestEntity = outStream.toByteArray();
if (requestEntity.length == 0) {
builder.append("");
} else {
builder.append(new String(requestEntity));
}
requestContext.setEntityStream(new ByteArrayInputStream(requestEntity) );
return builder.toString();
}
return null;
}
}
class customResource
{
//// This code is not working
@POST
@Path("voiceCallBack")
@ApiOperation(value = "Voice call back from Twilio")
public void voiceCallback(@FormParam("param") String param)
{
log.info("param:" + param);
}
// This code is working
@POST
@Path("voiceCallBackMap")
@ApiOperation(value = "Voice call back from Twilio")
public void voiceCallbackMap(final MultivaluedMap<String, String> formParams)
{
String param = formParams.getFirst("param");
}
}
请给我建议解决方案并提前致谢。
我在 运行 期间发现实体流实例(来自 http 请求)的类型为 org.apache.catalina.connector.CoyoteInputStream(我正在使用 jboss-as-7.1.1.Final).但是我们正在使用 java.io.ByteArrayInputStream 的实例设置实体流。所以Resteasy无法绑定单独的formparmeters。
有两种解决方案,您可以使用其中的任何一种:
- 使用这种方法How to read JBoss Resteasy's servlet request twice while maintaing @FormParam binding?
- 像这样获取表单参数:
@POST @Path("voiceCallBackMap") @ApiOperation(value = "Voice call back from Twilio") public void voiceCallbackMap(final MultivaluedMap<String, String> formParams) { String param = formParams.getFirst("param"); }