The browser (or any client) sends HTTP requests to our Glassfish server in order to consume our REST Services. If the server is able to process the request it returns the response data itself and a HTTP Status code that tells the caller if everything was ok or not. There are a lot of HTTP Staus codes defined in the HTTP Spec, I am sure you know at least 404 (Not Found), 200 (OK), 500 (Internal Server Error). On our frontend we use jQuery (frontend is discussed later). When executing Ajax requests with jQuery the error callback function that you define for your Ajax call is called automatically by jQuery depending on the HTTP Status code of the response. Besides that you could also define a statusCode object for your Ajax call and define callback functions for each HTTP Status code you are interested in (later you will see some example code below). When implementing your backend services you always want to implement a safe error handling, you want to consider everything that could happen. Once you know what could happen you start thinking about what HTTP Status code should be returned for each specific case, i.e. you might want to return a 404 in case the ID for your getBookById Service doesn’t exist in the database, or you might want to return a 403 in case the user doesn’t have enough privileges to call your getBookById service. This little example should only tell you that you could and should make use of the HTTP Status codes. But then there are also cases where you cannot clearly identify which HTTP Status you should return. Furthermore using all of the possible HTTP Status codes could also require additional lines of code within your frontend in order to “react” correctly. You should decide whether you want to treat the HTTP Status code as part of your REST APIs or not, and that decision can be different from project to project, or even from service to service (latter might not be the best solution). I usually make use of only a few HTTP Status codes, i.e. 404, 403, 500, 200 etc. Besides that I use a JsonEnvelope which separates the response data itself and the “application” status of the request. In all my JSON responses I use this JsonEnvelope – a very simple POJO which is not even extending javax.ws.rs.core.Response (ok, maybe I was a little lazy to extend javax.ws.rs.core.Response…). The application status (you might want to use another term for that, maybe “app request status”) is something different than the HTTP Status. To demonstrate this all let’s talk about our login service which is discussed in detail later: For now we only want to consider two cases (although there can be more). The first case is “Login succeeded” – in that case the HTTP Status is 200 (OK) and the JsonResponse status (aka application status) could be “SUCCESS”. The second case is “Login failed” – in that case the HTTP Status still stays at 200, whereas the JsonResponse status is “FAILED”. You don’t have to do it the way I decided, there are other options as well. Feel free to choose your own “Best Practics”. Please also consider that I have added a version attribute to the JsonResponse class because we might have different client technologies (not only our web frontend) and we might want to change the attributes of our JsonResponse. Here is the source code for our JsonResponse class:
1
2
3
4
5
6
7
8
9
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
|
package com.nabisoft.json; import java.util.Map; //import javax.xml.bind.annotation.XmlElement; //import javax.xml.bind.annotation.XmlRootElement; //import org.codehaus.jackson.map.annotate.JsonSerialize; //@XmlRootElement //we don't need this thanks to Jackson //@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY) //we already use global configuration, see MyJacksonJsonProvider.java public class JsonResponse{ private static final float version = 1 .0f; private String status; private String errorMsg; private Map<String, Object> fieldErrors; private Object data; public JsonResponse() { } public JsonResponse(String status) { this .status = status; } //@XmlElement //we don't need this thanks to Jackson public float getVersion() { return JsonResponse.version; } public String getStatus() { return status; } public void setStatus(String status) { this .status = status; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this .errorMsg = errorMsg; } public Map<String, Object> getFieldErrors() { return fieldErrors; } public void setFieldErrors(Map<String, Object> fieldErrors) { this .fieldErrors = fieldErrors; } public Object getData() { return data; } public void setData(Object data) { this .data = data; } } For more details about this check spring web hosting website.
|