рдкрд░рд┐рдЪрдп
рдпрд╣ рдПрдкреАрдЖрдИ
JSR 311: JAX-RS: рдж рд░реИрд╕реНрдЯрдлреБрд▓ рд╡реЗрдм рд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛ рдПрдкреАрдЖрдИ рдФрд░ рдЬрд╛рд╡рд╛ рдИрдИ 6 (рдЬрд╛рд╡рд╛ рдИрдИ 5 рдореЗрдВ рдпреЛрдЬрдирд╛рдмрджреНрдз) рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдерд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдирд╛рдо рд╕реЗ рд╣реА рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдЗрд╕реЗ рд░реЗрд╕реНрдЯрдлреБрд▓ рд╡реЗрдм рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп рдкрд╛рдардХ рдХреЛ JAX-RS API рдХреА рдореВрд▓ рдмрд╛рддреЛрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдХрд░рд╛рдирд╛ рд╣реИред рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдореИрдВрдиреЗ JAX-RS рд╕реЗрд╡рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░реВрдкреЛрдВ рдХреЗ рдХрд╛рдо рдХреЗ рд╕рд╛рде рдХреБрдЫ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИред рдЗрд╕ рддрдХрдиреАрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ Habr├й рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд▓рдЧрднрдЧ рдХреБрдЫ рднреА рдирд╣реАрдВ рдорд┐рд▓рд╛, рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдореИрдВ рд▓реЗрдЦ рдХреЗ рдкрд░рд┐рдЪрдп рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдореЗрдВ рд╕рдлрд▓ рдирд╣реАрдВ рд╣реЛрдКрдВрдЧрд╛ред
JAX-RS рдПрдкреАрдЖрдИ рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ, JBoss рд╕реЗ рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд░реЗрд╕реНрдЯрд╕реА рдврд╛рдВрдЪреЗ рдХреЗ рдЧреНрд░рд╛рд╣рдХ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдкрд░рд┐рдЪрдп рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдпрд╣
javax.ws.rsред * рдореЗрдВ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ
ред рдкрд░реНрдпрд╛рд╡рд░рдг рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдЖрдзреБрдирд┐рдХ AppServers рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ (рдЖрдк
maven рдореЗрдВ
<scope>provided</scope>
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рд░реНрд╡рд▓реЗрдЯ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдХрдИ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВ:
рдпрд╣ рддрдХрдиреАрдХ рдЖрдкрдХреЛ JAX-RS рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рд╡рд┐рд╢реЗрд╖ рд╕рд░реНрд╡рд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдордирдорд╛рдиреЗ рддрд░реАрдХреЗ рд╕реЗ рдирд┐рд░реНрдпрд╛рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ред рдХреНрд▓рд╛рдЗрдВрдЯ рднрд╛рдЧ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЪреБрдиреЗрдВ:
package com.example; import javax.ws.rs.*; @Path("/") public interface RestService { @GET @Path("echo") String echo(@QueryParam("q") String original); }
рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
package com.example; import javax.enterprise.ApplicationScoped; import javax.ws.rs.*; @ApplicationScoped @Path("/") public class Rest implements RestService{ @GET @Path("echo") @Override public String echo(@QueryParam("q") String original) { return original; } }
рдмреАрди рджреЛрдиреЛрдВ рд╣реА рдФрд░ рдЗрд╕рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдЗрд╕рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдкреВрд░рдХ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
@Path
, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рд╕рдВрд╕рд╛рдзрди рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдпрд╛ рдирд┐рд░рдкреЗрдХреНрд╖ рдкрде рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ; рдПрдиреЛрдЯреЗрд╢рди рдЧреНрд░реБрдк
@GET
,
@POST
,
@PUT
,
@DELETE
рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ
HTTP
рдЕрдиреБрд░реЛрдз рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред
рдХреНрд░рдордмрджреНрдзрддрд╛
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдордирдорд╛рдиреЗ рдбреЗрдЯрд╛ рдХреЗ рд╣рд╕реНрддрд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрд░рдорд╛рдВрдХрди рдЖрд╡рд╢реНрдпрдХ рд╣реИ - рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдПрдХ рд╕реЗрдЯ рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╕реЗ рдбреЗрдЯрд╛ рдХрд╛ рдЕрдиреБрд╡рд╛рджред рдореИрдВ рд░реЗрд╕реНрдЯрд╕реА рдкрд░ рдПрдХ рдирдЬрд░ рдХреЗ рд╕рд╛рде рдХрд╣рд╛рдиреА рдЬрд╛рд░реА рд░рдЦреВрдВрдЧрд╛ред
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡рд┐рд╢реЗрд╖ рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрд░рдорд╛рдВрдХрди / рдбрд┐рд╕реЗрд░рд┐рдПрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдо / рдбреЗрдЯрд╛ рд╕рд╛рдордЧреНрд░реА рдХреЗ MIME-рдкреНрд░рдХрд╛рд░ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
@Produces
рдФрд░
@Consumes
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рддрджрдиреБрд╕рд╛рд░, рдбреЗрдЯрд╛ рдХреНрд▓рд╛рд╕ рдХреЛ
JAXB рджреНрд╡рд╛рд░рд╛ рдПрдиреЛрдЯреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред JBoss AS 7 рдореЗрдВ рдорд╛рдирдХ рдкреНрд░рджрд╛рддрд╛ resteasy-jaxb- рдкреНрд░рджрд╛рддрд╛ (xml-marshaller / unmarshaller) рдФрд░ resteasy-jettison-provider (json) рд╣реИрдВред рдпреЗ рджреЛ рдкреНрд░рджрд╛рддрд╛ рдЖрдкрдХреЛ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдПрдХреНрд╕рдПрдордПрд▓ рдФрд░ JSON рдПрдкреАрдЖрдИ рдХреЛ рдмрд╛рд╣рд░ рдХреА рдУрд░ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред
рдХрд╕реНрдЯрдо рдЬрд╡рд╛рдм
рдпрджрд┐ рд╣рдо рдЧреИрд░-рдорд╛рдирдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдпрд╛ HTTP рдХреЛрдб рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? рдПрдиреЛрдЯреЗрдЯ JAX-RS рд╡рд┐рдзрд┐ рд╕реЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде, рдкрд░рд┐рдгрд╛рдо 500 рддреНрд░реБрдЯрд┐ рд╣реЛрдЧрд╛ред рдЕрдиреБрдХреВрд▓рди рдХреЗ рд▓рд┐рдП, рдпрд╣
javax.ws.rs.core.Response
рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ
javax.ws.rs.core.Response
рд▓реМрдЯреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрд╕рд╛рд░ред
@GET @Path("file/get/{name}") Response getFile(@PathParam("file") String fileName) { if(!Files.exists(Paths.get(fileName)) { return Response.status(422).entity("I'm a teapot"); } else { Response.Builder response = Response.ok(); response.header("X-Some-Server-Header", "value"); response.entity(new StreamingOutput() { @Override public void write(OutputStream outputStream) throws IOException, WebApplicationException { Files.copy(Paths.get(fileName), outputStream); } }); return response.build(); } }
рдЧреНрд░рд╛рд╣рдХ рдХреА рд░реВрдкрд░реЗрдЦрд╛
JBoss Resteasy рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджреВрд╕рд░реА рдЕрдЪреНрдЫреА рдмрд╛рдд рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЧреНрд░рд╛рд╣рдХ рдврд╛рдВрдЪреЗ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣реИред рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдп рдЕрдореВрд░реНрддрддрд╛ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╕реНрддрд░реЛрдВ рдкрд░ рд╕рдВрднрд╡ рд╣реИ: рдирд┐рдореНрди-рд╕реНрддрд░ рдХреЗ
ClientRequest
,
ClientResponse<T>
рдФрд░ рдПрдиреЛрдЯреЗрдЯ рдЬреЗрдПрдПрдХреНрд╕-рдЖрд░рдПрд╕ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░реЙрдХреНрд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдкреАрдврд╝реА рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрддред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рд╕реЗ
RestService
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:
RestService service = ProxyFactory.create(RestService.class, "http://localhost:8080/example"); log.info(service.echo("test message"));
рд▓реЗрдХрд┐рди рдХрднреА-рдХрднреА рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЬрдм рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ, рддреЛ рдкреНрд░реЙрдХреНрд╕реА рдЕрдкрд╡рд╛рдж рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред рдХрд╛рдо рдХреЗ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдХреЗ рд▓рд┐рдП,
ClientRequest
/
ClientResponse<T>
рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдкрд╛рдЪреЗ httpcompenders (Resteasy 2.3.x.GA рдореЗрдВ) рдпрд╛ Apache-httpclient (2.2.x.GA рдореЗрдВ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
ClientRequest request = new ClientRequest(url); request.header("X-Additional-Header", "header value");
UPD: рдХреНрд▓рд╛рдЗрдВрдЯ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╢реБрд░реВ рдХрд░рддреЗ рд╕рдордп рдЗрд╕реЗ рдПрдХ рдмрд╛рд░ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрдкрдХреЛ рдордирдорд╛рдирд╛ рдХреНрд╖реЗрддреНрд░, рдПрдХ рдордирдорд╛рдирд╛ рдЕрдиреБрд░реЛрдз рдирд┐рдХрд╛рдп, рдЖрджрд┐ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓реЗрдЦ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдПрдХ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдкрд┐рдд рд╣реЛрдЧрд╛ред
UPD: рдпрд╣рд╛рдВ рдирд┐рд░рдВрддрд░ рджреЗрдЦреЗрдВ