Add Content-Type header to AWScJson response and writer for servlet response
This commit is contained in:
@@ -19,6 +19,7 @@ package org.springframework.cloud.function.adapter.aws.web;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -77,7 +78,8 @@ public class WebProxyInvoker {
|
|||||||
logger.debug("httpMethod: " + httpMethod);
|
logger.debug("httpMethod: " + httpMethod);
|
||||||
logger.debug("path: " + path);
|
logger.debug("path: " + path);
|
||||||
}
|
}
|
||||||
ProxyHttpServletRequest httpRequest = new ProxyHttpServletRequest(null, httpMethod, path);
|
|
||||||
|
ProxyHttpServletRequest httpRequest = new ProxyHttpServletRequest(this.mvc.getServletContext(), httpMethod, path);
|
||||||
|
|
||||||
// CONTENT
|
// CONTENT
|
||||||
if (StringUtils.hasText((String) request.get("body"))) {
|
if (StringUtils.hasText((String) request.get("body"))) {
|
||||||
@@ -126,13 +128,14 @@ public class WebProxyInvoker {
|
|||||||
apiGatewayResponseStructure.put("isBase64Encoded", false);
|
apiGatewayResponseStructure.put("isBase64Encoded", false);
|
||||||
apiGatewayResponseStructure.put("statusCode", HttpStatus.OK.value());
|
apiGatewayResponseStructure.put("statusCode", HttpStatus.OK.value());
|
||||||
apiGatewayResponseStructure.put("body", responseString);
|
apiGatewayResponseStructure.put("body", responseString);
|
||||||
|
|
||||||
Map<String, List<String>> multiValueHeaders = new HashMap<>();
|
Map<String, List<String>> multiValueHeaders = new HashMap<>();
|
||||||
Map<String, String> headers = new HashMap<>();
|
Map<String, String> headers = new HashMap<>();
|
||||||
for (String headerName : httpResponse.getHeaderNames()) {
|
for (String headerName : httpResponse.getHeaderNames()) {
|
||||||
multiValueHeaders.put(headerName, httpResponse.getHeaders(headerName));
|
multiValueHeaders.put(headerName, httpResponse.getHeaders(headerName));
|
||||||
headers.put(headerName, httpResponse.getHeaders(headerName).toString());
|
headers.put(headerName, httpResponse.getHeaders(headerName).toString());
|
||||||
}
|
}
|
||||||
|
headers.put(HttpHeaders.CONTENT_TYPE, httpResponse.getContentType());
|
||||||
|
multiValueHeaders.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList(httpResponse.getContentType()));
|
||||||
apiGatewayResponseStructure.put("multiValueHeaders", multiValueHeaders);
|
apiGatewayResponseStructure.put("multiValueHeaders", multiValueHeaders);
|
||||||
apiGatewayResponseStructure.put("headers", headers);
|
apiGatewayResponseStructure.put("headers", headers);
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ package org.springframework.cloud.function.serverless.web;
|
|||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.io.Writer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -69,6 +71,8 @@ public class ProxyHttpServletResponse implements HttpServletResponse {
|
|||||||
|
|
||||||
private int status = HttpServletResponse.SC_OK;
|
private int status = HttpServletResponse.SC_OK;
|
||||||
|
|
||||||
|
private ResponsePrintWriter writer;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String errorMessage;
|
private String errorMessage;
|
||||||
|
|
||||||
@@ -89,7 +93,11 @@ public class ProxyHttpServletResponse implements HttpServletResponse {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrintWriter getWriter() throws UnsupportedEncodingException {
|
public PrintWriter getWriter() throws UnsupportedEncodingException {
|
||||||
throw new UnsupportedOperationException();
|
if (this.writer == null) {
|
||||||
|
Writer targetWriter = new OutputStreamWriter(this.content, getCharacterEncoding());
|
||||||
|
this.writer = new ResponsePrintWriter(targetWriter);
|
||||||
|
}
|
||||||
|
return this.writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getContentAsByteArray() {
|
public byte[] getContentAsByteArray() {
|
||||||
@@ -163,7 +171,7 @@ public class ProxyHttpServletResponse implements HttpServletResponse {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCommitted() {
|
public boolean isCommitted() {
|
||||||
return false;
|
return this.writer == null ? false : this.writer.commited;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -425,4 +433,47 @@ public class ProxyHttpServletResponse implements HttpServletResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ResponsePrintWriter extends PrintWriter {
|
||||||
|
|
||||||
|
private boolean commited;
|
||||||
|
|
||||||
|
ResponsePrintWriter(Writer out) {
|
||||||
|
super(out, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(char[] buf, int off, int len) {
|
||||||
|
super.write(buf, off, len);
|
||||||
|
super.flush();
|
||||||
|
this.commited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(String s, int off, int len) {
|
||||||
|
super.write(s, off, len);
|
||||||
|
super.flush();
|
||||||
|
this.commited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int c) {
|
||||||
|
super.write(c);
|
||||||
|
super.flush();
|
||||||
|
this.commited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() {
|
||||||
|
super.flush();
|
||||||
|
this.commited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
super.flush();
|
||||||
|
super.close();
|
||||||
|
this.commited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,14 +41,13 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
|
||||||
import org.springframework.web.servlet.DispatcherServlet;
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,11 +84,8 @@ public class ProxyMvc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ProxyMvc INSTANCE(Class<?>... componentClasses) {
|
public static ProxyMvc INSTANCE(Class<?>... componentClasses) {
|
||||||
GenericWebApplicationContext applpicationContext = new GenericWebApplicationContext();
|
AnnotationConfigServletWebApplicationContext applpicationContext = new AnnotationConfigServletWebApplicationContext();
|
||||||
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(applpicationContext);
|
applpicationContext.scan(componentClasses[0].getPackageName());
|
||||||
if (!ObjectUtils.isEmpty(componentClasses)) {
|
|
||||||
reader.register(componentClasses);
|
|
||||||
}
|
|
||||||
return INSTANCE(applpicationContext);
|
return INSTANCE(applpicationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,10 +104,17 @@ public class ProxyMvc {
|
|||||||
reg.setLoadOnStartup(1);
|
reg.setLoadOnStartup(1);
|
||||||
this.servletContext = applicationContext.getServletContext();
|
this.servletContext = applicationContext.getServletContext();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
this.dispatcher.init(new ProxyServletConfig(this.servletContext));
|
this.dispatcher.init(new ProxyServletConfig(this.servletContext));
|
||||||
|
try {
|
||||||
|
this.service(new ProxyHttpServletRequest(servletContext, "INFO", "/"), new ProxyHttpServletResponse());
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
//ignore as this is just a pre-warming attempt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException("Faild to create Spring MVC DispatcherServlet proxy", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +165,7 @@ public class ProxyMvc {
|
|||||||
*
|
*
|
||||||
* @param servlet the {@link Servlet} to invoke in this {@link FilterChain}
|
* @param servlet the {@link Servlet} to invoke in this {@link FilterChain}
|
||||||
* @param filters the {@link Filter}'s to invoke in this {@link FilterChain}
|
* @param filters the {@link Filter}'s to invoke in this {@link FilterChain}
|
||||||
* @since 3.2
|
* @since 4.0.x
|
||||||
*/
|
*/
|
||||||
ProxyFilterChain(DispatcherServlet servlet) {
|
ProxyFilterChain(DispatcherServlet servlet) {
|
||||||
List<Filter> filters = new ArrayList<>();
|
List<Filter> filters = new ArrayList<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user