Skip to content

Commit 25743a1

Browse files
author
Evgeniy Sinev
committed
Added IExceptionHandler, switched to maven.pne.io repo
1 parent 848bfb6 commit 25743a1

File tree

12 files changed

+194
-57
lines changed

12 files changed

+194
-57
lines changed

pom.xml

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@
3838
-->
3939
<distributionManagement>
4040
<repository>
41-
<id>sonatype-nexus-release</id>
42-
<name>sonatype oss RELEASE repository</name>
43-
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
41+
<id>mpos-repo</id>
42+
<name>mpos release repository</name>
43+
<url>https://mpos.pne.io/maven-deploy/releases</url>
4444
</repository>
4545

4646
<snapshotRepository>
47-
<id>sonatype-nexus-snapshot</id>
48-
<name>sonatype oss SNAPSHOT repository</name>
49-
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
47+
<id>mpos-repo-snapshots</id>
48+
<name>mpos snapshot repository</name>
49+
<url>https://mpos.pne.io/maven-deploy/snapshots</url>
5050
<uniqueVersion>false</uniqueVersion>
5151
</snapshotRepository>
5252

@@ -173,18 +173,6 @@
173173
<version>2.5.3</version>
174174
</plugin>
175175

176-
<plugin>
177-
<groupId>org.sonatype.plugins</groupId>
178-
<artifactId>nexus-staging-maven-plugin</artifactId>
179-
<version>1.6.3</version>
180-
<extensions>true</extensions>
181-
<configuration>
182-
<serverId>sonatype-nexus-staging</serverId>
183-
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
184-
<autoReleaseAfterClose>true</autoReleaseAfterClose>
185-
</configuration>
186-
</plugin>
187-
188176
</plugins>
189177
</build>
190178

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.payneteasy.apiservlet;
2+
3+
import javax.servlet.http.HttpServletResponse;
4+
5+
public class ExceptionContextImpl implements IExceptionContext {
6+
7+
private HttpServletResponse response;
8+
9+
public ExceptionContextImpl(HttpServletResponse response) {
10+
this.response = response;
11+
}
12+
13+
@Override
14+
public HttpServletResponse getHttpResponse() {
15+
return response;
16+
}
17+
}

src/main/java/com/payneteasy/apiservlet/GsonApiServlet.java

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,68 +9,59 @@
99
import javax.servlet.http.HttpServletResponse;
1010
import java.io.BufferedReader;
1111
import java.io.IOException;
12-
import java.util.UUID;
1312

1413
public class GsonApiServlet<I, O> extends HttpServlet {
1514

1615
private static final Logger LOG = LoggerFactory.getLogger(GsonApiServlet.class);
1716

18-
private final IApiCall<I, O> apiCall;
19-
private final Class<I> requestClass;
20-
private final Gson gson;
17+
private final IApiCall<I, O> apiCall;
18+
private final Class<I> requestClass;
19+
private final Gson gson;
20+
private final boolean isVoidRequest;
21+
private final IExceptionHandler exceptionHandler;
2122

22-
public GsonApiServlet(IApiCall<I, O> aApiCall, Class<I> aRequestClass, Gson aGson) {
23+
24+
public GsonApiServlet(IApiCall<I, O> aApiCall, Class<I> aRequestClass, Gson aGson, IExceptionHandler aExceptionHandler) {
2325
apiCall = aApiCall;
2426
gson = aGson;
2527
requestClass = aRequestClass;
28+
isVoidRequest = VoidRequest.class.equals(aRequestClass);
29+
exceptionHandler = aExceptionHandler;
2630
}
2731

2832
@Override
2933
protected void doPost(HttpServletRequest aRequest, HttpServletResponse aResponse) {
3034
try {
3135
String json = toJsonString(aRequest.getReader());
32-
I request = gson.fromJson(json, requestClass);
36+
//noinspection unchecked
37+
I request = isVoidRequest ? (I)VoidRequest.VOID_REQUEST : gson.fromJson(json, requestClass);
3338

34-
LOG.debug("Got {} \n{}", aRequest.getRequestURI(), json);
39+
LOG.debug("Incoming POST message {} \n{}", aRequest.getRequestURI(), json);
3540

3641
processRequest(aRequest, aResponse, request);
37-
} catch (IOException e) {
38-
sendError(aResponse, e);
39-
}
40-
}
4142

42-
private void sendError(HttpServletResponse aResponse, IOException e) {
43-
String errorId = UUID.randomUUID().toString();
44-
LOG.error("{}: IO error", errorId, e);
45-
aResponse.setStatus(500);
46-
try {
47-
aResponse.getWriter().write("{'error' : 'IO error " + errorId + "'}");
48-
} catch (IOException e1) {
49-
LOG.error("Cannot write error to servlet", e);
43+
} catch (Exception e) {
44+
exceptionHandler.handleException(e, new ExceptionContextImpl(aResponse));
5045
}
5146
}
5247

5348
@Override
5449
protected void doGet(HttpServletRequest aRequest, HttpServletResponse aResponse) {
5550
try {
51+
LOG.debug("Incoming GET message {}", aRequest.getRequestURI());
5652
processRequest(aRequest, aResponse, null);
57-
} catch (IOException e) {
58-
sendError(aResponse, e);
53+
} catch (Exception e) {
54+
exceptionHandler.handleException(e, new ExceptionContextImpl(aResponse));
5955
}
6056
}
6157

62-
private void processRequest(HttpServletRequest aRequest, HttpServletResponse aResponse, I request) throws IOException {
63-
try {
64-
O response = apiCall.exec(request);
58+
private void processRequest(HttpServletRequest aRequest, HttpServletResponse aResponse, I request) throws Exception {
59+
O response = apiCall.exec(request);
60+
String jsonResponse = gson.toJson(response);
6561

66-
aResponse.setContentType("application/json");
67-
gson.toJson(response, aResponse.getWriter());
68-
} catch (Exception e) {
69-
String id = UUID.randomUUID().toString();
70-
LOG.error("{}: Cannot process {}", aRequest.getRequestURI(), id, e);
71-
aResponse.setHeader("UNIQUE-ERROR-ID", id);
72-
aResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
73-
}
62+
LOG.debug("Response message {} is \n{}", aRequest.getRequestURI(), jsonResponse);
63+
aResponse.setContentType("application/json");
64+
aResponse.getWriter().write(jsonResponse);
7465
}
7566

7667
private String toJsonString(BufferedReader aRequestReader) throws IOException {

src/main/java/com/payneteasy/apiservlet/GsonJettyContextHandler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ public class GsonJettyContextHandler {
1414

1515
private final ServletContextHandler context;
1616
private final Gson gson;
17+
private final IExceptionHandler exceptionHandler;
1718

18-
public GsonJettyContextHandler(ServletContextHandler aContext, Gson aGson) {
19+
public GsonJettyContextHandler(ServletContextHandler aContext, Gson aGson, IExceptionHandler aHandler) {
1920
context = aContext;
2021
gson = aGson;
22+
exceptionHandler = aHandler;
2123
}
2224

2325
public void add(String path, HttpServlet servlet) {
@@ -26,7 +28,7 @@ public void add(String path, HttpServlet servlet) {
2628
}
2729

2830
public <I,O> void addApi(String path, IApiCall<I, O> aApiCall, Class<I> aRequestClass) {
29-
add(path, new GsonApiServlet<>(aApiCall, aRequestClass, gson));
31+
add(path, new GsonApiServlet<>(aApiCall, aRequestClass, gson, exceptionHandler));
3032
}
3133

3234
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.payneteasy.apiservlet;
2+
3+
import javax.servlet.http.HttpServletResponse;
4+
5+
public interface IExceptionContext {
6+
7+
HttpServletResponse getHttpResponse();
8+
9+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.payneteasy.apiservlet;
2+
3+
public interface IExceptionHandler {
4+
5+
void handleException(Exception aException, IExceptionContext aContext);
6+
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.payneteasy.apiservlet;
2+
3+
public class VoidRequest {
4+
5+
public static final VoidRequest VOID_REQUEST = new VoidRequest();
6+
7+
private VoidRequest() {
8+
}
9+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.payneteasy.apiservlet.problem;
2+
3+
/**
4+
* See https://tools.ietf.org/html/rfc7807
5+
*/
6+
public interface IProblemType {
7+
8+
String getType();
9+
10+
int getStatusCode();
11+
12+
String getTitle();
13+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.payneteasy.apiservlet.problem;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
public class ProblemDetails {
7+
8+
/**
9+
* A URI reference [RFC3986] that identifies the
10+
* problem type. This specification encourages that, when
11+
* dereferenced, it provide human-readable documentation for the
12+
* problem type (e.g., using HTML [W3C.REC-html5-20141028]). When
13+
* this member is not present, its value is assumed to be
14+
* "about:blank".
15+
*/
16+
private final String type;
17+
18+
/**
19+
* A short, human-readable summary of the problem
20+
* type. It SHOULD NOT change from occurrence to occurrence of the
21+
* problem, except for purposes of localization (e.g., using
22+
* proactive content negotiation; see [RFC7231], Section 3.4).
23+
*/
24+
private final String title;
25+
26+
/**
27+
* The HTTP status code ([RFC7231], Section 6)
28+
* generated by the origin server for this occurrence of the problem.
29+
*/
30+
private final int status;
31+
32+
/**
33+
* A human-readable explanation specific to this
34+
* occurrence of the problem
35+
*/
36+
private final String detail;
37+
38+
/**
39+
* A URI reference that identifies the specific
40+
* occurrence of the problem. It may or may not yield further
41+
* information if dereferenced.
42+
*
43+
* Example: /account/12345/msgs/abc
44+
*/
45+
private final String instance;
46+
47+
private final Map<String, String> context;
48+
49+
private final List<ProblemDetails> subproblems;
50+
51+
public ProblemDetails(String type, String title, int aStatus, String detail, String aInstance, Map<String, String> aContext, List<ProblemDetails> subproblems) {
52+
this.type = type;
53+
this.title = title;
54+
this.detail = detail;
55+
this.subproblems = subproblems;
56+
status = aStatus;
57+
instance = aInstance;
58+
context = aContext;
59+
}
60+
61+
public String getType() {
62+
return type;
63+
}
64+
65+
public String getTitle() {
66+
return title;
67+
}
68+
69+
public String getDetail() {
70+
return detail;
71+
}
72+
73+
public List<ProblemDetails> getSubproblems() {
74+
return subproblems;
75+
}
76+
77+
78+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.payneteasy.apiservlet.problem;
2+
3+
public class ProblemDetailsException extends Exception {
4+
5+
private final ProblemDetails problemDetails;
6+
7+
public ProblemDetailsException(ProblemDetails aProblem, String message) {
8+
super(message);
9+
problemDetails = aProblem;
10+
}
11+
12+
public ProblemDetailsException(ProblemDetails aProblem, String message, Throwable cause) {
13+
super(message, cause);
14+
problemDetails = aProblem;
15+
}
16+
17+
public ProblemDetails getProblemDetails() {
18+
return problemDetails;
19+
}
20+
21+
}

0 commit comments

Comments
 (0)