我正在使用Java的RESTful Web服务。如果出现问题,我需要一种向客户端发送错误消息的好方法。
根据Javadoc,HttpServletResponse.setStatus(int status, String message)
由于消息参数含义不明确而被弃用“。
是否有首选方式设置状态消息或响应的“reason phrase”? sendError(int, String)
方法不会这样做。
编辑:
为了澄清,我想修改HTTP状态行,即"HTTP/1.1 404 Not Found"
,而不是正文内容。具体来说,我想发送像"HTTP/1.1 400 Missing customerNumber parameter"
这样的回复。
答案 0 :(得分:21)
我认为任何RESTful客户端都不会期望查看出现问题的原因。我见过/使用过的大多数RESTful服务都会在响应正文中发送标准状态信息和扩展消息。 sendError(int, String)
非常适合这种情况。
答案 1 :(得分:18)
如果您使用的是Tomcat,请参阅设置org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER:
http://tomcat.apache.org/tomcat-5.5-doc/config/systemprops.html
有关原始漏洞的详细信息,请参阅此页:
http://www.securityfocus.com/archive/1/archive/1/495021/100/0/threaded
答案 2 :(得分:12)
在澄清之后,我在Tomcat中尝试了这个。执行
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "message goes here");
返回
HTTP/1.1 400 message goes here
作为回复中的第一行。
您正在使用的servlet容器一定存在问题。
答案 3 :(得分:2)
我不太熟悉REST的“最佳实践”。但我知道这个概念是基于HTTP以及它应该如何自然地解决。那么如何在主体内部使用mime类型和简单文本来解决应用程序错误,例如'application / myapp-exception'和一些'Bla bla'?您可以为此提供客户端库。
我不会将HTTP响应代码用于应用程序错误。因为我想知道什么是失败的:无论是我的应用程序还是我的HTTP服务器。
(我希望,我也会在这里看到一些最佳实践建议。)
答案 4 :(得分:0)
你想要完成的事情并不是很清楚。我的第一个想法是sendError,但是你说它没有做你想要的...你看过创建一组“错误响应”,意思是特定的xml或JSON内容(或者你用作转移语言的任何东西)包含错误消息或代码以及任何其他有用信息?
我曾经为基于Spring-mvc的RESTful服务做了类似的事情,但它运行良好但你必须抓住并处理每个异常,以防止客户端获得通用的500消息或其他东西。 Spring异常解析器在这方面运作良好。
希望这会有所帮助......如果没有,也许可以更清楚地了解你想要实现的目标。对不起,如果我是密集的,并且遗漏了一些明显的东西。
答案 5 :(得分:0)
我认为sendError
应该这样做,但你的应用服务器可能会失败......很久以前IBM WebSphere 3.5在我身上失败了,而Tomcat会传播消息就好了;请参阅Sun论坛上的JavaServer Pages (JSP) and JSTL - Error page: preserve header "HTTP/1.x 400 My message"?。
最终我使用了以下解决方法,但这是一种特定于JSP的,实际上可能是旧的:
<%@ page isErrorPage="true" %>
<%
// This attribute is NOT set when calling HttpResponse#setStatus and then
// explicitely incuding this error page using RequestDispatcher#include()
// So: only set by HttpResponse#sendError()
Integer origStatus =
(Integer)request.getAttribute("javax.servlet.error.status_code");
if(origStatus != null) {
String origMessage =
(String)request.getAttribute("javax.servlet.error.message");
if(origMessage != null) {
response.reset();
response.setContentType("text/html");
// deprecated, but works:
response.setStatus(origStatus.intValue(), origMessage);
// would yield recursive error:
// response.sendError(origStatus, origMessage);
}
}
%>
如果您碰巧使用Internet Explorer进行测试:禁用“显示友好的HTTP错误消息”。 (当没有禁用它时,IE对HTML内容的某些最小长度有一些奇怪的要求,如果不满足,将会 - 或者 - 会使IE显示自己的错误消息。另请参阅注册表项HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\ErrorThresholds
at微软的Description of Hypertext Transport Protocol Error Messages。)
答案 6 :(得分:0)
在Spring驱动的Web应用程序中,在Tomcat上运行我使用以下bean:
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.springframework.beans.factory.InitializingBean;
public class SystemPropertiesInitializingBean implements InitializingBean {
private Map<String, String> systemProperties;
@Override
public void afterPropertiesSet() throws Exception {
if (null == systemProperties || systemProperties.isEmpty()) {
return;
}
final Set<Entry<String, String>> entrySet = systemProperties.entrySet();
for (final Entry<String, String> entry : entrySet) {
final String key = entry.getKey();
final String value = entry.getValue();
System.setProperty(key, value);
}
}
public void setSystemProperties(final Map<String, String> systemProperties) {
this.systemProperties = systemProperties;
}
}
在applicationContext.xml中:
<bean class="....SystemPropertiesInitializingBean">
<property name="systemProperties">
<map>
<entry key="org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER" value="true"/>
</map>
</property>
</bean>