我试图编写一个检查用户凭据的方法,如果这些是正确的解析发送的JSON。它工作正常,但我无法访问JSON。在我的代码中有一个命令InputStream inputStream = request.getInputStream();
应该读取JSON,但每次返回org.apache.catalina.connector.CoyoteInputStream@3f1e9348
。请看一下我的代码:
@POST
@Path("auth")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_HTML)
public String controller(@Context HttpServletRequest request) {
String authorization = request.getHeader("Authorization");
if (authorization == null) {
authorization = request.getHeader("authorization");
}
String basicHeader = "basic";
if (authorization != null && authorization.toLowerCase().startsWith(basicHeader)) {
String base64Credentials = authorization.substring(basicHeader.length()).trim();
String credentials = new String(Base64.getDecoder().decode(base64Credentials),
Charset.forName("UTF-8"));
String[] values = credentials.split(":", 2);
}
try {
InputStream inputStream = request.getInputStream();
System.out.println(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
当我尝试使用request.getReader()
时,我会收到臭名昭着的IllegalStateException: getInputStream() has already been called for this request
例外情况。请参阅相关的代码:
if ("POST".equalsIgnoreCase(request.getMethod()))
{
try {
String req = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
} catch (IOException e) {
e.printStackTrace();
}
}
我使用curl发送POST
:
curl -u myusername:mypasswor -H "Content-Type: application/json"
-X POST -d '{"username":"xyz","password":"xyz"}' localhost
答案 0 :(得分:0)
您可以通过在方法上声明参数来获取您的身体内容:
public String controller(String body, @Context HttpServletRequest request)
但您也可以使用JAX-RS实现将该JSON反序列化为您的预期类型:
public String controller(MyExpectedType body, @Context HttpServletRequest request)
这应该有效,因为您已经宣布了您的预期内容类型,假设您有一个适用的提供商(例如jackson-jaxrs ......)。
关于输入流错误:这可能是因为容器JAXRS实现已经解析了请求。
但如果您要在正常情况下处理它,例如在servlet中,您仍然需要更正您阅读它的方式:
getInputStream
州的文件:
使用ServletInputStream以二进制数据的形式检索请求的主体。可以调用此方法或getReader()来读取正文,而不是两者。
这意味着要获取客户端在正文中发送的内容,您需要阅读流:
String body = request.getReader().lines()
.collect(Collectors.joining("\n"));
您还可以使用基于Stream
的API:
byte[] bytes = new byte[request.getContentLength()];
request.getInputStream().read(bytes);
String body = new String(bytes); //you may need to specify the character set
实际的输入流类是基于实现的(容器提供的),所以你不应该关注CoyoteInputStream