Java 为Web服务的请求和响应对象建模的设计模式

Java 为Web服务的请求和响应对象建模的设计模式,java,web-services,rest,design-patterns,jax-rs,Java,Web Services,Rest,Design Patterns,Jax Rs,我有大约7个RESTWeb服务要实现。这些web服务中的一些具有标准(相同)响应,而另一些具有不同的响应 对这些web服务的请求是不同的,但是一些请求和一些响应具有相同的底层数据对象 我不确定是否必须为每个web服务构建单独的请求/响应类或重用标准类。我想知道是否有一种设计模式来为这些web服务的请求对象和响应对象建模 好的,假设Account和Book是我的web服务将要处理的两个rest资源 class Account { String username; String id

我有大约7个RESTWeb服务要实现。这些web服务中的一些具有标准(相同)响应,而另一些具有不同的响应

对这些web服务的请求是不同的,但是一些请求和一些响应具有相同的底层数据对象

我不确定是否必须为每个web服务构建单独的请求/响应类或重用标准类。我想知道是否有一种设计模式来为这些web服务的请求对象和响应对象建模

好的,假设Account和Book是我的web服务将要处理的两个rest资源

class Account {
    String username;
    String id;
}


class Book {
    String title;
    String isbn;
}
因此,我的web服务如下所示:

MYAPI/CreateAccountandBook
MYAPI/Account/Create
MYAPI/Book/Create
MYAPI/Book/Update/{isbn}
MYAPI/Account/Update/{id}
MYAPI/Account/getInfo/{id} 
public class ResponseWrapper {
    private int statusCode;
    private String description;
    private String value;
}
{ "error" : "There is no foo in bar." }
等等

现在,
CreateAccountandBook
请求将获取一个account对象和有效负载中的书籍列表。 另外,
MYAPI/Account/getInfo/{id}
的响应对象有一个Account对象和一个与该帐户关联的书籍列表。但是响应对象还包括
statusCode
Description

现在我想为这些请求和响应对象创建类 以最好的方式

好吧,开始吧

我有两个抽象类
StandardRequest
StandardResponse

所有请求类都将扩展标准请求类并进行相应的自定义。 所有响应类都将扩展标准响应类并进行相应的自定义

但是这些请求和响应可能彼此不同,但仍然可以重用相同的实体对象

例如:

createAccountandBook
请求对象如下所示:

class CreateAccountAndBookRequest {
   Account account;
   List<Book> books;
}

因此,请求和响应类之间存在重叠。我可以为每个web服务创建两个(req/res)类。但想知道是否有更好的方法来建模这些类。

< p>您可以尝试六方架构,它包括将业务逻辑放在中间,并通过REST、SOAP、SMTP等来访问它。 在Rest文件中,您只需要公开路径并调用一个类,其中包含所有需要执行的操作,如DAO或其他操作

如果服务引用相同的内容,您可以在单个类中离开,也可以根据服务的建议分开离开

对于您的问题,您可以使用所需的简单数据(如帐号、账簿、说明)创建DTO(数据传输对象),并且您可以覆盖toString()以提供正确的响应或在json响应中转换数据

你可以检查一下,我认为这是最好的实践{
 public ResponseDto(){
     String username;
     int id;
     ArrayList books <Book> = new ArrayList<Book>();

    // proper getters and setters...
    @Override
    public String toString(){
       //parse this object to return a proper response to the rest service,
       //you can parse using some JSON library like GSON
    }
}
字符串用户名; int-id; ArrayList books=新建ArrayList(); //合适的接受者和接受者。。。 @凌驾 公共字符串toString(){ //解析此对象以向rest服务返回正确的响应, //您可以使用诸如GSON之类的JSON库进行解析 } }
我不知道是否有这样的设计模式。我做了以下工作:

  • 对于GET请求,在查询字符串或路径中定义参数。首选的方式是路径。此外,您的服务也没有多少参数。每个服务将自行处理此问题。这里没有可重用性
  • 对于POST请求,使用请求体中JSON格式的参数。另外,使用适配器(取决于您使用的技术),将JSON内容映射到作为参数接收的特定类
  • 对于响应,有两种方法:

    • 您可以创建一个自定义的
      ResponseWrapper
      类,它将成为您的真实响应。这将包含响应代码、描述和一个名为value的字段,在成功处理输入数据的情况下,该字段存储响应的真实内容。该类将如下所示:

      MYAPI/CreateAccountandBook
      MYAPI/Account/Create
      MYAPI/Book/Create
      MYAPI/Book/Update/{isbn}
      MYAPI/Account/Update/{id}
      MYAPI/Account/getInfo/{id} 
      
      public class ResponseWrapper {
          private int statusCode;
          private String description;
          private String value;
      }
      
      { "error" : "There is no foo in bar." }
      
      在这种情况下,
      String value
      将以JSON格式存储具体响应。例如:

      @Path("/yourapi/book")
      public class BookRestfulService {
      
          @POST("/create")
          @Produces("json")
          public ResponseWrapper createBook(Book book) {
              ResponseWrapper rw = new ResponseWrapper();
              //do the processing...
              BookService bookService = new BookService();
              SomeClassToStoreResult result = bookService.create(book);
              //define the response...
              rw.setStatusCode(...);
              rw.setDescription("...");
              rw.setValue( convertToJson(result) );
          }
      
          static String convertToJson(Object object) {
              //method that probably will use a library like Jackson or Gson
              //to convert the object into a proper JSON strong
          }
      }
      
    • 重用,使用200(或201,这取决于请求的类型)表示成功的请求,并为响应使用正确的状态代码。如果响应的状态代码为200(或201),则以JSON格式返回适当的对象。如果您的响应具有不同的状态代码,请提供如下JSON对象:

      MYAPI/CreateAccountandBook
      MYAPI/Account/Create
      MYAPI/Book/Create
      MYAPI/Book/Update/{isbn}
      MYAPI/Account/Update/{id}
      MYAPI/Account/getInfo/{id} 
      
      public class ResponseWrapper {
          private int statusCode;
          private String description;
          private String value;
      }
      
      { "error" : "There is no foo in bar." }
      
将RESTful服务与JSON或XML结合使用是一种折衷,这是消费者复杂性的代价,他们可能不知道响应的结构。在WS-*web服务的情况下,折衷是性能方面(与RESTful方法相比)。

关于

如果有一个设计模式来为请求对象和响应对象建模

标准的方式,你可以考虑的是。因为它允许您将命令请求封装为对象。因此,您可以使用不同的请求、队列或日志请求、响应和支持可撤销操作等参数化客户端

作为示例实现:

  abstract class Request{
    public abstract void Execute();
    public abstract void UnExecute();
  } 

   class AccountAndBookRequest extends Request{
   Account account;
   List<Book> books;
   }
抽象类请求{
公共抽象void Execute();
公开摘要无效未执行();
} 
类AccountAndBookRequest扩展了请求{
账户;
列出书籍;
}

我也遇到了类似的困境;我选择了通用方向,我喜欢结果;从那以后就再也没有回头看

如果我有一个
GetAccounts
API方法,那么签名可能会是这样的

public final Response<Account[]> getAccounts()
public final Response getAccounts()
当然,同样的原则也适用于请求

public final Response<Account[]> rebalanceAccounts(Request<Account[]>) { ... }
公共最终响应重新平衡帐户(请求){…}
在我看来;将各个实体与请求和响应分离,可以生成更整洁的域和对象图

下面是这样一个通用响应对象的示例。就我而言;我已经构建了服务器,以便对所有请求都有一个通用的响应,以增强错误处理并降低域对象和响应对象之间的耦合。