update tomcat to 11 and remove javax.servlet

This commit is contained in:
Looly
2025-04-17 17:15:05 +08:00
parent 869b82b8d0
commit 1b54272ea8
5 changed files with 4 additions and 858 deletions

View File

@@ -34,13 +34,12 @@
<properties>
<Automatic-Module-Name>cn.hutool.v7.http</Automatic-Module-Name>
<httpclient5.version>5.4.1</httpclient5.version>
<httpclient5.version>5.4.3</httpclient5.version>
<httpclient4.version>4.5.14</httpclient4.version>
<okhttp.version>4.12.0</okhttp.version>
<undertow.version>2.3.18.Final</undertow.version>
<jetty.version>12.0.19</jetty.version>
<!-- 固定 9.x支持到JDK8 -->
<tomcat.version>9.0.97</tomcat.version>
<tomcat.version>11.0.6</tomcat.version>
<smartboot.version>1.4.3</smartboot.version>
</properties>

View File

@@ -1,91 +0,0 @@
/*
* Copyright (c) 2013-2025 Hutool Team and hutool.cn
*
* Licensed 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 cn.hutool.v7.http.server.servlet;
import cn.hutool.v7.http.server.handler.ServerRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
/**
* Javax Servlet请求对象包装
*
* @author Looly
*/
public class JavaxServletRequest implements ServerRequest {
private final HttpServletRequest request;
/**
* 构造
*
* @param request Jetty请求对象
*/
public JavaxServletRequest(final HttpServletRequest request) {
this.request = request;
}
@Override
public String getMethod() {
return this.request.getMethod();
}
@Override
public String getPath() {
return this.request.getContextPath();
}
@Override
public String getQuery() {
return this.request.getQueryString();
}
/**
* 获取所有请求头
*
* @return 请求头Map
*/
public Map<String, String> getHeaderMap(){
return JavaxServletUtil.getHeaderMap(this.request);
}
/**
* 获取所有请求头,包括多个相同名称的请求头
*
* @return 请求头Map
*/
public Map<String, List<String>> getHeadersMap(){
return JavaxServletUtil.getHeadersMap(this.request);
}
@Override
public String getHeader(final String name) {
return this.request.getHeader(name);
}
@Override
public InputStream getBodyStream() {
try {
return this.request.getInputStream();
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright (c) 2013-2025 Hutool Team and hutool.cn
*
* Licensed 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 cn.hutool.v7.http.server.servlet;
import cn.hutool.v7.core.io.IORuntimeException;
import cn.hutool.v7.http.server.handler.ServerResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
/**
* Javax Jetty响应对象包装
*
* @author Looly
*/
public class JavaxServletResponse implements ServerResponse {
private final HttpServletResponse response;
private Charset charset;
/**
* 构造
*
* @param response Jetty响应对象
*/
public JavaxServletResponse(final HttpServletResponse response) {
this.response = response;
}
@Override
public JavaxServletResponse setStatus(final int statusCode) {
this.response.setStatus(statusCode);
return this;
}
@Override
public JavaxServletResponse setCharset(final Charset charset) {
this.charset = charset;
return this;
}
@Override
public Charset getCharset() {
return this.charset;
}
@Override
public JavaxServletResponse addHeader(final String header, final String value) {
this.response.addHeader(header, value);
return this;
}
@Override
public JavaxServletResponse setHeader(final String header, final String value) {
this.response.setHeader(header, value);
return this;
}
/**
* 增加Cookie
*
* @param cookie Cookie对象
* @return this
*/
public JavaxServletResponse addCookie(final Cookie cookie){
JavaxServletUtil.addCookie(this.response, cookie);
return this;
}
@Override
public OutputStream getOutputStream() {
try {
return this.response.getOutputStream();
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
}

View File

@@ -1,667 +0,0 @@
/*
* Copyright (c) 2013-2025 Hutool Team and hutool.cn
*
* Licensed 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 cn.hutool.v7.http.server.servlet;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.hutool.v7.core.array.ArrayUtil;
import cn.hutool.v7.core.bean.BeanUtil;
import cn.hutool.v7.core.bean.copier.CopyOptions;
import cn.hutool.v7.core.bean.copier.ValueProvider;
import cn.hutool.v7.core.collection.ListUtil;
import cn.hutool.v7.core.collection.iter.ArrayIter;
import cn.hutool.v7.core.exception.HutoolException;
import cn.hutool.v7.core.io.IORuntimeException;
import cn.hutool.v7.core.io.IoUtil;
import cn.hutool.v7.core.io.file.FileUtil;
import cn.hutool.v7.core.map.CaseInsensitiveMap;
import cn.hutool.v7.core.map.MapUtil;
import cn.hutool.v7.core.net.NetUtil;
import cn.hutool.v7.http.multipart.MultipartFormData;
import cn.hutool.v7.http.multipart.UploadSetting;
import cn.hutool.v7.core.net.url.UrlEncoder;
import cn.hutool.v7.core.reflect.ConstructorUtil;
import cn.hutool.v7.core.text.StrUtil;
import cn.hutool.v7.core.util.CharsetUtil;
import cn.hutool.v7.core.util.ObjUtil;
import cn.hutool.v7.http.meta.Method;
import java.io.*;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.*;
/**
* javax.Servlet相关工具类封装
*
* @author Looly
* @since 3.2.0
*/
public class JavaxServletUtil {
// --------------------------------------------------------- getParam start
/**
* 获得所有请求参数
*
* @param request 请求对象{@link ServletRequest}
* @return Map
*/
public static Map<String, String[]> getParams(final ServletRequest request) {
final Map<String, String[]> map = request.getParameterMap();
return Collections.unmodifiableMap(map);
}
/**
* 获得所有请求参数
*
* @param request 请求对象{@link ServletRequest}
* @return Map
*/
public static Map<String, String> getParamMap(final ServletRequest request) {
final Map<String, String> params = new HashMap<>();
for (final Map.Entry<String, String[]> entry : getParams(request).entrySet()) {
params.put(entry.getKey(), ArrayUtil.join(entry.getValue(), StrUtil.COMMA));
}
return params;
}
/**
* 获取请求体<br>
* 调用该方法后getParam方法将失效
*
* @param request {@link ServletRequest}
* @return 获得请求体
* @since 4.0.2
*/
public static String getBody(final ServletRequest request) {
try (final BufferedReader reader = request.getReader()) {
return IoUtil.read(reader);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
/**
* 获取请求体byte[]<br>
* 调用该方法后getParam方法将失效
*
* @param request {@link ServletRequest}
* @return 获得请求体byte[]
* @since 4.0.2
*/
public static byte[] getBodyBytes(final ServletRequest request) {
try {
return IoUtil.readBytes(request.getInputStream());
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
// --------------------------------------------------------- getParam end
// --------------------------------------------------------- fillBean start
/**
* ServletRequest 参数转Bean
*
* @param <T> Bean类型
* @param request ServletRequest
* @param bean Bean
* @param copyOptions 注入时的设置
* @return Bean
* @since 3.0.4
*/
public static <T> T fillBean(final ServletRequest request, final T bean, final CopyOptions copyOptions) {
final String beanName = StrUtil.lowerFirst(bean.getClass().getSimpleName());
return BeanUtil.fillBean(bean, new ValueProvider<String>() {
@Override
public Object value(final String key, final Type valueType) {
String[] values = request.getParameterValues(key);
if (ArrayUtil.isEmpty(values)) {
values = request.getParameterValues(beanName + StrUtil.DOT + key);
if (ArrayUtil.isEmpty(values)) {
return null;
}
}
if (1 == values.length) {
// 单值表单直接返回这个值
return values[0];
} else {
// 多值表单返回数组
return values;
}
}
@Override
public boolean containsKey(final String key) {
// 对于Servlet来说返回值null意味着无此参数
return (null != request.getParameter(key)) || (null != request.getParameter(beanName + StrUtil.DOT + key));
}
}, copyOptions);
}
/**
* ServletRequest 参数转Bean
*
* @param <T> Bean类型
* @param request {@link ServletRequest}
* @param bean Bean
* @param isIgnoreError 是否忽略注入错误
* @return Bean
*/
public static <T> T fillBean(final ServletRequest request, final T bean, final boolean isIgnoreError) {
return fillBean(request, bean, CopyOptions.of().setIgnoreError(isIgnoreError));
}
/**
* ServletRequest 参数转Bean
*
* @param <T> Bean类型
* @param request ServletRequest
* @param beanClass Bean Class
* @param isIgnoreError 是否忽略注入错误
* @return Bean
*/
public static <T> T toBean(final ServletRequest request, final Class<T> beanClass, final boolean isIgnoreError) {
return fillBean(request, ConstructorUtil.newInstanceIfPossible(beanClass), isIgnoreError);
}
// --------------------------------------------------------- fillBean end
/**
* 获取客户端IP
*
* <p>
* 默认检测的Header:
*
* <pre>
* 1、X-Forwarded-For
* 2、X-Real-IP
* 3、Proxy-Client-IP
* 4、WL-Proxy-Client-IP
* </pre>
*
* <p>
* otherHeaderNames参数用于自定义检测的Header<br>
* 需要注意的是使用此方法获取的客户IP地址必须在Http服务器例如Nginx中配置头信息否则容易造成IP伪造。
* </p>
*
* @param request 请求对象{@link HttpServletRequest}
* @param otherHeaderNames 其他自定义头文件通常在Http服务器例如Nginx中配置
* @return IP地址
*/
public static String getClientIP(final HttpServletRequest request, final String... otherHeaderNames) {
String[] headers = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
if (ArrayUtil.isNotEmpty(otherHeaderNames)) {
headers = ArrayUtil.addAll(headers, otherHeaderNames);
}
return getClientIPByHeader(request, headers);
}
/**
* 获取客户端IP
*
* <p>
* headerNames参数用于自定义检测的Header<br>
* 需要注意的是使用此方法获取的客户IP地址必须在Http服务器例如Nginx中配置头信息否则容易造成IP伪造。
* </p>
*
* @param request 请求对象{@link HttpServletRequest}
* @param headerNames 自定义头通常在Http服务器例如Nginx中配置
* @return IP地址
* @since 4.4.1
*/
public static String getClientIPByHeader(final HttpServletRequest request, final String... headerNames) {
String ip;
for (final String header : headerNames) {
ip = request.getHeader(header);
if (!NetUtil.isUnknown(ip)) {
return NetUtil.getMultistageReverseProxyIp(ip);
}
}
ip = request.getRemoteAddr();
return NetUtil.getMultistageReverseProxyIp(ip);
}
/**
* 获得MultiPart表单内容多用于获得上传的文件 在同一次请求中,此方法只能被执行一次!
*
* @param request {@link ServletRequest}
* @return MultipartFormData
* @throws IORuntimeException IO异常
* @since 4.0.2
*/
public static MultipartFormData getMultipart(final ServletRequest request) throws IORuntimeException {
return getMultipart(request, new UploadSetting());
}
/**
* 获得multipart/form-data 表单内容<br>
* 包括文件和普通表单数据<br>
* 在同一次请求中,此方法只能被执行一次!
*
* @param request {@link ServletRequest}
* @param uploadSetting 上传文件的设定,包括最大文件大小、保存在内存的边界大小、临时目录、扩展名限定等
* @return MultiPart表单
* @throws IORuntimeException IO异常
* @since 4.0.2
*/
public static MultipartFormData getMultipart(final ServletRequest request, final UploadSetting uploadSetting) throws IORuntimeException {
final MultipartFormData formData = new MultipartFormData(uploadSetting);
try {
formData.parseRequestStream(request.getInputStream(), CharsetUtil.charset(request.getCharacterEncoding()));
} catch (final IOException e) {
throw new IORuntimeException(e);
}
return formData;
}
// --------------------------------------------------------- Header start
/**
* 获取请求所有的头header信息
*
* @param request 请求对象{@link HttpServletRequest}
* @return header值
* @since 4.6.2
*/
public static Map<String, String> getHeaderMap(final HttpServletRequest request) {
final Map<String, String> headerMap = new HashMap<>();
final Enumeration<String> names = request.getHeaderNames();
String name;
while (names.hasMoreElements()) {
name = names.nextElement();
headerMap.put(name, request.getHeader(name));
}
return headerMap;
}
/**
* 获取请求所有的头header信息
*
* @param request 请求对象{@link HttpServletRequest}
* @return header值
* @since 6.0.0
*/
public static Map<String, List<String>> getHeadersMap(final HttpServletRequest request) {
final Map<String, List<String>> headerMap = new LinkedHashMap<>();
final Enumeration<String> names = request.getHeaderNames();
String name;
while (names.hasMoreElements()) {
name = names.nextElement();
headerMap.put(name, ListUtil.of(request.getHeaders(name)));
}
return headerMap;
}
/**
* 获取响应所有的头header信息
*
* @param response 响应对象{@link HttpServletResponse}
* @return header值
*/
public static Map<String, Collection<String>> getHeadersMap(final HttpServletResponse response) {
final Map<String, Collection<String>> headerMap = new HashMap<>();
final Collection<String> names = response.getHeaderNames();
for (final String name : names) {
headerMap.put(name, response.getHeaders(name));
}
return headerMap;
}
/**
* 忽略大小写获得请求header中的信息
*
* @param request 请求对象{@link HttpServletRequest}
* @param nameIgnoreCase 忽略大小写头信息的KEY
* @return header值
*/
public static String getHeaderIgnoreCase(final HttpServletRequest request, final String nameIgnoreCase) {
final Enumeration<String> names = request.getHeaderNames();
String name;
while (names.hasMoreElements()) {
name = names.nextElement();
if (name != null && name.equalsIgnoreCase(nameIgnoreCase)) {
return request.getHeader(name);
}
}
return null;
}
/**
* 获得请求header中的信息
*
* @param request 请求对象{@link HttpServletRequest}
* @param name 头信息的KEY
* @param charset 字符集
* @return header值
* @since 4.6.2
*/
public static String getHeader(final HttpServletRequest request, final String name, final Charset charset) {
final String header = request.getHeader(name);
if (null != header) {
return CharsetUtil.convert(header, CharsetUtil.ISO_8859_1, charset);
}
return null;
}
/**
* 客户浏览器是否为IE
*
* @param request 请求对象{@link HttpServletRequest}
* @return 客户浏览器是否为IE
*/
public static boolean isIE(final HttpServletRequest request) {
String userAgent = getHeaderIgnoreCase(request, "User-Agent");
if (StrUtil.isNotBlank(userAgent)) {
userAgent = userAgent.toUpperCase();
return userAgent.contains("MSIE") || userAgent.contains("TRIDENT");
}
return false;
}
/**
* 是否为GET请求
*
* @param request 请求对象{@link HttpServletRequest}
* @return 是否为GET请求
*/
public static boolean isGetMethod(final HttpServletRequest request) {
return Method.GET.name().equalsIgnoreCase(request.getMethod());
}
/**
* 是否为POST请求
*
* @param request 请求对象{@link HttpServletRequest}
* @return 是否为POST请求
*/
public static boolean isPostMethod(final HttpServletRequest request) {
return Method.POST.name().equalsIgnoreCase(request.getMethod());
}
/**
* 是否为Multipart类型表单此类型表单用于文件上传
*
* @param request 请求对象{@link HttpServletRequest}
* @return 是否为Multipart类型表单此类型表单用于文件上传
*/
public static boolean isMultipart(final HttpServletRequest request) {
if (!isPostMethod(request)) {
return false;
}
final String contentType = request.getContentType();
if (StrUtil.isBlank(contentType)) {
return false;
}
return contentType.toLowerCase().startsWith("multipart/");
}
// --------------------------------------------------------- Header end
// --------------------------------------------------------- Cookie start
/**
* 获得指定的Cookie
*
* @param httpServletRequest {@link HttpServletRequest}
* @param name cookie名
* @return Cookie对象
*/
public static Cookie getCookie(final HttpServletRequest httpServletRequest, final String name) {
return readCookieMap(httpServletRequest).get(name);
}
/**
* 将cookie封装到Map里面
*
* @param httpServletRequest {@link HttpServletRequest}
* @return Cookie map
*/
public static Map<String, Cookie> readCookieMap(final HttpServletRequest httpServletRequest) {
final Cookie[] cookies = httpServletRequest.getCookies();
if (ArrayUtil.isEmpty(cookies)) {
return MapUtil.empty();
}
return MapUtil.putAll(
new CaseInsensitiveMap<>(),
(Iterator<Cookie>) new ArrayIter<>(httpServletRequest.getCookies()),
Cookie::getName);
}
/**
* 设定返回给客户端的Cookie
*
* @param response 响应对象{@link HttpServletResponse}
* @param cookie Servlet Cookie对象
*/
public static void addCookie(final HttpServletResponse response, final Cookie cookie) {
response.addCookie(cookie);
}
/**
* 设定返回给客户端的Cookie
*
* @param response 响应对象{@link HttpServletResponse}
* @param name Cookie名
* @param value Cookie值
*/
public static void addCookie(final HttpServletResponse response, final String name, final String value) {
response.addCookie(new Cookie(name, value));
}
/**
* 设定返回给客户端的Cookie
*
* @param response 响应对象{@link HttpServletResponse}
* @param name cookie名
* @param value cookie值
* @param maxAgeInSeconds -1: 关闭浏览器清除Cookie. 0: 立即清除Cookie. &gt;0 : Cookie存在的秒数.
* @param path Cookie的有效路径
* @param domain the domain name within which this cookie is visible; form is according to RFC 2109
*/
public static void addCookie(final HttpServletResponse response, final String name, final String value, final int maxAgeInSeconds, final String path, final String domain) {
final Cookie cookie = new Cookie(name, value);
if (domain != null) {
cookie.setDomain(domain);
}
cookie.setMaxAge(maxAgeInSeconds);
cookie.setPath(path);
addCookie(response, cookie);
}
/**
* 设定返回给客户端的Cookie<br>
* Path: "/"<br>
* No Domain
*
* @param response 响应对象{@link HttpServletResponse}
* @param name cookie名
* @param value cookie值
* @param maxAgeInSeconds -1: 关闭浏览器清除Cookie. 0: 立即清除Cookie. &gt;0 : Cookie存在的秒数.
*/
public static void addCookie(final HttpServletResponse response, final String name, final String value, final int maxAgeInSeconds) {
addCookie(response, name, value, maxAgeInSeconds, "/", null);
}
// --------------------------------------------------------- Cookie end
// --------------------------------------------------------- Response start
/**
* 获得PrintWriter
*
* @param response 响应对象{@link HttpServletResponse}
* @return 获得PrintWriter
* @throws IORuntimeException IO异常
*/
public static PrintWriter getWriter(final HttpServletResponse response) throws IORuntimeException {
try {
return response.getWriter();
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
/**
* 返回数据给客户端
*
* @param response 响应对象{@link HttpServletResponse}
* @param text 返回的内容
* @param contentType 返回的类型
*/
public static void write(final HttpServletResponse response, final String text, final String contentType) {
response.setContentType(contentType);
Writer writer = null;
try {
writer = response.getWriter();
writer.write(text);
writer.flush();
} catch (final IOException e) {
throw new IORuntimeException(e);
} finally {
IoUtil.closeQuietly(writer);
}
}
/**
* 返回文件给客户端
*
* @param response 响应对象{@link HttpServletResponse}
* @param file 写出的文件对象
* @since 4.1.15
*/
public static void write(final HttpServletResponse response, final File file) {
final String fileName = file.getName();
final String contentType = ObjUtil.defaultIfNull(FileUtil.getMimeType(fileName), "application/octet-stream");
BufferedInputStream in = null;
try {
in = FileUtil.getInputStream(file);
write(response, in, contentType, fileName);
} finally {
IoUtil.closeQuietly(in);
}
}
/**
* 返回数据给客户端
*
* @param response 响应对象{@link HttpServletResponse}
* @param in 需要返回客户端的内容
* @param contentType 返回的类型,可以使用{@link FileUtil#getMimeType(String)}获取对应扩展名的MIME信息
* <ul>
* <li>application/pdf</li>
* <li>application/vnd.ms-excel</li>
* <li>application/msword</li>
* <li>application/vnd.ms-powerpoint</li>
* </ul>
* docx、xlsx 这种 office 2007 格式 设置 MIME;网页里面docx 文件是没问题但是下载下来了之后就变成doc格式了
* 参考:<a href="https://my.oschina.net/shixiaobao17145/blog/32489">https://my.oschina.net/shixiaobao17145/blog/32489</a>
* <ul>
* <li>MIME_EXCELX_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";</li>
* <li>MIME_PPTX_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";</li>
* <li>MIME_WORDX_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";</li>
* <li>MIME_STREAM_TYPE = "application/octet-stream;charset=utf-8"; #原始字节流</li>
* </ul>
* @param fileName 文件名,自动添加双引号
* @since 4.1.15
*/
public static void write(final HttpServletResponse response, final InputStream in, final String contentType, final String fileName) {
final String charset = ObjUtil.defaultIfNull(response.getCharacterEncoding(), CharsetUtil.NAME_UTF_8);
final String encodeText = UrlEncoder.encodeAll(fileName, CharsetUtil.charset(charset));
response.setHeader("Content-Disposition",
StrUtil.format("attachment;filename=\"{}\";filename*={}''{}", encodeText, charset, encodeText));
response.setContentType(contentType);
write(response, in);
}
/**
* 返回数据给客户端
*
* @param response 响应对象{@link HttpServletResponse}
* @param in 需要返回客户端的内容
* @param contentType 返回的类型
*/
public static void write(final HttpServletResponse response, final InputStream in, final String contentType) {
response.setContentType(contentType);
write(response, in);
}
/**
* 返回数据给客户端
*
* @param response 响应对象{@link HttpServletResponse}
* @param in 需要返回客户端的内容
*/
public static void write(final HttpServletResponse response, final InputStream in) {
write(response, in, IoUtil.DEFAULT_BUFFER_SIZE);
}
/**
* 返回数据给客户端
*
* @param response 响应对象{@link HttpServletResponse}
* @param in 需要返回客户端的内容
* @param bufferSize 缓存大小
*/
public static void write(final HttpServletResponse response, final InputStream in, final int bufferSize) {
ServletOutputStream out = null;
try {
out = response.getOutputStream();
IoUtil.copy(in, out, bufferSize);
} catch (final IOException e) {
throw new HutoolException(e);
} finally {
IoUtil.closeQuietly(out);
IoUtil.closeQuietly(in);
}
}
/**
* 设置响应的Header
*
* @param response 响应对象{@link HttpServletResponse}
* @param name 名
* @param value 值可以是StringDate int
*/
public static void setHeader(final HttpServletResponse response, final String name, final Object value) {
if (value instanceof String) {
response.setHeader(name, (String) value);
} else if (Date.class.isAssignableFrom(value.getClass())) {
response.setDateHeader(name, ((Date) value).getTime());
} else if (value instanceof Integer || "int".equalsIgnoreCase(value.getClass().getSimpleName())) {
response.setIntHeader(name, (int) value);
} else {
response.setHeader(name, value.toString());
}
}
// --------------------------------------------------------- Response end
}

View File

@@ -35,7 +35,7 @@
<properties>
<Automatic-Module-Name>cn.hutool.v7.poi</Automatic-Module-Name>
<!-- versions -->
<poi.version>5.3.0</poi.version>
<poi.version>5.4.1</poi.version>
<log4j2.version>2.20.0</log4j2.version>
</properties>
@@ -58,7 +58,7 @@
<dependency>
<groupId>org.ofdrw</groupId>
<artifactId>ofdrw-full</artifactId>
<version>2.3.4</version>
<version>2.3.6</version>
<scope>compile</scope>
<exclusions>
<exclusion>