将现有API公开为Web服务

Sub*_*ian 4 api web-services

我目前正致力于将API公开为Web服务.这里的想法是将JAR文件中的现有业务逻辑打包到WAR文件中,并将WAR文件公开为可返回自由格式XML字符串的Web服务.当我们将现有API公开为Web服务时,我们是否可以提供返回的XML字符串数据的XSD和WSDL文件?这是惯例还是标准做法?

jmo*_*253 14

这取决于您是否使用SOAP或REST.SOAP更具限制性; 因此,更期望您将拥有一个WSDL文件来生成与API接口的类.

另一方面,如果您正在使用REST,那么只需暴露RESTful URI即可满足具有统一接口的RESTful Web服务的约束.

REST往往比SOAP更具优势,因为它是一种宽松的架构风格.我更喜欢这种方法,如果您不熟悉开发Web服务,我会推荐这种方法.

根据您使用的语言,我假设使用Java,您可以使用Restlets或Spring 3.0的REST框架来帮助您构建RESTful Web服务.这些工具确实使这项工作变得更加容易,并帮助您符合RESTful Web服务6个约束并满足4个关键目标.

更新:

假设您已经拥有现有的面向对象代码,并假设您希望将该代码公开为REST API,那么使用Spring 3.0 MVC,创建一个将包装现有包的Controller子类:

示例GET:

资源: 杰克逊的ObjectMapper POJO/JSON Marshaller的Javadocs

 // this is the wrapper around your existing Java packages.  
 @Controller
 public class UserController {

     protected static final DATA_TYPE = "json";

     // In REST, GET method is used to retrieve data with no side effects, 
         // meaning that no changes are made to the data on the server.
     @RequestMapping(value="/users/{username}", method=RequestMethod.GET)
     public void getUserData(@PathVariable("username") String userName, Model model) {

         // this is your existing class
         UserDataService userDataService = new UserDataService();

         // assume you have a class User, and getUserDetails gives you that POJO object.
         User user = userDataService.getUserDetails(username);


         // marshal the User object to JSON, using Jackson, and write as output in response
         ObjectMapper mapper = new ObjectMapper();
         mapper.writeValue(response.getWriter(), user);

     }
 }

 // assume you have an existing POJO class called User
 class User implements Serializable {

     String username;
     String age;
     String birthday;
     String mood;

     String getMood() { return this.mood; }
     String getBirthday() { return this.birthday; }
     String getAge() { return this.age; }
     String getUsername() { return this.username; }

     String setMood(String mood) { this.mood = mood; }
     String setBirthday(String birthday) { this.birthday = birthday; }
     String setAge(String age) { this.age = age; }
     String setUsername(String username) { this.username = username; }
}
Run Code Online (Sandbox Code Playgroud)

要求:

http://api.example.com:8080/users/jmort253/
Run Code Online (Sandbox Code Playgroud)

响应:

{ 
    "username":"jmort253",
    "mood":"good",
    "age":"not too old and not too young",
    "birthday","Jan 1, 1900"
}
Run Code Online (Sandbox Code Playgroud)

XML而不是JSON:

返回XML和返回JSON之间的主要区别在于使用的编组器.使用javax.xml.bind.annotations,您可以在POJO类上放置注释,以便编组器可以将其转换为XML,从而使您不必手动编写XML代码的详细信息:

使用javax.xml.bind.annotations将Java对象转换为XML和XSD.如果您认为这是REST Web服务的一项要求,那么该资源还解释了如何生成XML Schema.

 @XmlRootElement
 class User implements Serializable {

     String username;
     String age;
     String birthday;
     String mood;

     String getMood() { return this.mood; }
     String getBirthday() { return this.birthday; }
     String getAge() { return this.age; }
     String getUsername() { return this.username; }

     String setMood(String mood) { this.mood = mood; }
     String setBirthday(String birthday) { this.birthday = birthday; }
     String setAge(String age) { this.age = age; }
     String setUsername(String username) { this.username = username; }
}
Run Code Online (Sandbox Code Playgroud)

不使用Jackson API的ObjectMapper类将POJO类编组为JSON,而是使用javax.xml.bind.annotations包代替ObjectMapper:

JAXBContext context = JAXBContext.newInstance(User.class);
Marshaller marshaller = context.createMarshaller();

// pretty print XML
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
marshaller.marshal(user, System.out);
Run Code Online (Sandbox Code Playgroud)

除了其他资源之外,本文还有一些使用JAXB将POJO对象的ArrayList反序列化为XML的示例.

在处理REST Web服务包装器时,我的最终建议是将您的日志记录级别设置为"ALL"或"DEBUG".我发现这有助于我更轻松地确定设置Web服务时遇到的任何问题的根本原因.这些库本身将输出有用的调试消息,以帮助您解决配置问题,例如缺少依赖项,缺少注释以及在处理转换为XML/JSON过程或设置Spring 3.0时可能遇到的其他问题.

一旦设置了统一接口并且可以发出GET请求并接收响应,就可以将日志记录级别设置回以前的INFO或WARN级别.