RESTEasy入门

  • 博客分类:
  • RESTEasy
mavenWebServiceJBossServletWeb 

RESTEasy是JBoss的开源项目之一,是一个RESTful Web Services框架。RESTEasy的开发者Bill Burke同时也是JAX-RS的J2EE标准制定者之一。JAX-RS是一个JCP制订的新标准,用于规范基于HTTP的RESTful Web Services的API。

我们已经有SOAP了,为什么需要Restful WebServices?用Bill自己的话来说:"如果是为了构建SOA应用,从技术选型的角度来讲,我相信REST比SOAP更具优势。开发人员会意识到使用传统方式有进行SOA架构有多复杂,更不用提使用这些做出来的接口了。这时他们就会发现Restful Web Services的光明之处。"

说了这么多,我们使用RESTEasy做一个项目玩玩看。首先创造一个maven1的web项目

Java代码  
  1. mvn archetype:create -DgroupId=org.bluedash \
  2. -DartifactId=try-resteasy -DarchetypeArtifactId=maven-archetype-webapp
mvn archetype:create -DgroupId=org.bluedash \  -DartifactId=try-resteasy -DarchetypeArtifactId=maven-archetype-webapp

准备工作完成后,我们就可以开始写代码了,假设我们要撰写一个处理客户信息的Web Service,它包含两个功能:一是添加用户信息;二是通过用户Id,获取某个用户的信息,而交互的方式是标准的WebService形式,数据交换格式为XML。假设一条用户包含两个属性:Id和用户名。那么我们设计交换的XML数据如下:

Java代码  
  1. <user>
  2. <id>1</id>
  3. <name>liweinan</name>
  4. </user>
<user><id>1</id><name>liweinan</name>
</user>

首先要做的就是把上述格式转换成XSD2,网上有在线工具可以帮助我们完成这一工作3,在此不详细展开。使用工具转换后,生成如下xsd文件:

Java代码  
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
  3. version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  4. <xsd:element name="user" type="userType" />
  5. <xsd:complexType name="userType">
  6. <xsd:sequence>
  7. <xsd:element name="id" type="xsd:int" />
  8. <xsd:element name="name" type="xsd:string" />
  9. </xsd:sequence>
  10. </xsd:complexType>
  11. </xsd:schema>
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><xsd:element name="user" type="userType" /><xsd:complexType name="userType"><xsd:sequence><xsd:element name="id" type="xsd:int" /><xsd:element name="name" type="xsd:string" /></xsd:sequence></xsd:complexType>
</xsd:schema>

有了xsd文件,我们便可以使用JDK自带工具的xjc将xsd转换成为Java的Class。将上述xsd文件存为 user.xsd,并使用如下命令进行转换:

Java代码  
  1. xjc user.xsd
xjc user.xsd

执行结束后我们会得到一系列的类文件:

Java代码  
  1. Li-Weinans-MacBook-Pro:Desktop liweinan$ xjc user.xsd
  2. parsing a schema...
  3. compiling a schema...
  4. generated/ObjectFactory.java
  5. generated/UserType.java
Li-Weinans-MacBook-Pro:Desktop liweinan$ xjc user.xsd
parsing a schema...
compiling a schema...
generated/ObjectFactory.java
generated/UserType.java

这样,我们的XML格式的交换数据便转化为面向对像的Java类了,是不是感觉有点像Hibernate的ORM理念?没错,将XML映射成成面向对象的数据类,这个过程叫做XML Binding,即XML绑定。这个过程也有J2EE标准,叫做JAXB4。而RESTEasy是全面支持JAXB的。可以说RESTEasy所支持的JAX-RS标准,当与JAXB标准结合在一起使用时,就可以发挥出最大优势,让程序员少写一堆一堆的代码。有关JAXB标准,会在 独立的篇章中 详细讨论,在此先不展开。总之我们将生成的Java类放进项目中等候使用。我们可以看一下UserType类的内容:

Java代码  
  1. package org.bluedash.resteasy;
  2. import javax.xml.bind.annotation.XmlAccessType;
  3. import javax.xml.bind.annotation.XmlAccessorType;
  4. import javax.xml.bind.annotation.XmlElement;
  5. import javax.xml.bind.annotation.XmlType;
  6. @XmlAccessorType(XmlAccessType.FIELD)
  7. @XmlType(name = "userType", propOrder = {
  8. "id",
  9. "name"
  10. })
  11. public class UserType {
  12. protected int id;
  13. @XmlElement(required = true)
  14. protected String name;
  15. /**
  16. * Gets the value of the id property.
  17. *
  18. */
  19. public int getId() {
  20. return id;
  21. }
  22. /**
  23. * Sets the value of the id property.
  24. *
  25. */
  26. public void setId(int value) {
  27. this.id = value;
  28. }
  29. /**
  30. * Gets the value of the name property.
  31. *
  32. * @return
  33. *     possible object is
  34. *     {@link String }
  35. *
  36. */
  37. public String getName() {
  38. return name;
  39. }
  40. /**
  41. * Sets the value of the name property.
  42. *
  43. * @param value
  44. *     allowed object is
  45. *     {@link String }
  46. *
  47. */
  48. public void setName(String value) {
  49. this.name = value;
  50. }
  51. }
package org.bluedash.resteasy;import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "userType", propOrder = {"id","name"
})
public class UserType {protected int id;@XmlElement(required = true)protected String name;/*** Gets the value of the id property.* */public int getId() {return id;}/*** Sets the value of the id property.* */public void setId(int value) {this.id = value;}/*** Gets the value of the name property.* * @return*     possible object is*     {@link String }*     */public String getName() {return name;}/*** Sets the value of the name property.* * @param value*     allowed object is*     {@link String }*     */public void setName(String value) {this.name = value;}}

可以看到,XML格式就是通过一些JAXB的标记被映射成了Java类。我们没写什么代码,已经把数据模型定义清楚了。接下来我们撰写最核心的WebService API。我们的WebService包含两个接口:一个是添加用户接口createUser,另一个是获取用户接口getUser:

Java代码  
  1. package org.bluedash.resteasy;
  2. import java.net.URI;
  3. import java.util.Map;
  4. import java.util.concurrent.ConcurrentHashMap;
  5. import java.util.concurrent.atomic.AtomicInteger;
  6. import javax.ws.rs.Consumes;
  7. import javax.ws.rs.GET;
  8. import javax.ws.rs.POST;
  9. import javax.ws.rs.Path;
  10. import javax.ws.rs.PathParam;
  11. import javax.ws.rs.Produces;
  12. import javax.ws.rs.WebApplicationException;
  13. import javax.ws.rs.core.Response;
  14. @Path("/users")
  15. public class UserServlet {
  16. private Map<Integer, UserType> userStore =
  17. new ConcurrentHashMap<Integer, UserType>();
  18. private AtomicInteger idGenerator = new AtomicInteger();
  19. @POST
  20. @Consumes("application/xml")
  21. public Response createUser(UserType user) {
  22. user.setId(idGenerator.incrementAndGet());
  23. userStore.put(user.getId(), user);
  24. System.out.println(user.getName() + " created: "
  25. + user.getId());
  26. return Response.created(URI.create("/users/"
  27. + user.getId())).build();
  28. }
  29. @GET
  30. @Path("{id}")
  31. @Produces("application/xml")
  32. public UserType getUser(@PathParam("id") int id) {
  33. UserType u = userStore.get(id);
  34. if (u == null) {
  35. throw new WebApplicationException(
  36. Response.Status.NOT_FOUND);
  37. }
  38. return u;
  39. }
  40. }
package org.bluedash.resteasy;import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;@Path("/users")
public class UserServlet {private Map<Integer, UserType> userStore = new ConcurrentHashMap<Integer, UserType>();private AtomicInteger idGenerator = new AtomicInteger();@POST@Consumes("application/xml")public Response createUser(UserType user) {user.setId(idGenerator.incrementAndGet());userStore.put(user.getId(), user);System.out.println(user.getName() + " created: " + user.getId());return Response.created(URI.create("/users/" + user.getId())).build();}@GET@Path("{id}")@Produces("application/xml")public UserType getUser(@PathParam("id") int id) {UserType u = userStore.get(id);if (u == null) {throw new WebApplicationException(Response.Status.NOT_FOUND);}return u;}}

用几个简单的JAX-RS标记,便把普通的函数变成了WebService接口。而这些标记将由RESTEasy支持生效。接下来我们将要进行RESTEasy的配置工作。RESTEasy的配置方法有多种多样,可以和Spring等容器集成,也可以独立运行,因为我们用的Servlet的形式使RESTEasy进行工作,这也是最主流的方式,因此在这里使用web容器来加载它,首先定义一个配置类:

Java代码  
  1. package org.bluedash.resteasy;
  2. import java.util.HashSet;
  3. import java.util.Set;
  4. import javax.ws.rs.core.Application;
  5. public class BluedashResteasyApplication extends Application {
  6. private Set<Object> singletons = new HashSet<Object>();
  7. private Set<Class<?>> classes = new HashSet<Class<?>>();
  8. public BluedashResteasyApplication() {
  9. //      classes.add(UserServlet.class);
  10. singletons.add(new UserServlet());
  11. }
  12. @Override
  13. public Set<Class<?>> getClasses() {
  14. return classes;
  15. }
  16. @Override
  17. public Set<Object> getSingletons() {
  18. return singletons;
  19. }
  20. }
package org.bluedash.resteasy;import java.util.HashSet;
import java.util.Set;import javax.ws.rs.core.Application;public class BluedashResteasyApplication extends Application {private Set<Object> singletons = new HashSet<Object>();private Set<Class<?>> classes = new HashSet<Class<?>>();public BluedashResteasyApplication() {
//      classes.add(UserServlet.class);singletons.add(new UserServlet());}@Overridepublic Set<Class<?>> getClasses() {return classes;}@Overridepublic Set<Object> getSingletons() {return singletons;}
}

这个类扩展JAX-RS的Application接口,用于封装我们的WebService API方法。我们可以看到JAX-RS支持两种封装方法,一种是classes封装,由容器管理WebServices类的实例化和销毁等动作,一个线程一个实例,开发者不需要关心线程安全问题。但这种方法可能比较浪费资源。如果开发者想自己管理线程安全,共线程共用一个WebServices实例,那么就用singletons封装。我们在这里用的singletons封装,这也就解释了为什么我们在 UserServlet中使用了ConcurrentHashMap和AtomicInteger这些保障线程安全的类。接下来就是在web.xml中启动RESTEasy:

Java代码  
  1. <!DOCTYPE web-app PUBLIC
  2. "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  3. "http://java.sun.com/dtd/web-app_2_3.dtd" >
  4. <web-app>
  5. <display-name>Archetype Created Web Application</display-name>
  6. <context-param>
  7. <param-name>javax.ws.rs.core.Application</param-name>
  8. <param-value>org.bluedash.resteasy.
  9. BluedashResteasyApplication</param-value>
  10. </context-param>
  11. <listener>
  12. <listener-class>org.jboss.resteasy.plugins.server.
  13. servlet.ResteasyBootstrap</listener-class>
  14. </listener>
  15. <servlet>
  16. <servlet-name>Resteasy</servlet-name>
  17. <servlet-class>org.jboss.resteasy.plugins.server.servlet.
  18. HttpServletDispatcher</servlet-class>
  19. </servlet>
  20. <servlet-mapping>
  21. <servlet-name>Resteasy</servlet-name>
  22. <url-pattern>/*</url-pattern>
  23. </servlet-mapping>
  24. </web-app>
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><context-param><param-name>javax.ws.rs.core.Application</param-name><param-value>org.bluedash.resteasy.BluedashResteasyApplication</param-value></context-param><listener><listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class></listener><servlet><servlet-name>Resteasy</servlet-name><servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class></servlet><servlet-mapping><servlet-name>Resteasy</servlet-name><url-pattern>/*</url-pattern></servlet-mapping>
</web-app>

没错,就是这么简单,这样,我们的WebService就完成了!还差点什么呢?嗯,还差一个Test Case来使用我们的WebService接口,并验证它的正确性,让我们来写一个TestUserAPI

Java代码  
  1. package org.bluedash.resteasy.test.integration.test;
  2. import java.io.IOException;
  3. import java.io.OutputStream;
  4. import java.net.HttpURLConnection;
  5. import java.net.URL;
  6. import junit.framework.TestCase;
  7. public class TestUserAPI extends TestCase {
  8. public static final String USER_API =
  9. "http://127.0.0.1:8080/try-resteasy/users";
  10. public void testCreateUserAndGetUser() throws IOException {
  11. URL url =
  12. new URL(USER_API);
  13. HttpURLConnection connection =
  14. (HttpURLConnection) url.openConnection();
  15. connection.setRequestMethod("POST");
  16. connection.setRequestProperty("Content-Type", "application/xml");
  17. connection.setDoOutput(true);
  18. connection.setInstanceFollowRedirects(false);
  19. connection.setConnectTimeout(1000);
  20. String userXML = "<user><name>liweinan</name></user>";
  21. OutputStream os = connection.getOutputStream();
  22. os.write(userXML.getBytes());
  23. os.flush();
  24. assertEquals(HttpURLConnection.HTTP_CREATED, connection
  25. .getResponseCode());
  26. connection.disconnect();
  27. }
  28. }
package org.bluedash.resteasy.test.integration.test;import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;import junit.framework.TestCase;public class TestUserAPI extends TestCase {public static final String USER_API = "http://127.0.0.1:8080/try-resteasy/users";public void testCreateUserAndGetUser() throws IOException {URL url = new URL(USER_API);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("POST");connection.setRequestProperty("Content-Type", "application/xml");connection.setDoOutput(true);connection.setInstanceFollowRedirects(false);connection.setConnectTimeout(1000);String userXML = "<user><name>liweinan</name></user>";OutputStream os = connection.getOutputStream();os.write(userXML.getBytes());os.flush();assertEquals(HttpURLConnection.HTTP_CREATED, connection.getResponseCode());        connection.disconnect();}
}

一切都已经准备就绪,最后我们要配置一下Maven,让它下载所需的RESTEasy等库,然后配置Maven使用Jetty Web服务器,来把我们的服务和测试跑起来:

Java代码  
  1. <project xmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/maven-v4_0_0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>org.bluedash</groupId>
  7. <artifactId>try-resteasy</artifactId>
  8. <packaging>war</packaging>
  9. <version>1.0-SNAPSHOT</version>
  10. <name>try-resteasy Maven Webapp</name>
  11. <url>http://maven.apache.org</url>
  12. <repositories>
  13. <repository>
  14. <id>JBossMavenRepo</id>
  15. <name>JBoss Maven2 repo</name>
  16. <url>http://repository.jboss.org/maven2</url>
  17. <releases>
  18. <enabled>true</enabled>
  19. </releases>
  20. <snapshots>
  21. <enabled>false</enabled>
  22. </snapshots>
  23. </repository>
  24. </repositories>
  25. <dependencies>
  26. <dependency>
  27. <groupId>junit</groupId>
  28. <artifactId>junit</artifactId>
  29. <version>4.4</version>
  30. <scope>test</scope>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.jboss.resteasy</groupId>
  34. <artifactId>resteasy-jaxrs</artifactId>
  35. <version>1.2.RC1</version>
  36. </dependency>
  37. <dependency>
  38. <groupId>org.jboss.resteasy</groupId>
  39. <artifactId>resteasy-jaxb-provider</artifactId>
  40. <version>1.2.RC1</version>
  41. </dependency>
  42. <dependency>
  43. <groupId>javax.servlet</groupId>
  44. <artifactId>servlet-api</artifactId>
  45. <version>2.4</version>
  46. </dependency>
  47. </dependencies>
  48. <build>
  49. <finalName>try-resteasy</finalName>
  50. <plugins>
  51. <plugin>
  52. <groupId>org.apache.maven.plugins</groupId>
  53. <artifactId>maven-compiler-plugin</artifactId>
  54. <configuration>
  55. <source>1.6</source>
  56. <target>1.6</target>
  57. <encoding>UTF-8</encoding>
  58. </configuration>
  59. </plugin>
  60. <plugin>
  61. <groupId>org.apache.maven.plugins</groupId>
  62. <artifactId>maven-surefire-plugin</artifactId>
  63. <configuration>
  64. <excludes>
  65. <exclude>**/integration/**</exclude>
  66. </excludes>
  67. </configuration>
  68. <executions>
  69. <execution>
  70. <id>integration-tests</id>
  71. <phase>integration-test</phase>
  72. <goals>
  73. <goal>test</goal>
  74. </goals>
  75. <configuration>
  76. <skip>false</skip>
  77. <excludes>
  78. <exclude>none</exclude>
  79. </excludes>
  80. <includes>
  81. <include>**/integration/**</include>
  82. </includes>
  83. </configuration>
  84. </execution>
  85. </executions>
  86. </plugin>
  87. <plugin>
  88. <groupId>org.mortbay.jetty</groupId>
  89. <artifactId>maven-jetty-plugin</artifactId>
  90. <version>6.1.15</version>
  91. <configuration>
  92. <scanIntervalSeconds>5</scanIntervalSeconds>
  93. <stopKey>foo</stopKey>
  94. <stopPort>9999</stopPort>
  95. </configuration>
  96. <executions>
  97. <execution>
  98. <id>start-jetty</id>
  99. <phase>pre-integration-test</phase>
  100. <goals>
  101. <goal>run</goal>
  102. </goals>
  103. <configuration>
  104. <scanIntervalSeconds>5</scanIntervalSeconds>
  105. <daemon>true</daemon>
  106. </configuration>
  107. </execution>
  108. <execution>
  109. <id>stop-jetty</id>
  110. <phase>post-integration-test</phase>
  111. <goals>
  112. <goal>stop</goal>
  113. </goals>
  114. </execution>
  115. </executions>
  116. </plugin>
  117. </plugins>
  118. </build>
  119. </project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.bluedash</groupId><artifactId>try-resteasy</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>try-resteasy Maven Webapp</name><url>http://maven.apache.org</url><repositories><repository><id>JBossMavenRepo</id><name>JBoss Maven2 repo</name><url>http://repository.jboss.org/maven2</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository></repositories><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.4</version><scope>test</scope></dependency><dependency><groupId>org.jboss.resteasy</groupId><artifactId>resteasy-jaxrs</artifactId><version>1.2.RC1</version></dependency><dependency><groupId>org.jboss.resteasy</groupId><artifactId>resteasy-jaxb-provider</artifactId><version>1.2.RC1</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.4</version></dependency></dependencies><build><finalName>try-resteasy</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.6</source><target>1.6</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><excludes><exclude>**/integration/**</exclude></excludes></configuration><executions><execution><id>integration-tests</id><phase>integration-test</phase><goals><goal>test</goal></goals><configuration><skip>false</skip><excludes><exclude>none</exclude></excludes><includes><include>**/integration/**</include></includes></configuration></execution></executions></plugin><plugin><groupId>org.mortbay.jetty</groupId><artifactId>maven-jetty-plugin</artifactId><version>6.1.15</version><configuration><scanIntervalSeconds>5</scanIntervalSeconds><stopKey>foo</stopKey><stopPort>9999</stopPort></configuration><executions><execution><id>start-jetty</id><phase>pre-integration-test</phase><goals><goal>run</goal></goals><configuration><scanIntervalSeconds>5</scanIntervalSeconds><daemon>true</daemon></configuration></execution><execution><id>stop-jetty</id><phase>post-integration-test</phase><goals><goal>stop</goal></goals></execution></executions></plugin></plugins></build>
</project>

有关Maven的配置就不详细展开了。配置完成后我们便可以运行单元测试,看看WebServices是否正确运行。执行下述命令

Java代码  
  1. mvn integration-test
mvn integration-test

执行结果如下:

Java代码  
  1. -------------------------------------------------------
  2. T E S T S
  3. -------------------------------------------------------
  4. Running org.bluedash.resteasy.test.integration.test.TestUserAPI
  5. liweinan created: 1
  6. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.372 sec
  7. Results :
  8. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
-------------------------------------------------------T E S T S
-------------------------------------------------------
Running org.bluedash.resteasy.test.integration.test.TestUserAPI
liweinan created: 1
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.372 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

可以看到,我们的测试按预期执行成功了。这篇文章中,我简单向大家介绍了RESTEasy的初步使用方法,希望对大家在架构SOA应用时,有所帮助。JAX-RS标准做为J2EE家庭中相对较新的一员,其应用前景是十分广阔的。

RESTEasy入门相关推荐

  1. RestEasy的入门与使用

    文章目录 RestEasy的入门与使用 背景 传统Servlet JAX-RS和JSR 为什么要看规范? 简单解读JSR370 Applications Resources Providers Res ...

  2. 计算机科学精彩帖子收集--JAVA和分布式专栏

    之前收集了一个计算机科学精彩帖子收集,渐渐发现帖子越来越大,所以现在干脆把Java和分布式的部分单独一贴. Java jdk下载 http://openjdk.java.net/projects/jd ...

  3. quarkus_Quarkus入门

    quarkus Quarkus – 一个针对OpenJDK HotSpot和GraalVM量身定制的Kubernetes本机Java堆栈,它是从最佳Java库和标准中精制而成的. –是一个容器优先的框 ...

  4. Java 云原生微服务框架 Quarkus 入门实践

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  5. 带有RESTEasy + JAXB + Jettison的JSON示例

    RESTEasy使用Jettison JSON库在JSON之间来回映射JAXB注释对象. 在本教程中,我们向您展示如何将带​​有JAXB注释的对象转换为JSON格式并将其返回给客户端. 杰克逊(Jac ...

  6. 用Construct 2制作入门小游戏~

    今天在软导课上了解到了Construct 2这个神器,本零基础菜鸟决定尝试做一个简单的小游戏(实际上是入门的教程啊= = 首先呢,肯定是到官网下载软件啊,点击我下载~ 等安装完毕后我便按照新手教程开始 ...

  7. Docker入门六部曲——Swarm

    原文链接:http://www.dubby.cn/detail.html?id=8738 准备工作 安装Docker(版本最低1.13). 安装好Docker Compose,上一篇文章介绍过的. 安 ...

  8. Docker入门六部曲——Stack

    原文链接:http://www.dubby.cn/detail.html?id=8739 准备知识 安装Docker(版本最低1.13). 阅读完Docker入门六部曲--Swarm,并且完成其中介绍 ...

  9. Docker入门六部曲——服务

    原文链接:http://www.dubby.cn/detail.html?id=8735 准备 已经安装好Docker 1.13或者以上的版本. 安装好Docker Compose.如果你是用的是Do ...

最新文章

  1. 中国新冠研究登上Science封面,全球首次揭示新冠病毒人体蛋白受体结构
  2. 对比MySQL表数据内容方式汇总
  3. Android--表格布局
  4. 如何自学python a byte to python-你是如何自学 Python 的?
  5. dev机上数据库中批量生成table
  6. 常见的 OOM 原因及其解决方法(OutOfMemoryError)
  7. linux命令看文件内容,Linux文件内容查看相关命令
  8. 转载------------java equals 方法
  9. python antlr_使用ANTLR在5分钟内用Java解析任何语言:例如Python
  10. 比开源快30倍的自研SQL Parser设计与实践
  11. 蓝桥杯 PREV-37 历届试题 分巧克力
  12. 快速排序C++方法(3种)
  13. PMP课程笔记:第6章 项目进度管理
  14. 最详细的 paypal 支付接口开发--Java版
  15. 【信号处理】单通道盲源分离(SSA-ICA)算法
  16. MATLAB APP设计工具
  17. Python 一维数据
  18. Java多线程面经整理
  19. OpenCV-Python之画椭圆
  20. 教你快速去除照片上的水印?操作简单,小白一学就会!

热门文章

  1. elk笔记13--Queries-geo queries
  2. 分析kdump(vmcore)
  3. LXC、docker
  4. 一文了解摩根大通的金融区块链平台:Quorum
  5. python集合(set)
  6. UNION ALL的使用
  7. 富文本编辑器和fastdfs的使用
  8. PHPCMS 模板修改
  9. 因为年轻被骗了,难受啊马飞
  10. 你愿意花几百块钱去拍最美证件照么?证件照省钱攻略 看过来