Недавно я начал работать над проектом веб-сервиса Restful, используя Jersey API . В Интернете есть несколько учебных пособий, но я столкнулся с некоторыми проблемами при обработке исключений, и я не нашел нигде законченного проекта, использующего JaxB и обеспечивающего подход к обработке исключений. Поэтому, когда мне удалось создать веб-сервис Restful с использованием API-интерфейса Jersey с обработкой исключений и клиентской программой, я решил написать это руководство, чтобы помочь каждому начать работу с Jersey.
Кто должен использовать этот учебник
Это руководство предназначено для Java-программистов, которые заинтересованы в разработке и развертывании Restful Web Services с использованием Jersey API и JaxB.
Предпосылки
Целью данного руководства является использование API-интерфейса Jersey для создания веб-служб Restful и вызова веб-службы с помощью клиентской программы Java и тестирования веб-службы с помощью инструмента. Базовое понимание Java, веб-сервисов, XML, Maven и любого сервера приложений (JBoss / Tomcat) необходимо для легкого понимания учебника.
Программное обеспечение и инструменты, используемые
- JDK версия 1.6.0_37
- Apache Maven 3.0.3
- Mac OS X 10.8.2
- JBoss 4.2.2 (Вы можете использовать любой сервер приложений, например Tomcat, Glassfish и т. Д.)
- Eclipse Indigo (любая Java IDE с поддержкой Maven)
Создание проекта Maven в Eclipse и Джерси
Создайте проект maven в Eclipse, и он предоставит вам базовую структуру проекта. Я дал GroupId как «JD» и artifactID как «my-jersey-project», но вы можете дать все, что захотите. Как только мы завершим разработку нашего проекта, он будет выглядеть как на картинке ниже.
Описание проекта веб-сервиса Джерси
pom.xml : детали конфигурации проекта, обратите внимание на предоставленные зависимости джерси, другие детали являются общими для любого проекта maven.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
<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/xsd/maven-4.0.0.xsd'> <modelVersion>4.0.0</modelVersion> <groupId>JD</groupId> <artifactId>my-jersey-project</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>1.14</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-servlet</artifactId> <version>1.14</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.14</version> </dependency> </dependencies> <build> <finalName>${artifactId}-${version}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.1-alpha-2</version> <configuration> <packagingExcludes> WEB-INF/lib/servlet-api-*.jar </packagingExcludes> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.0</version> <executions> <execution> <id>unpack</id> <phase>install</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>${groupId}</groupId> <artifactId>${artifactId}</artifactId> <version>${version}</version> <type>${packaging}</type> <overWrite>true</overWrite> <outputDirectory>${project.build.directory}/${artifactId}-${version}-exploded.${packaging}</outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> </plugins> </build></project> |
EmpRequest.java : Java Bean для объекта запроса. Здесь важно отметить аннотацию @XmlRootElement для сопоставления класса с элементом XML.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package com.jd.model;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(name = 'empRequest')public class EmpRequest { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }} |
EmpResponse.java : Java-бин для объекта ответа.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package com.jd.model;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(name = 'empResponse')public class EmpResponse { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }} |
ErrorResponse.java : Java Bean, который будет отправлен как ответ в случае исключения.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package com.jd.model;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(name = 'errorResponse')public class ErrorResponse { private String errorCode; private int errorId; public String getErrorCode() { return errorCode; } public void setErrorCode(String errorCode) { this.errorCode = errorCode; } public int getErrorId() { return errorId; } public void setErrorId(int errorId) { this.errorId = errorId; }} |
EmpNotFoundException.java : обычный класс исключений, создаваемый в веб-службе.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
package com.jd.exception;public class EmpNotFoundException extends Exception { private static final long serialVersionUID = 4351720088030656859L; private int errorId; public int getErrorId() { return errorId; } public EmpNotFoundException(String msg, int errorId) { super(msg); this.errorId = errorId; } public EmpNotFoundException(String msg, Throwable cause) { super(msg, cause); }} |
jboss-web.xml : для определения контекста сервлета JBoss для веб-службы.
|
1
2
3
|
<jboss-web> <context-root>jd</context-root></jboss-web> |
web.xml : дескриптор развертывания для веб-службы. Поэтому любой запрос с URI «http: // <HOST>: <POST> / jd / rest / *» будет обрабатываться сервлетом Jersey ServletContainer. Важно отметить, что значение init-param передается для com.sun.jersey.config.property.packages. Это определяет, в каком пакете Джерси будет искать классы веб-сервисов. Это свойство должно указывать на ваши классы ресурсов. Он также ищет классы ресурсов в подпакетах.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?xml version='1.0' encoding='UTF-8'?><web-app id='WebApp_ID' version='2.5' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee <display-name>My Jersey Project</display-name> <!-- Jersey Servlet configurations --> <servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.jd</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <!-- Jersey Servlet configurations --></web-app> |
EmpRouter.java : класс ресурсов, обрабатывающий различные типы запросов.
- @Path («/ emp») — все запросы с URI http: // <HOST>: <PORT> / jd / rest / emp / будут обрабатываться этим классом ресурсов.
- @Path («/ getEmp») — все запросы с URI http: // <HOST>: <PORT> / jd / rest / emp / getEmp будут обрабатываться этим методом.
- @POST — эта аннотация определяет, что используемый метод HTTP должен быть POST. Некоторые другие возможные значения: @GET, @PUT, @DELETE
- @Consumes (MediaType.APPLICATION_XML) — метод принимает элемент XML
- @Produces (MediaType.APPLICATION_XML) — метод возвращает элемент XML
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package com.jd.router;import com.jd.exception.EmpNotFoundException;import com.jd.model.*;import javax.ws.rs.Consumes;import javax.ws.rs.POST;import javax.ws.rs.Path;import javax.ws.rs.Produces;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.Response;import javax.xml.bind.JAXBElement;@Path('/emp')public class EmpRouter { @POST @Path('/getEmp') @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_XML) public Response getEmp(JAXBElement<EmpRequest> empRequest) throws EmpNotFoundException { EmpResponse empResponse = new EmpResponse(); if (empRequest.getValue().getId() == 1) { empResponse.setId(empRequest.getValue().getId()); empResponse.setName(empRequest.getValue().getName()); } else { throw new EmpNotFoundException('Wrong ID', empRequest.getValue() .getId()); } return Response.ok(empResponse).build(); }} |
EmpNotFoundExceptionMapper.java : класс сопоставления исключений, который сопоставляет EmpNotFoundException с объектом Response. Класс должен иметь аннотацию @Provider. Этот класс должен быть в пакете, предусмотренном для классов ресурсов в web.xml. Реализация метода toResponse () генерирует объект ErrorResponse и устанавливает его как объект в объекте ответа со статусом INTERNAL_SERVER_ERROR.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package com.jd.exceptionmapper;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.Response;import javax.ws.rs.ext.ExceptionMapper;import javax.ws.rs.ext.Provider;import com.jd.exception.EmpNotFoundException;import com.jd.model.ErrorResponse;@Providerpublic class EmpNotFoundExceptionMapper implements ExceptionMapper<EmpNotFoundException> { public EmpNotFoundExceptionMapper() { } public Response toResponse( EmpNotFoundException empNotFoundException) { ErrorResponse errorResponse = new ErrorResponse(); errorResponse.setErrorId(empNotFoundException.getErrorId()); errorResponse.setErrorCode(empNotFoundException.getMessage()); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( errorResponse).type( MediaType.APPLICATION_XML).build(); }} |
Наш веб-сервис готов, просто создайте его, чтобы создать файл WAR и развернуть его на сервере приложений.
EmpClient.java : это пример Java-программы, с помощью которой вызывается наш веб-сервис. Мы используем клиентский API-интерфейс jersey для вызова службы и, основываясь на состоянии ответа, анализируем сущность ответа в классе EmpResponse или ErrorResponse.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package com.jd.client;import javax.ws.rs.core.MediaType;import com.jd.model.EmpRequest;import com.jd.model.EmpResponse;import com.jd.model.ErrorResponse;import com.sun.jersey.api.client.Client;import com.sun.jersey.api.client.ClientResponse;import com.sun.jersey.api.client.WebResource;public class EmpClient { /** * @param args */ public static void main(String[] args) { EmpRequest request = new EmpRequest(); //set id as 1 for OK response request.setId(2); request.setName('PK'); try{ Client client = Client.create(); WebResource r=client.resource(uri); ClientResponse response = r.type(MediaType.APPLICATION_XML).post(ClientResponse.class,request ); System.out.println(response.getStatus()); if(response.getStatus() == 200){ EmpResponse empResponse = response.getEntity(EmpResponse.class); System.out.println(empResponse.getId() + '::'+empResponse.getName()); }else{ ErrorResponse exc = response.getEntity(ErrorResponse.class); System.out.println(exc.getErrorCode()); System.out.println(exc.getErrorId()); } }catch(Exception e){ System.out.println(e.getMessage()); } }} |
Я надеюсь, что учебник достаточно прост, чтобы следовать и написать свой первый веб-сервис Restful, используя Джерси.
Пожалуйста, дайте мне знать, если у вас возникнут какие-либо проблемы или вам нужны дальнейшие объяснения.
Ссылка: Отдых с использованием Джерси — полное руководство с JAXB, обработкой исключений и клиентской программой от нашего партнера JCG Панкаджа Кумара в блоге Developer Recipes .
