Java 为Web服务的请求和响应对象建模的设计模式
我有大约7个RESTWeb服务要实现。这些web服务中的一些具有标准(相同)响应,而另一些具有不同的响应 对这些web服务的请求是不同的,但是一些请求和一些响应具有相同的底层数据对象 我不确定是否必须为每个web服务构建单独的请求/响应类或重用标准类。我想知道是否有一种设计模式来为这些web服务的请求对象和响应对象建模 好的,假设Account和Book是我的web服务将要处理的两个rest资源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
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内容映射到作为参数接收的特定类
- 对于响应,有两种方法:
- 您可以创建一个自定义的
类,它将成为您的真实响应。这将包含响应代码、描述和一个名为value的字段,在成功处理输入数据的情况下,该字段存储响应的真实内容。该类将如下所示:ResponseWrapper
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." }
将以JSON格式存储具体响应。例如:String value
@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." }
- 您可以创建一个自定义的
标准的方式,你可以考虑的是。因为它允许您将命令请求封装为对象。因此,您可以使用不同的请求、队列或日志请求、响应和支持可撤销操作等参数化客户端
作为示例实现: 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[]>) { ... }
公共最终响应重新平衡帐户(请求){…}
在我看来;将各个实体与请求和响应分离,可以生成更整洁的域和对象图
下面是这样一个通用响应对象的示例。就我而言;我已经构建了服务器,以便对所有请求都有一个通用的响应,以增强错误处理并降低域对象和响应对象之间的耦合。