BaseJsonApiManager.java 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright 2012-2020 CodeLibs Project and the Others.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  13. * either express or implied. See the License for the specific language
  14. * governing permissions and limitations under the License.
  15. */
  16. package org.codelibs.fess.api;
  17. import java.io.IOException;
  18. import java.io.PrintWriter;
  19. import java.io.StringWriter;
  20. import java.text.SimpleDateFormat;
  21. import java.util.Date;
  22. import java.util.List;
  23. import java.util.Locale;
  24. import java.util.Map;
  25. import javax.servlet.http.HttpServletResponse;
  26. import org.apache.commons.text.StringEscapeUtils;
  27. import org.codelibs.core.CoreLibConstants;
  28. import org.codelibs.core.lang.StringUtil;
  29. import org.codelibs.fess.Constants;
  30. import org.codelibs.fess.exception.InvalidAccessTokenException;
  31. import org.codelibs.fess.util.ComponentUtil;
  32. import org.lastaflute.web.util.LaRequestUtil;
  33. import org.lastaflute.web.util.LaResponseUtil;
  34. public abstract class BaseJsonApiManager extends BaseApiManager {
  35. protected String mimeType = "application/json";
  36. protected void writeJsonResponse(final int status, final String body, final Throwable t) {
  37. if (t == null) {
  38. writeJsonResponse(status, body, (String) null);
  39. return;
  40. }
  41. if (t instanceof InvalidAccessTokenException) {
  42. final InvalidAccessTokenException e = (InvalidAccessTokenException) t;
  43. final HttpServletResponse response = LaResponseUtil.getResponse();
  44. response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  45. response.setHeader("WWW-Authenticate", "Bearer error=\"" + e.getType() + "\"");
  46. }
  47. final StringBuilder sb = new StringBuilder();
  48. if (StringUtil.isBlank(t.getMessage())) {
  49. sb.append(t.getClass().getName());
  50. } else {
  51. sb.append(t.getMessage());
  52. }
  53. final StringWriter sw = new StringWriter();
  54. t.printStackTrace(new PrintWriter(sw));
  55. sb.append(" [ ").append(sw.toString()).append(" ]");
  56. try {
  57. sw.close();
  58. } catch (final IOException ignore) {}
  59. writeJsonResponse(status, body, sb.toString());
  60. }
  61. protected void writeJsonResponse(final int status, final String body, final String errMsg) {
  62. String content = null;
  63. if (status == 0) {
  64. if (StringUtil.isNotBlank(body)) {
  65. content = body;
  66. }
  67. } else {
  68. content = "\"message\":" + escapeJson(errMsg);
  69. }
  70. writeJsonResponse(status, content);
  71. }
  72. protected void writeJsonResponse(final int status, final String body) {
  73. final String callback = LaRequestUtil.getRequest().getParameter("callback");
  74. final boolean isJsonp = ComponentUtil.getFessConfig().isApiJsonpEnabled() && StringUtil.isNotBlank(callback);
  75. final StringBuilder buf = new StringBuilder(1000);
  76. if (isJsonp) {
  77. buf.append(escapeCallbackName(callback));
  78. buf.append('(');
  79. }
  80. buf.append("{\"response\":");
  81. buf.append("{\"version\":");
  82. buf.append(ComponentUtil.getSystemHelper().getProductVersion());
  83. buf.append(',');
  84. buf.append("\"status\":");
  85. buf.append(status);
  86. if (StringUtil.isNotBlank(body)) {
  87. buf.append(',');
  88. buf.append(body);
  89. }
  90. buf.append('}');
  91. buf.append('}');
  92. if (isJsonp) {
  93. buf.append(')');
  94. }
  95. write(buf.toString(), mimeType, Constants.UTF_8);
  96. }
  97. protected String escapeCallbackName(final String callbackName) {
  98. return "/**/" + callbackName.replaceAll("[^0-9a-zA-Z_\\$\\.]", StringUtil.EMPTY);
  99. }
  100. protected String escapeJson(final Object obj) {
  101. if (obj == null) {
  102. return "null";
  103. }
  104. final StringBuilder buf = new StringBuilder(255);
  105. if (obj instanceof String[]) {
  106. buf.append('[');
  107. boolean first = true;
  108. for (final Object child : (String[]) obj) {
  109. if (first) {
  110. first = false;
  111. } else {
  112. buf.append(',');
  113. }
  114. buf.append(escapeJson(child));
  115. }
  116. buf.append(']');
  117. } else if (obj instanceof List<?>) {
  118. buf.append('[');
  119. boolean first = true;
  120. for (final Object child : (List<?>) obj) {
  121. if (first) {
  122. first = false;
  123. } else {
  124. buf.append(',');
  125. }
  126. buf.append(escapeJson(child));
  127. }
  128. buf.append(']');
  129. } else if (obj instanceof Map<?, ?>) {
  130. buf.append('{');
  131. boolean first = true;
  132. for (final Map.Entry<?, ?> entry : ((Map<?, ?>) obj).entrySet()) {
  133. if (first) {
  134. first = false;
  135. } else {
  136. buf.append(',');
  137. }
  138. buf.append(escapeJson(entry.getKey())).append(':').append(escapeJson(entry.getValue()));
  139. }
  140. buf.append('}');
  141. } else if (obj instanceof Integer) {
  142. buf.append((obj));
  143. } else if (obj instanceof Long) {
  144. buf.append((obj));
  145. } else if (obj instanceof Float) {
  146. buf.append((obj));
  147. } else if (obj instanceof Double) {
  148. buf.append((obj));
  149. } else if (obj instanceof Boolean) {
  150. buf.append(obj.toString());
  151. } else if (obj instanceof Date) {
  152. final SimpleDateFormat sdf = new SimpleDateFormat(CoreLibConstants.DATE_FORMAT_ISO_8601_EXTEND, Locale.ROOT);
  153. buf.append('\"').append(StringEscapeUtils.escapeJson(sdf.format(obj))).append('\"');
  154. } else {
  155. buf.append('\"').append(StringEscapeUtils.escapeJson(obj.toString())).append('\"');
  156. }
  157. return buf.toString();
  158. }
  159. public void setMimeType(final String mimeType) {
  160. this.mimeType = mimeType;
  161. }
  162. }