Skip to content

Commit 35e1b06

Browse files
committed
Custom error handler that deals with json/jsonp
1 parent f9c9b8a commit 35e1b06

File tree

5 files changed

+108
-47
lines changed

5 files changed

+108
-47
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.regexplanet;
2+
3+
import org.springframework.boot.web.servlet.error.ErrorController;
4+
import org.springframework.stereotype.Controller;
5+
import org.springframework.web.bind.annotation.RequestMapping;
6+
import org.springframework.web.util.UrlPathHelper;
7+
8+
import java.util.LinkedHashMap;
9+
import java.util.Map;
10+
import java.util.regex.Pattern;
11+
12+
@Controller
13+
public class CustomErrorController implements ErrorController {
14+
15+
static final Pattern callbackPattern = Pattern.compile("([&]|^)callback=([^&]+)");
16+
17+
@RequestMapping("/error")
18+
public void handleError(jakarta.servlet.http.HttpServletRequest req,
19+
jakarta.servlet.http.HttpServletResponse resp) throws java.io.IOException {
20+
Object status = req.getAttribute("jakarta.servlet.error.status_code");
21+
22+
23+
String callback = null;
24+
String qs = UrlPathHelper.defaultInstance.getOriginatingQueryString(req);
25+
if (qs != null) {
26+
java.util.regex.Matcher matcher = callbackPattern.matcher(qs);
27+
if (matcher.find()) {
28+
callback = matcher.group(2);
29+
}
30+
}
31+
32+
Integer statusCode = 500;
33+
if (status != null) {
34+
statusCode = Integer.valueOf(status.toString());
35+
} else {
36+
// LATER: warning message
37+
//System.out.println("No status code found in request");
38+
}
39+
40+
String message = (String) req.getAttribute("jakarta.servlet.error.message");
41+
if (message == null || message.length() == 0) {
42+
//System.out.println("No error message found in request");
43+
44+
Object ex = req.getAttribute("jakarta.servlet.error.exception");
45+
if (ex != null && ex instanceof Throwable) {
46+
Throwable throwable = (Throwable) ex;
47+
message = throwable.getMessage();
48+
} else {
49+
message = "Server Error";
50+
}
51+
}
52+
resp.setStatus(statusCode);
53+
Map<String, Object> retVal = new LinkedHashMap<>();
54+
retVal.put("success", Boolean.FALSE);
55+
retVal.put("code", statusCode);
56+
retVal.put("message", message);
57+
58+
HandleJsonp.handleJsonp(resp, callback, retVal);
59+
}
60+
61+
public String getErrorPath() {
62+
return "/error";
63+
}
64+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.regexplanet;
2+
3+
import java.io.PrintWriter;
4+
import java.util.Map;
5+
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
8+
public class HandleJsonp {
9+
10+
public static void handleJsonp(
11+
jakarta.servlet.http.HttpServletResponse resp,
12+
String callback,
13+
Map<String, Object> retVal
14+
) throws java.io.IOException {
15+
16+
ObjectMapper objectMapper = new ObjectMapper();
17+
String jsonResponse = objectMapper.writeValueAsString(retVal);
18+
19+
if (callback != null && callback.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
20+
resp.setContentType("application/javascript");
21+
resp.setCharacterEncoding("UTF-8");
22+
PrintWriter writer = resp.getWriter();
23+
writer.write(callback);
24+
writer.write("(");
25+
writer.write(jsonResponse);
26+
writer.write(");");
27+
} else {
28+
resp.setHeader("Access-Control-Allow-Origin", "*");
29+
resp.setHeader("Access-Control-Allow-Methods", "GET, POST");
30+
resp.setHeader("Access-Control-Max-Age", "604800");
31+
resp.setContentType("application/json");
32+
resp.setCharacterEncoding("UTF-8");
33+
resp.getWriter().write(jsonResponse);
34+
}
35+
}
36+
}
Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
package com.regexplanet;
22

3-
import com.fasterxml.jackson.databind.ObjectMapper;
43

54
import org.springframework.stereotype.Controller;
65
import org.springframework.web.bind.annotation.GetMapping;
76
import org.springframework.web.bind.annotation.RequestParam;
87

98
import java.io.IOException;
10-
import java.io.PrintWriter;
119
import java.time.ZoneOffset;
1210
import java.time.ZonedDateTime;
1311
import java.time.format.DateTimeFormatter;
14-
import java.util.HashMap;
12+
import java.util.LinkedHashMap;
1513
import java.util.Map;
1614

1715
@Controller
@@ -22,7 +20,7 @@ public void handle(jakarta.servlet.http.HttpServletResponse resp, @RequestParam(
2220
throws IOException {
2321

2422
// Create a JSON response
25-
Map<String, Object> retVal = new HashMap<>();
23+
Map<String, Object> retVal = new LinkedHashMap<>();
2624
retVal.put("success", Boolean.TRUE);
2725
retVal.put("message", "OK");
2826
retVal.put("commit", System.getenv("COMMIT"));
@@ -42,26 +40,6 @@ public void handle(jakarta.servlet.http.HttpServletResponse resp, @RequestParam(
4240
retVal.put("java.vm.name", System.getProperty("java.vm.name"));
4341
retVal.put("file.encoding", System.getProperty("file.encoding"));
4442

45-
// Convert the map to JSON using Jackson
46-
ObjectMapper objectMapper = new ObjectMapper();
47-
String jsonResponse = objectMapper.writeValueAsString(retVal);
48-
49-
// Write the JSON response
50-
if (callback != null && callback.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
51-
resp.setContentType("application/javascript");
52-
resp.setCharacterEncoding("UTF-8");
53-
PrintWriter writer = resp.getWriter();
54-
writer.write(callback);
55-
writer.write("(");
56-
writer.write(jsonResponse);
57-
writer.write(");");
58-
} else {
59-
resp.setHeader("Access-Control-Allow-Origin", "*");
60-
resp.setHeader("Access-Control-Allow-Methods", "GET, POST");
61-
resp.setHeader("Access-Control-Max-Age", "604800");
62-
resp.setContentType("application/json");
63-
resp.setCharacterEncoding("UTF-8");
64-
resp.getWriter().write(jsonResponse);
65-
}
43+
HandleJsonp.handleJsonp(resp, callback, retVal);
6644
}
6745
}

src/main/java/com/regexplanet/TestController.java

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
import org.springframework.web.bind.annotation.RequestParam;
1919
import org.springframework.web.util.HtmlUtils;
2020

21-
import com.fasterxml.jackson.databind.ObjectMapper;
22-
2321
@Controller
2422
public class TestController {
2523

@@ -293,26 +291,7 @@ public void handle(jakarta.servlet.http.HttpServletResponse resp,
293291
pw.close();
294292
retVal.put("html", sw.toString());
295293
}
296-
297-
ObjectMapper objectMapper = new ObjectMapper();
298-
String jsonResponse = objectMapper.writeValueAsString(retVal);
299-
300-
if (callback != null && callback.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
301-
resp.setContentType("application/javascript");
302-
resp.setCharacterEncoding("UTF-8");
303-
PrintWriter writer = resp.getWriter();
304-
writer.write(callback);
305-
writer.write("(");
306-
writer.write(jsonResponse);
307-
writer.write(");");
308-
} else {
309-
resp.setHeader("Access-Control-Allow-Origin", "*");
310-
resp.setHeader("Access-Control-Allow-Methods", "GET, POST");
311-
resp.setHeader("Access-Control-Max-Age", "604800");
312-
resp.setContentType("application/json");
313-
resp.setCharacterEncoding("UTF-8");
314-
resp.getWriter().write(jsonResponse);
315-
}
294+
HandleJsonp.handleJsonp(resp, callback, retVal);
316295
}
317296

318297
}

src/main/resources/application.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
# remap PORT to SERVER_PORT
22
server:
33
port: ${PORT:4000}
4+
error:
5+
include-stacktrace: never
6+
whitelabel:
7+
enabled: false

0 commit comments

Comments
 (0)