我正在阅读HTTP POST,HTTP请求的主体可以是JSON或XML。 现在我已将读数委托给一个特殊的实用程序类。
interface HttpUtils
{
BodyWrapper parseBody( HttpServletRequest req );
}
interface BodyWrapper
{
boolean isXML(); // 1
boolean isJSON(); // 2
String body(); // 3
}
答案 0 :(得分:8)
不要向对象询问信息,然后就他们告诉您的内容做出决定。让您的对象为您完成工作。也就是说,不要这样做:
if (body.isXML()) {
// do XML stuff
}
else if (body.isJSON()) {
// do JSON stuff
}
这是一个令人头疼的问题。做这样的事情(BodyWrapper实现将使用abstract factory method或类似的)
创建public interface BodyWrapper {
Object doStuff();
}
public class DOMBodyWrapper implements BodyWrapper {
public Object doStuff() {
}
}
public class JSONBodyWrapper implements BodyWrapper {
public Object doStuff() {
// do something and return a success/failure result. I've
// deliberately not defined what this object is....
}
}
然后:
// get the body via a factory or similar
body.doStuff();
这样,某些东西会创建适当的BodyWrapper
实现,然后不再询问它是什么类型,而是使用它。请注意,BodyWrapper不会返回不同类型的内部结构,因为它(可能是一个抽象基类)正在为您完成工作。
答案 1 :(得分:3)
首先,HttpUtils
是通用名称的方式。我会选择HttpRequestParser
或其他什么。您还需要一个工厂,它将根据请求的内容类型(XmlRequestParser
或JsonRequestParser
)创建适当的实施。
就解析而言,我建议将XML和JSON解析为一些任意的内部表示(IR),这样堆栈中较高的代码就不会关注这些细节。 IR可以是XML文档,也可以是某个对象图。
答案 2 :(得分:3)
BodyWrapper
到底是什么意思? parseBody
不应该只返回de-seriealized对象?这可能是一个模型对象,也可能只是一个值包(字典/ map / hashtable)。
因此,parseBody
需要检查POST的类型然后反序列化。你期待什么数据?结果应该是一种类型,表示您希望客户端以java
方式发布的实际数据,无论 是如何发布的(jason) / xml)
答案 3 :(得分:2)
JSONObject和DOM节点彼此无关,继承明智。这意味着为了在返回类型上重载,它必须返回object
。这是一个令人讨厌的代码味道,因为你可能必须使用内省来找出返回的内容。通常在这种情况下,您应该在对象(主体)上使用虚拟方法,该方法能够以正确的方式对身体起作用,具体取决于实际情况。
答案 4 :(得分:2)
只是为了给你一些思考的东西,访问者模式的一种变体,其中数据类型与interitance无关,可以帮助你。
老实说,根据您的实际使用情况,在这种特殊情况下也可能会出现过度杀伤。
这是一些伪代码:
interface BodyTypesVisitor
{
void visit( DOMNode domNode );
void visit( JSONObject jsonObject );
}
interface BodyWrapper
{
void accept( BodyTypesVisitor );
}
interface HttpUtils
{
BodyWrapper parseBody( HttpServletRequest req );
}
class DOMVisitor implements BodyTypesVisitor
{
void visit( DOMNode domNode ) { /* do something useful with domNode */ }
void visit( JSONObject jsonObject ) { /* ignore */ }
}
class DOMBody implements BodyWrapper
{
...
void accept( BodyTypesVisitor visitor )
{ visitor.visit( this->domNode ); }
private DOMNode domNode;
}
...
// Process DOM
BodyWrapper wrapper = <some HttpUtils implementation that creates a DOMBody>
DOMVisitor visitor = new DOMVisitor();
wrapper.accept(visitor);
如果您想要以多种不同的方式处理一组独特且相对静态的“数据类型”,则访问者模式通常很有用。
答案 5 :(得分:1)
这个级别的抽象似乎很难。你如何处理作为正文返回的JSONObject或DOM?通常更容易更进一步。是否可以将两者转换为相同的Java结构?根据内容类型,创建正文解析器的JSOn或DOM实现,并在正文中使用的代码中使用由解析器创建的结果java结构。如果需要(创建正确的答案格式),您可以从答案中获取原始内容类型(getMimeType()或类似的内容)。