खोज…


टिप्पणियों

SOAP और WS- स्टैक के विपरीत, जो W3C मानकों के रूप में निर्दिष्ट हैं, REST वास्तव में वेब-आधारित इंटरफ़ेस को डिज़ाइन करने और उपयोग करने के लिए सिद्धांतों का एक सेट है। REST / RESTful एप्लिकेशन अन्य मानकों पर बहुत अधिक निर्भर करते हैं:

HTTP
URI, URL
XML, JSON, HTML, GIF, JPEG, and so forth (resource representations)

JAX-RS (RESTful Web Services के लिए जावा एपीआई) की भूमिका RESTful सेवाओं के निर्माण में सहायता करने वाले API प्रदान करना है। हालाँकि, JAX-RS ऐसा करने का सिर्फ एक तरीका है । Restful सेवाओं को जावा में अन्य तरीकों से लागू किया जा सकता है, और (वास्तव में) कई अन्य प्रोग्रामिंग भाषाओं में।

सरल संसाधन

JAX-RS एप्लिकेशन के लिए सबसे पहले एक आधार URI निर्धारित किया जाना चाहिए, जहां से सभी संसाधन उपलब्ध होंगे। उस प्रयोजन के लिए javax.ws.rs.core.Application class को javax.ws.rs.ApplicationPath एनोटेशन के साथ विस्तारित और एनोटेट करना होगा। एनोटेशन एक स्ट्रिंग तर्क को स्वीकार करता है जो आधार URI को परिभाषित करता है।

@ApplicationPath(JaxRsActivator.ROOT_PATH)
public class JaxRsActivator extends Application {

    /**
     * JAX-RS root path.
     */
    public static final String ROOT_PATH = "/api";

}

संसाधन सरल POJO वर्ग हैं जो @Path एनोटेशन के साथ एनोटेट किए जाते हैं।

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/hello")
public class HelloWorldResource {
    public static final String MESSAGE = "Hello StackOverflow!";

    @GET
    @Produces("text/plain")
    public String getHello() {
        return MESSAGE;
    }
}

जब एक HTTP GET अनुरोध /hello भेजा जाता है, तो संसाधन एक Hello StackOverflow! साथ प्रतिक्रिया करता है Hello StackOverflow! संदेश।

GET विधि प्रकार

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/hello")
public class HelloWorldResource {
    public static final String MESSAGE = "Hello World!";

    @GET
    @Produces("text/plain")
    public String getHello() {
        return MESSAGE;
    }

    @GET
    @Path("/{letter}")
    @Produces("text/plain")
    public String getHelloLetter(@PathParam("letter") int letter){
        if (letter >= 0 && letter < MESSAGE.length()) {
            return MESSAGE.substring(letter, letter + 1);
        } else {
            return "";
        }
    }
}

बिना पैरामीटर के GET सभी सामग्री ("हैलो वर्ल्ड!") देता है और पथ पैरामीटर के साथ GET उस स्ट्रिंग में से विशिष्ट अक्षर देता है।

कुछ उदाहरण:

$ curl http://localhost/hello
Hello World!
$ curl http://localhost/hello/0
H
$ curl http://localhost/hello/4
o

नोट: यदि आप विधि-प्रकार एनोटेशन (जैसे @GET ऊपर) @GET हैं, तो GET अनुरोध हैंडलर होने के लिए एक अनुरोध विधि चूक जाती है।

DELETE विधि

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;

@Path("hello")
public class HelloWorldResource {

    private String message = "Hello StackOverflow!";

    @GET
    @Produces("text/plain")
    public String getHello() {
        return message;
    }

    @DELETE
    public Response deleteMessage() {
        message = null;
        return Response.noContent().build();
    }
}

इसे कर्ल के साथ सेवन करें:

$ curl http://localhost/hello
Hello StackOverflow!

$ curl -X "DELETE" http://localhost/hello


$ curl http://localhost/hello
null

पोस्ट विधि

import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

@Path("hello")
public class HelloWorldResource {
    @POST
    @Path("/receiveParams")
    public Response receiveHello(@FormParam("name") String name, @FormParam("message") String message) {
        //process parameters
        return Response.status(200).build();
    }

    @POST
    @Path("/saveObject")
    @Consumes("application/json")
    public Response saveMessage(Message message) {
        //process message json
        return Response.status(200).entity("OK").build();
    }
}

पहले तरीके को कैप्चर किए गए इनपुट मापदंडों को भेजकर HTML फॉर्म जमा के माध्यम से लागू किया जा सकता है। फॉर्म जमा करने की कार्रवाई को इंगित करना चाहिए -

/hello/receiveParams

दूसरी विधि के लिए संदेश POJO को गेटर्स / सेटर की आवश्यकता होती है। कोई भी ग्राहक JSON इनपुट के साथ इस विधि को कॉल कर सकता है -

{"sender":"someone","message":"Hello SO!"}

POJO के पास वैसी ही संपत्ति होनी चाहिए जैसे कि क्रमिक कार्य करने के लिए JSON की है।

public class Message {

    String sender;
    String message;

    public String getSender() {
        return sender;
    }
    public void setSender(String sender) {
        this.sender = sender;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

अपवाद मैपर

@Provider
public class IllegalArgumentExceptionMapper implements ExceptionMapper<IllegalArgumentException> {
        
  @Override
  public Response toResponse(IllegalArgumentException exception) {
    return Response.serverError().entity("Invalid input: " + exception.getMessage()).build();
  }
}

यह अपवाद मैपर एप्लिकेशन में फेंके गए सभी IllegalArgumentException को पकड़ लेगा, और उपयोगकर्ता को स्टैट्रेस के बजाय एक स्पष्ट संदेश दिखाएगा।

UriInfo

ताकि आपके संसाधन का उपयोग करने के लिए इस्तेमाल उपयोगकर्ता एजेंट यूआरआई के बारे में जानकारी पाने के लिए, आप उपयोग कर सकते @Context एक साथ पैरामीटर एनोटेशन UriInfo पैरामीटर। UriInfo ऑब्जेक्ट में कुछ विधियाँ हैं जिनका उपयोग URI के विभिन्न भागों को प्राप्त करने के लिए किया जा सकता है।

//server is running on https://localhost:8080,
// webapp is at /webapp, servlet at /webapp/servlet
@Path("class")
class Foo {
    
    @GET
    @Path("resource")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getResource(@Context UriInfo uriInfo) {
        StringBuilder sb = new StringBuilder();
        sb.append("Path: " + uriInfo.getPath() + "\n");
        sb.append("Absolute Path: " + uriInfo.getAbsolutePath() + "\n");
        sb.append("Base URI: " + uriInfo.getBaseUri() + "\n");
        sb.append("Request URI: " + uriInfo.getRequestUri() + "\n");
        return Response.ok(sb.toString()).build();
    }
}

https://localhost:8080/webapp/servlet/class/resource :

Path: class/resource
Absolute Path: https://localhost:8080/webapp/servlet/class/resource#
Base URI: https://localhost:8080/webapp/servlet/
Request URI: https://localhost:8080/webapp/servlet/class/resource

SubResources

कभी-कभी संगठनात्मक या अन्य कारणों से यह समझ में आता है कि आपके शीर्ष स्तर का संसाधन एक उप-संसाधन लौटाता है जो इस तरह दिखेगा। (आपके उप-संसाधन को आंतरिक वर्ग होने की आवश्यकता नहीं है)

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("items")
public class ItemsResource {

    @Path("{id}")
    public String item(@PathParam("id") String id) {
        return new ItemSubResource(id);
    }

    public static class ItemSubResource {

        private final String id;

        public ItemSubResource(String id) {
            this.id = id;
        }
        
        @GET
        @Produces("text/plain")
        public Item item() {
            return "The item " + id;
        }
    }
}

कस्टम पैरामीटर कन्वर्टर्स

यह एक उदाहरण है कि JAX-RS समापन बिंदु के लिए कस्टम पैरामीटर कन्वर्टर्स को कैसे लागू किया जाए। उदाहरण जावा 8 के java.time लाइब्रेरी से दो कक्षाएं java.time है।

@Provider
public class ParamConverters implements ParamConverterProvider {  
  @Override
  public <T> ParamConverter<T> getConverter(Class<T> rawType,
                                            Type genericType,
                                            Annotation[] annotations)
  {
    if (rawType == LocalDate.class)
      return (ParamConverter<T>) new ParamConverter<LocalDate>() {
        @Override
        public LocalDate fromString(String value) {
          return LocalDate.parse(value);
        }

        @Override
        public String toString(LocalDate value) {
          return null;
        }
      };
    else if (rawType == MonthDay.class)
      return (ParamConverter<T>) new ParamConverter<MonthDay>() {
        @Override
        public MonthDay fromString(String value) {
          int[] ddmm = Arrays.stream(value.split("/"))
                             .mapToInt(Integer::parseInt)
                             .toArray();
          return MonthDay.of(ddmm[1], ddmm[0]);
        }

        @Override
        public String toString(MonthDay value) {
          return null;
        }
      };
    return null;
  }
}

नाम बंधन

नाम बाइंडिंग एक अवधारणा है जो JAX-RS रनटाइम से यह कहने की अनुमति देता है कि एक विशिष्ट फ़िल्टर या इंटरसेप्टर को केवल एक विशिष्ट संसाधन विधि के लिए निष्पादित किया जाएगा। जब कोई फ़िल्टर या इंटरसेप्टर केवल एक विशिष्ट संसाधन विधि तक सीमित होता है, तो हम कहते हैं कि यह नाम-बाध्य है । फिल्टर और इंटरसेप्टर जिनके पास ऐसी कोई सीमा नहीं है, उन्हें वैश्विक कहा जाता है।

एक नाम बंधन एनोटेशन को परिभाषित करना

फिल्टर या इंटरसेप्टर को @NameBinding एनोटेशन का उपयोग करके संसाधन विधि को सौंपा जा सकता है। इस एनोटेशन का उपयोग किसी अन्य उपयोगकर्ता द्वारा लागू एनोटेशन के लिए मेटा एनोटेशन के रूप में किया जाता है जो प्रदाताओं और संसाधन विधियों पर लागू होते हैं। निम्नलिखित उदाहरण देखें:

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Compress {}

ऊपर दिया गया उदाहरण एक नया @Compress एनोटेशन को परिभाषित करता है जो एक नाम बाइंडिंग एनोटेशन है क्योंकि यह @NameBinding साथ एनोटेट किया @NameBinding@Compress एनोटेशन का उपयोग फिल्टर और इंटरसेप्टर को एंडपॉइंट्स को बांधने के लिए किया जा सकता है।

एक समापन बिंदु के लिए एक फिल्टर या इंटरसेप्टर बांधना

विचार करें कि आपके पास एक इंटरसेप्टर है जो GZIP संपीड़न करता है और आप इस तरह के इंटरसेप्टर को एक संसाधन विधि से बांधना चाहते हैं। इसे करने के लिए, संसाधन विधि और इंटरसेप्टर दोनों को एनोटेट करें, निम्नानुसार:

@Compress
public class GZIPWriterInterceptor implements WriterInterceptor {

    @Override
    public void aroundWriteTo(WriterInterceptorContext context)
                    throws IOException, WebApplicationException {
        final OutputStream outputStream = context.getOutputStream();
        context.setOutputStream(new GZIPOutputStream(outputStream));
        context.proceed();
    }
}
@Path("helloworld")
public class HelloWorldResource {
 
    @GET
    @Produces("text/plain")
    public String getHello() {
        return "Hello World!";
    }
 
    @GET
    @Path("too-much-data")
    @Compress
    public String getVeryLongString() {
        String str = ... // very long string
        return str;
    }
}

@Compress संसाधन विधि getVeryLongString() और इंटरसेप्टर GZIPWriterInterceptor पर लागू किया जाता है। इंटरसेप्टर को केवल तभी निष्पादित किया जाएगा जब इस तरह के एनोटेशन के साथ कोई संसाधन विधि निष्पादित की जाएगी।

उपरोक्त उदाहरण में, इंटरसेप्टर को केवल getVeryLongString() पद्धति के लिए निष्पादित किया जाएगा। विधि getHello() लिए इंटरसेप्टर को निष्पादित नहीं किया जाएगा। इस उदाहरण में कारण शायद स्पष्ट है। हम केवल लंबे डेटा को संपीड़ित करना चाहते हैं और हमें "Hello World!" की संक्षिप्त प्रतिक्रिया को संपीड़ित करने की आवश्यकता नहीं है "Hello World!"

नाम बंधन संसाधन वर्ग पर लागू किया जा सकता है। उदाहरण में HelloWorldResource को @Compress साथ एनोटेट किया @Compress । इसका मतलब यह होगा कि सभी संसाधन विधियां इस मामले में संपीड़न का उपयोग करेंगी।

ध्यान दें कि वैश्विक फ़िल्टर हमेशा निष्पादित होते हैं, यहां तक कि संसाधन विधियों के लिए जिनके पास कोई भी नाम बाध्यकारी एनोटेशन हैं।

प्रलेखन



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow