REST वेब सेवा में HTTP स्थिति कोड सेट करने के लिए कई उपयोग के मामले हैं, और कम से कम एक को मौजूदा उत्तरों में पर्याप्त रूप से प्रलेखित नहीं किया गया था (यानी जब आप JAXB का उपयोग करके ऑटो-जादुई JSON / XML क्रमांकन का उपयोग कर रहे हैं, और आप एक वापस लौटना चाहते हैं क्रमबद्ध होने वाली वस्तु, लेकिन डिफ़ॉल्ट 200 से भिन्न स्थिति कोड भी)।
तो मुझे अलग-अलग उपयोग के मामलों और हर एक के समाधान के लिए प्रयास करना चाहिए:
1. त्रुटि कोड (500, 404, ...)
जब आप 200 OK
किसी त्रुटि के कारण स्थिति कोड को अलग से लौटना चाहते हैं तो सबसे आम उपयोग मामला है।
उदाहरण के लिए:
- एक इकाई का अनुरोध किया गया है, लेकिन यह मौजूद नहीं है (404)
- अनुरोध शब्दार्थ गलत है (400)
- उपयोगकर्ता अधिकृत नहीं है (401)
- डेटाबेस कनेक्शन के साथ एक समस्या है (500)
- आदि..
क) एक अपवाद फेंक दें
उस मामले में, मुझे लगता है कि समस्या को संभालने का सबसे साफ तरीका अपवाद को फेंकना है। इस अपवाद को एक द्वारा नियंत्रित किया ExceptionMapper
जाएगा, जो उचित त्रुटि कोड के साथ प्रतिक्रिया में अपवाद का अनुवाद करेगा।
आप ExceptionMapper
जर्सी के साथ पूर्व-कॉन्फ़िगर किए गए डिफ़ॉल्ट का उपयोग कर सकते हैं (और मुझे लगता है कि यह अन्य कार्यान्वयनों के साथ समान है) और के किसी भी मौजूदा उप-वर्गों को फेंक दें javax.ws.rs.WebApplicationException
। ये पूर्व-परिभाषित अपवाद प्रकार हैं जो विभिन्न त्रुटि कोड के लिए पूर्व-मैप किए गए हैं, उदाहरण के लिए:
- BadRequestException (400)
- इंटरनलसर्वरर एक्ससेप्शन (500)
- NotFoundException (404)
आदि आप यहाँ सूची पा सकते हैं: एपीआई
वैकल्पिक रूप से, आप अपने स्वयं के कस्टम अपवादों और ExceptionMapper
वर्गों को परिभाषित कर सकते हैं , और @Provider
एनोटेशन ( इस उदाहरण का स्रोत ) के माध्यम से जर्सी में इन मैपर्स को जोड़ सकते हैं :
public class MyApplicationException extends Exception implements Serializable
{
private static final long serialVersionUID = 1L;
public MyApplicationException() {
super();
}
public MyApplicationException(String msg) {
super(msg);
}
public MyApplicationException(String msg, Exception e) {
super(msg, e);
}
}
प्रदाता:
@Provider
public class MyApplicationExceptionHandler implements ExceptionMapper<MyApplicationException>
{
@Override
public Response toResponse(MyApplicationException exception)
{
return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();
}
}
नोट: आप मौजूदा अपवाद प्रकारों के लिए ExceptionMappers भी लिख सकते हैं जिनका आप उपयोग करते हैं।
बी) रिस्पांस बिल्डर का उपयोग करें
स्टेटस कोड सेट करने का दूसरा तरीका यह है कि आप Response
बिल्डर का उपयोग इच्छित कोड के साथ प्रतिक्रिया बनाने के लिए करें।
उस स्थिति में, आपके विधि का रिटर्न प्रकार अवश्य होना चाहिए javax.ws.rs.core.Response
। इसे विभिन्न अन्य प्रतिक्रियाओं में वर्णित किया गया है, जैसे कि उनका जवाब 'स्वीकार किए जाते हैं और इस तरह दिखता है:
@GET
@Path("myresource({id}")
public Response retrieveSomething(@PathParam("id") String id) {
...
Entity entity = service.getById(uuid);
if(entity == null) {
return Response.status(Response.Status.NOT_FOUND).entity("Resource not found for ID: " + uuid).build();
}
...
}
2. सफलता, लेकिन 200 नहीं
एक अन्य मामला जब आप रिटर्न की स्थिति सेट करना चाहते हैं, जब ऑपरेशन सफल रहा था, लेकिन आप 200 से अधिक सफलता कोड वापस करना चाहते हैं, साथ ही उस सामग्री के साथ जो आप शरीर में वापस करते हैं।
एक बार-बार उपयोग का मामला तब होता है जब आप एक नई इकाई ( POST
अनुरोध) बनाते हैं और इस नई इकाई के बारे में जानकारी वापस करना चाहते हैं या हो सकता है कि इकाई ही, एक साथ एक 201 Created
स्थिति कोड के साथ।
एक दृष्टिकोण प्रतिक्रिया वस्तु का उपयोग करना है जैसा कि ऊपर वर्णित है और अनुरोध के शरीर को स्वयं सेट करें। हालाँकि, ऐसा करने से आप JAXB द्वारा प्रदान किए गए XML या JSON को स्वचालित क्रमांकन का उपयोग करने की क्षमता को ढीला कर देते हैं।
यह एक मूल वस्तु है, जो JAXB द्वारा JSON को क्रमबद्ध की जाएगी, एक इकाई वस्तु लौटाती है:
@Path("/")
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public User addUser(User user){
User newuser = ... do something like DB insert ...
return newuser;
}
यह नए बनाए गए उपयोगकर्ता का JSON प्रतिनिधित्व लौटाएगा, लेकिन रिटर्न की स्थिति 200 होगी, न कि 201।
अब समस्या यह है कि अगर मैं Response
रिटर्न कोड सेट करने के लिए बिल्डर का उपयोग करना चाहता हूं, तो मुझे Response
अपने तरीके से एक ऑब्जेक्ट वापस करना होगा । मैं अभी भी User
धारावाहिक होने के लिए वस्तु कैसे लौटाऊं?
a) सर्वलेट रिस्पांस पर कोड सेट करें
इसे हल करने के लिए एक दृष्टिकोण एक सर्वलेट अनुरोध ऑब्जेक्ट प्राप्त करना है और मैन्युअल रूप से प्रतिक्रिया कोड स्वयं सेट करना है, जैसे गैरेट विल्सन के उत्तर में दिखाया गया है:
@Path("/")
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public User addUser(User user, @Context final HttpServletResponse response){
User newUser = ...
//set HTTP code to "201 Created"
response.setStatus(HttpServletResponse.SC_CREATED);
try {
response.flushBuffer();
}catch(Exception e){}
return newUser;
}
विधि अभी भी एक इकाई वस्तु लौटाती है और स्थिति कोड 201 होगा।
ध्यान दें कि इसे काम करने के लिए, मुझे प्रतिक्रिया को फ्लश करना पड़ा। यह हमारे अच्छे JAX_RS संसाधन में निम्न-स्तर के सर्वलेट एपीआई कोड का एक अप्रिय पुनरुत्थान है, और इससे भी बदतर, यह हेडर को इसके बाद अनम्य होने का कारण बनता है क्योंकि वे पहले से ही तार पर भेजे गए थे।
ख) इकाई के साथ प्रतिक्रिया वस्तु का उपयोग करें
उस मामले में सबसे अच्छा समाधान, प्रतिक्रिया वस्तु का उपयोग करना है और इस प्रतिक्रिया वस्तु पर क्रमबद्ध होने के लिए इकाई निर्धारित करना है। उस मामले में पेलोड इकाई के प्रकार को इंगित करने के लिए रिस्पांस ऑब्जेक्ट को सामान्य बनाना अच्छा होगा, लेकिन वर्तमान में ऐसा नहीं है।
@Path("/")
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response addUser(User user){
User newUser = ...
return Response.created(hateoas.buildLinkUri(newUser, "entity")).entity(restResponse).build();
}
उस स्थिति में, हम स्थिति कोड को 201 पर सेट करने के लिए रिस्पॉन्स बिल्डर वर्ग की बनाई गई विधि का उपयोग करते हैं। हम इकाई () विधि के माध्यम से प्रतिक्रिया के लिए इकाई वस्तु (उपयोगकर्ता) पास करते हैं।
इसका नतीजा यह है कि HTTP कोड 401 है जैसा हम चाहते थे, और प्रतिक्रिया का शरीर ठीक उसी JSON है जैसा कि हमने पहले किया था जब हमने उपयोगकर्ता ऑब्जेक्ट वापस किया था। यह एक स्थान हेडर भी जोड़ता है।
रिस्पांस क्लास में विभिन्न स्टेटस (स्टेटि) के लिए कई बिल्डर विधि होती है जैसे:
Response.accepted () Response.ok () Response.noContent () Response.notAcable ()
NB: हटियोस ऑब्जेक्ट एक सहायक वर्ग है जिसे मैंने संसाधन URI बनाने में मदद करने के लिए विकसित किया है। आपको अपने स्वयं के तंत्र के साथ आने की आवश्यकता होगी;)
यह इसके बारे में।
मुझे उम्मीद है कि यह लंबी प्रतिक्रिया किसी की मदद करती है :)