This is an automated email from the ASF dual-hosted git repository.

peterxcli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 2e323b4b92c HDDS-13258. Refactor HttpServletResponse (Part1 - 
HddsConfServlet) (#9126)
2e323b4b92c is described below

commit 2e323b4b92cf1b075324d5c7e8227c6807cb11d6
Author: Eric Chang <[email protected]>
AuthorDate: Fri Nov 7 23:11:48 2025 +0800

    HDDS-13258. Refactor HttpServletResponse (Part1 - HddsConfServlet) (#9126)
    
    Co-authored-by: Doroszlai, Attila 
<[email protected]>
    Co-authored-by: Peter Lee <[email protected]>
---
 .../apache/hadoop/hdds/conf/HddsConfServlet.java   |  91 ++++-----
 .../apache/hadoop/hdds/utils/HttpServletUtils.java | 211 +++++++++++++++++++++
 .../hadoop/hdds/conf/TestHddsConfServlet.java      |  76 +++-----
 .../hadoop/hdds/utils/TestHttpServletUtils.java    |  78 ++++++++
 4 files changed, 351 insertions(+), 105 deletions(-)

diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/HddsConfServlet.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/HddsConfServlet.java
index cc5513e5e90..066735a0258 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/HddsConfServlet.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/conf/HddsConfServlet.java
@@ -17,7 +17,6 @@
 
 package org.apache.hadoop.hdds.conf;
 
-import com.google.common.annotations.VisibleForTesting;
 import java.io.IOException;
 import java.io.Writer;
 import java.util.HashMap;
@@ -27,11 +26,14 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.HttpHeaders;
+import org.apache.hadoop.conf.ConfServlet.BadFormatException;
 import org.apache.hadoop.hdds.annotation.InterfaceAudience;
 import org.apache.hadoop.hdds.annotation.InterfaceStability;
 import org.apache.hadoop.hdds.server.JsonUtils;
 import org.apache.hadoop.hdds.server.http.HttpServer2;
+import org.apache.hadoop.hdds.utils.HttpServletUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * A servlet to print out the running configuration data.
@@ -39,11 +41,11 @@
 @InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
 @InterfaceStability.Unstable
 public class HddsConfServlet extends HttpServlet {
+  private static final Logger LOG =
+      LoggerFactory.getLogger(HddsConfServlet.class);
 
   private static final long serialVersionUID = 1L;
 
-  protected static final String FORMAT_JSON = "json";
-  protected static final String FORMAT_XML = "xml";
   private static final String COMMAND = "cmd";
   private static final OzoneConfiguration OZONE_CONFIG =
       new OzoneConfiguration();
@@ -55,7 +57,7 @@ public class HddsConfServlet extends HttpServlet {
   private OzoneConfiguration getConfFromContext() {
     OzoneConfiguration conf =
         (OzoneConfiguration) getServletContext().getAttribute(
-        HttpServer2.CONF_CONTEXT_ATTRIBUTE);
+            HttpServer2.CONF_CONTEXT_ATTRIBUTE);
     assert conf != null;
     return conf;
   }
@@ -69,75 +71,47 @@ public void doGet(HttpServletRequest request, 
HttpServletResponse response)
       return;
     }
 
-    String format = parseAcceptHeader(request);
-    if (FORMAT_XML.equals(format)) {
-      response.setContentType("text/xml; charset=utf-8");
-    } else if (FORMAT_JSON.equals(format)) {
-      response.setContentType("application/json; charset=utf-8");
+    HttpServletUtils.ResponseFormat format = 
HttpServletUtils.getResponseFormat(request);
+    if (format == HttpServletUtils.ResponseFormat.UNSPECIFIED) {
+      // use XML as default response format
+      format = HttpServletUtils.ResponseFormat.XML;
     }
 
     String name = request.getParameter("name");
-    Writer out = response.getWriter();
     String cmd = request.getParameter(COMMAND);
 
-    processCommand(cmd, format, request, response, out, name);
-    out.close();
+    processCommand(cmd, format, request, response, name);
   }
 
-  private void processCommand(String cmd, String format,
-      HttpServletRequest request, HttpServletResponse response, Writer out,
-      String name)
+  private void processCommand(String cmd, HttpServletUtils.ResponseFormat 
format, HttpServletRequest request,
+                              HttpServletResponse response, String name)
       throws IOException {
     try {
       if (cmd == null) {
-        writeResponse(getConfFromContext(), out, format, name);
+        HttpServletUtils.writeResponse(response, format, (out) -> {
+          switch (format) {
+          case JSON:
+            OzoneConfiguration.dumpConfiguration(getConfFromContext(), name, 
out);
+            break;
+          case XML:
+            getConfFromContext().writeXml(name, out);
+            break;
+          default:
+            throw new BadFormatException("Bad format: " + format);
+          }
+        }, IllegalArgumentException.class);
       } else {
-        processConfigTagRequest(request, cmd, out);
+        processConfigTagRequest(request, cmd, response);
       }
-    } catch (BadFormatException bfe) {
-      response.sendError(HttpServletResponse.SC_BAD_REQUEST, bfe.getMessage());
     } catch (IllegalArgumentException iae) {
-      response.sendError(HttpServletResponse.SC_NOT_FOUND, iae.getMessage());
-    }
-  }
-
-  @VisibleForTesting
-  static String parseAcceptHeader(HttpServletRequest request) {
-    String format = request.getHeader(HttpHeaders.ACCEPT);
-    return format != null && format.contains(FORMAT_JSON) ?
-        FORMAT_JSON : FORMAT_XML;
-  }
-
-  /**
-   * Guts of the servlet - extracted for easy testing.
-   */
-  static void writeResponse(OzoneConfiguration conf,
-      Writer out, String format, String propertyName)
-      throws IOException, IllegalArgumentException, BadFormatException {
-    if (FORMAT_JSON.equals(format)) {
-      OzoneConfiguration.dumpConfiguration(conf, propertyName, out);
-    } else if (FORMAT_XML.equals(format)) {
-      conf.writeXml(propertyName, out);
-    } else {
-      throw new BadFormatException("Bad format: " + format);
-    }
-  }
-
-  /**
-   * Exception for signal bad content type.
-   */
-  public static class BadFormatException extends Exception {
-
-    private static final long serialVersionUID = 1L;
-
-    public BadFormatException(String msg) {
-      super(msg);
+      HttpServletUtils.writeErrorResponse(HttpServletResponse.SC_NOT_FOUND, 
iae.getMessage(), format, response);
     }
   }
 
-  private void processConfigTagRequest(HttpServletRequest request, String cmd,
-      Writer out) throws IOException {
+  private void processConfigTagRequest(HttpServletRequest request, String cmd, 
HttpServletResponse response)
+      throws IOException {
     OzoneConfiguration config = getOzoneConfig();
+    Writer out = response.getWriter();
 
     switch (cmd) {
     case "getOzoneTags":
@@ -147,7 +121,7 @@ private void processConfigTagRequest(HttpServletRequest 
request, String cmd,
       String tags = request.getParameter("tags");
       if (tags == null || tags.isEmpty()) {
         throw new IllegalArgumentException("The tags parameter should be set" +
-                " when using the getPropertyByTag command.");
+            " when using the getPropertyByTag command.");
       }
       Map<String, Properties> propMap = new HashMap<>();
 
@@ -162,7 +136,6 @@ private void processConfigTagRequest(HttpServletRequest 
request, String cmd,
     default:
       throw new IllegalArgumentException(cmd + " is not a valid command.");
     }
-
   }
 
   private static OzoneConfiguration getOzoneConfig() {
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HttpServletUtils.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HttpServletUtils.java
new file mode 100644
index 00000000000..682777e1f20
--- /dev/null
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HttpServletUtils.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hdds.utils;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.hadoop.hdds.server.JsonUtils;
+import org.apache.hadoop.util.XMLUtils;
+import org.apache.ratis.util.MemoizedCheckedSupplier;
+import org.apache.ratis.util.function.CheckedSupplier;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Utility class for HTTP servlet operations.
+ * Provides methods for parsing request headers and writing responses.
+ */
+public final class HttpServletUtils implements Serializable {
+
+  private static final CheckedSupplier<DocumentBuilderFactory, 
ParserConfigurationException> DOCUMENT_BUILDER_FACTORY =
+      
MemoizedCheckedSupplier.valueOf(XMLUtils::newSecureDocumentBuilderFactory);
+
+  private HttpServletUtils() {
+    // Utility class, prevent instantiation
+  }
+
+  /**
+   * Get the response format from request header.
+   *
+   * @param request the HTTP servlet request
+   * @return {@link ResponseFormat#JSON} if Accept header contains 
"application/json",
+   * otherwise {@link ResponseFormat#XML} (default for backwards compatibility)
+   * @see HttpHeaders#ACCEPT
+   */
+  public static ResponseFormat getResponseFormat(HttpServletRequest request) 
throws IllegalArgumentException {
+    String format = request.getHeader(HttpHeaders.ACCEPT);
+    if (format == null) {
+      return ResponseFormat.UNSPECIFIED;
+    }
+    return format.contains(ResponseFormat.JSON.getValue()) ?
+        ResponseFormat.JSON : ResponseFormat.XML;
+  }
+
+  /**
+   * Write error response according to the specified format.
+   *
+   * @param errorMessage the error message
+   * @param format       the response format
+   * @param response     the response
+   */
+  public static void writeErrorResponse(int status, String errorMessage, 
ResponseFormat format,
+      HttpServletResponse response)
+      throws IOException {
+    response.setStatus(status);
+    PrintWriter writer = response.getWriter();
+    switch (format) {
+    case JSON:
+      Map<String, String> errorMap = new HashMap<>();
+      errorMap.put("error", errorMessage);
+      writer.write(JsonUtils.toJsonString(errorMap));
+      break;
+    case XML:
+      writeXmlError(errorMessage, writer);
+      break;
+    default:
+      throw new IOException("Unsupported response format for error response: " 
+ format,
+          new IllegalArgumentException("Bad format: " + format));
+    }
+  }
+
+  private static void writeXmlError(String errorMessage, Writer out) throws 
IOException {
+    try {
+      DocumentBuilder builder = 
DOCUMENT_BUILDER_FACTORY.get().newDocumentBuilder();
+      Document doc = builder.newDocument();
+
+      Element root = doc.createElement("error");
+      root.setTextContent(errorMessage);
+      doc.appendChild(root);
+
+      TransformerFactory transformerFactory = TransformerFactory.newInstance();
+      Transformer transformer = transformerFactory.newTransformer();
+      transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+      transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
+
+      DOMSource source = new DOMSource(doc);
+      StreamResult result = new StreamResult(out);
+      transformer.transform(source, result);
+    } catch (ParserConfigurationException | TransformerException e) {
+      throw new IOException("Failed to write XML error response", e);
+    }
+  }
+
+  /**
+   * Write response according to the specified format.
+   * The caller provides a callback to write the content.
+   *
+   * @param response        the HTTP servlet response
+   * @param format          the response format
+   * @param contentWriter   callback to write content to the writer
+   * @param exceptionClass  class of exception to propagate from contentWriter
+   * @param <E>             the type of exception that may be thrown by 
contentWriter
+   * @throws IOException if an I/O error occurs
+   * @throws E           if contentWriter throws an exception of type E
+   */
+  public static <E extends Exception> void writeResponse(HttpServletResponse 
response, ResponseFormat format,
+      CheckedConsumer<Writer> contentWriter, Class<E> exceptionClass) throws 
IOException, E {
+    response.setContentType(format.getContentType());
+    Writer out = response.getWriter();
+    try {
+      contentWriter.accept(out);
+    } catch (IOException e) {
+      // Always rethrow IOException as-is
+      throw e;
+    } catch (Exception e) {
+      // If exception matches the generic type, throw it
+      if (exceptionClass.isInstance(e)) {
+        throw exceptionClass.cast(e);
+      }
+      // Otherwise wrap in IOException
+      throw new IOException("Failed to write response", e);
+    }
+  }
+
+  /**
+   * Functional interface for operations that accept a parameter and may throw 
exceptions.
+   *
+   * @param <T> the type of the input to the operation
+   */
+  @FunctionalInterface
+  public interface CheckedConsumer<T> {
+    void accept(T t) throws Exception;
+  }
+
+  /**
+   * Response format enumeration for HTTP responses.
+   * Supports JSON, XML, and UNSPECIFIED formats.
+   */
+  public enum ResponseFormat {
+    UNSPECIFIED("unspecified"),
+    JSON("json"),
+    XML("xml");
+    private final String value;
+
+    ResponseFormat(String value) {
+      this.value = value;
+    }
+
+    /**
+     * Get the string value of this response format.
+     *
+     * @return the format value (e.g., "json", "xml", "unspecified")
+     */
+    public String getValue() {
+      return value;
+    }
+
+    @Override
+    public String toString() {
+      return value;
+    }
+
+    /**
+     * Get Content-Type header value with UTF-8 charset for this format.
+     *
+     * @return Content-Type string (e.g., "application/json;charset=utf-8"),
+     * or null if UNSPECIFIED
+     */
+    public String getContentType() {
+      switch (this) {
+      case JSON:
+        return MediaType.APPLICATION_JSON_TYPE.withCharset("utf-8").toString();
+      case XML:
+        return MediaType.APPLICATION_XML_TYPE.withCharset("utf-8").toString();
+      default:
+        return null;
+      }
+    }
+  }
+}
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/conf/TestHddsConfServlet.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/conf/TestHddsConfServlet.java
index 3c262fdc924..671b3707a33 100644
--- 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/conf/TestHddsConfServlet.java
+++ 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/conf/TestHddsConfServlet.java
@@ -19,7 +19,6 @@
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
@@ -41,6 +40,7 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 import org.apache.hadoop.hdds.JsonTestUtils;
 import org.apache.hadoop.hdds.server.http.HttpServer2;
+import org.apache.hadoop.hdds.utils.HttpServletUtils;
 import org.apache.hadoop.util.XMLUtils;
 import org.eclipse.jetty.util.ajax.JSON;
 import org.junit.jupiter.api.BeforeAll;
@@ -64,27 +64,8 @@ public static void setup() {
     TEST_PROPERTIES.put("test.key1", "value1");
     TEST_PROPERTIES.put("test.key2", "value2");
     TEST_PROPERTIES.put("test.key3", "value3");
-    TEST_FORMATS.put(HddsConfServlet.FORMAT_XML, "application/xml");
-    TEST_FORMATS.put(HddsConfServlet.FORMAT_JSON, "application/json");
-  }
-
-  @Test
-  public void testParseHeaders() throws Exception {
-    HashMap<String, String> verifyMap = new HashMap<String, String>();
-    verifyMap.put("text/plain", HddsConfServlet.FORMAT_XML);
-    verifyMap.put(null, HddsConfServlet.FORMAT_XML);
-    verifyMap.put("text/xml", HddsConfServlet.FORMAT_XML);
-    verifyMap.put("application/xml", HddsConfServlet.FORMAT_XML);
-    verifyMap.put("application/json", HddsConfServlet.FORMAT_JSON);
-
-    HttpServletRequest request = mock(HttpServletRequest.class);
-    for (Map.Entry<String, String> entry : verifyMap.entrySet()) {
-      String contenTypeActual = entry.getValue();
-      when(request.getHeader(HttpHeaders.ACCEPT))
-          .thenReturn(entry.getKey());
-      assertEquals(contenTypeActual,
-          HddsConfServlet.parseAcceptHeader(request));
-    }
+    TEST_FORMATS.put(HttpServletUtils.ResponseFormat.XML.toString(), 
"application/xml");
+    TEST_FORMATS.put(HttpServletUtils.ResponseFormat.JSON.toString(), 
"application/json");
   }
 
   @Test
@@ -114,15 +95,26 @@ public void testGetPropertyWithCmd() throws Exception {
     // cmd is getPropertyByTag
     result = getResultWithCmd(conf, "getPropertyByTag");
     assertThat(result).contains("ozone.test.test.key");
-    // cmd is illegal
-    getResultWithCmd(conf, "illegal");
+    // cmd is illegal - verify XML error response
+    result = getResultWithCmd(conf, "illegal");
+    String expectedXmlResult = "<?xml version=\"1.0\" encoding=\"UTF-8\" 
standalone=\"no\"?>" +
+        "<error>illegal is not a valid command.</error>";
+    assertEquals(expectedXmlResult, result);
   }
 
   @Test
   @SuppressWarnings("unchecked")
   public void testWriteJson() throws Exception {
     StringWriter sw = new StringWriter();
-    HddsConfServlet.writeResponse(getTestConf(), sw, "json", null);
+    PrintWriter pw = new PrintWriter(sw);
+    HttpServletResponse response = mock(HttpServletResponse.class);
+    when(response.getWriter()).thenReturn(pw);
+
+    OzoneConfiguration conf = getTestConf();
+    HttpServletUtils.writeResponse(response, 
HttpServletUtils.ResponseFormat.JSON, (out) -> {
+      OzoneConfiguration.dumpConfiguration(conf, null, out);
+    }, IllegalArgumentException.class);
+
     String json = sw.toString();
     boolean foundSetting = false;
     Object parsed = JSON.parse(json);
@@ -143,7 +135,15 @@ public void testWriteJson() throws Exception {
   @Test
   public void testWriteXml() throws Exception {
     StringWriter sw = new StringWriter();
-    HddsConfServlet.writeResponse(getTestConf(), sw, "xml", null);
+    PrintWriter pw = new PrintWriter(sw);
+    HttpServletResponse response = mock(HttpServletResponse.class);
+    when(response.getWriter()).thenReturn(pw);
+
+    OzoneConfiguration conf = getTestConf();
+    HttpServletUtils.writeResponse(response, 
HttpServletUtils.ResponseFormat.XML, (out) -> {
+      conf.writeXml(null, out);
+    }, IllegalArgumentException.class);
+
     String xml = sw.toString();
 
     DocumentBuilderFactory docBuilderFactory =
@@ -166,14 +166,6 @@ public void testWriteXml() throws Exception {
     assertTrue(foundSetting);
   }
 
-  @Test
-  public void testBadFormat() throws Exception {
-    StringWriter sw = new StringWriter();
-    assertThrows(HddsConfServlet.BadFormatException.class,
-        () -> HddsConfServlet.writeResponse(getTestConf(), sw, "not a format", 
null));
-    assertEquals("", sw.toString());
-  }
-
   private String getResultWithCmd(OzoneConfiguration conf, String cmd)
       throws Exception {
     StringWriter sw = null;
@@ -198,13 +190,7 @@ private String getResultWithCmd(OzoneConfiguration conf, 
String cmd)
       when(response.getWriter()).thenReturn(pw);
       // response request
       service.doGet(request, response);
-      if (cmd.equals("illegal")) {
-        verify(response).sendError(
-            eq(HttpServletResponse.SC_NOT_FOUND),
-            eq("illegal is not a valid command."));
-      }
-      String result = sw.toString().trim();
-      return result;
+      return sw.toString().trim();
     } finally {
       if (sw != null) {
         sw.close();
@@ -263,11 +249,9 @@ private void verifyGetProperty(OzoneConfiguration conf, 
String format,
           }
         } else {
           // if property name is not empty, and it's not in configuration
-          // expect proper error code and error message is set to the response
-          verify(response)
-              .sendError(
-                  eq(HttpServletResponse.SC_NOT_FOUND),
-                  eq("Property " + propertyName + " not found"));
+          // expect proper error code and error message in response
+          verify(response).setStatus(eq(HttpServletResponse.SC_NOT_FOUND));
+          assertThat(result).contains("Property " + propertyName + " not 
found");
         }
       }
     } finally {
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestHttpServletUtils.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestHttpServletUtils.java
new file mode 100644
index 00000000000..46de47742f4
--- /dev/null
+++ 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestHttpServletUtils.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hdds.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import jakarta.annotation.Nullable;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.stream.Stream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.HttpHeaders;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class TestHttpServletUtils {
+  public static Stream<Arguments> provideGetResponseFormatTestCases() {
+    return Stream.of(
+        Arguments.of("text/plain", HttpServletUtils.ResponseFormat.XML),
+        Arguments.of(null, HttpServletUtils.ResponseFormat.UNSPECIFIED),
+        Arguments.of("text/xml", HttpServletUtils.ResponseFormat.XML),
+        Arguments.of("application/xml", HttpServletUtils.ResponseFormat.XML),
+        Arguments.of("application/json", HttpServletUtils.ResponseFormat.JSON)
+    );
+  }
+
+  @ParameterizedTest
+  @MethodSource("provideGetResponseFormatTestCases")
+  public void testGetResponseFormat(@Nullable String contentType,
+      HttpServletUtils.ResponseFormat expectResponseFormat) {
+    HttpServletRequest request = mock(HttpServletRequest.class);
+    when(request.getHeader(HttpHeaders.ACCEPT))
+        .thenReturn(contentType);
+    assertEquals(expectResponseFormat,
+        HttpServletUtils.getResponseFormat(request));
+  }
+
+  @Test
+  public void testWriteErrorResponseJson() throws Exception {
+    StringWriter sw = new StringWriter();
+    HttpServletResponse response = mock(HttpServletResponse.class);
+    when(response.getWriter()).thenReturn(new PrintWriter(sw));
+    
HttpServletUtils.writeErrorResponse(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
 "example error",
+        HttpServletUtils.ResponseFormat.JSON, response);
+    assertEquals("{\"error\":\"example error\"}", sw.toString());
+  }
+
+  @Test
+  public void testWriteErrorResponseXml() throws Exception {
+    StringWriter sw = new StringWriter();
+    HttpServletResponse response = mock(HttpServletResponse.class);
+    when(response.getWriter()).thenReturn(new PrintWriter(sw));
+    
HttpServletUtils.writeErrorResponse(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
 "example error",
+        HttpServletUtils.ResponseFormat.XML, response);
+    assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\" 
standalone=\"no\"?><error>example error</error>",
+        sw.toString());
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to