将 UTF-8 字符集添加到 Spring Boot 中的响应标头

add UTF-8 charset to to response headers in spring boot

提问人:Mohammad 提问时间:11/15/2023 更新时间:11/15/2023 访问量:25

问:

我有一个spring boot应用程序,它以各种形式发送和接收数据,例如application/json,application/xml,application/x-www-form-urlencoded,...。

我想编写一个自定义过滤器来将 UTF-8 字符集设置为响应标头。但是我只想将其应用于contentType标头设置为“application/json”的响应。

我怎样才能实现这个目标?

我试图将以下内容添加到application.yml中:

server:
  servlet:
    encoding:
      charset: UTF-8
      force-response: true

但我怀疑它是否适用于所有响应(不仅仅是“application/json”响应)。

到目前为止,我做的另一件事是编写一个过滤器:

public class CharEncodingFilter extends CharacterEncodingFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {

        filterChain.doFilter(request , response);

        if (response.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) {
            String encoding = getEncoding();
            if (encoding != null) {
                if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {
                    request.setCharacterEncoding(encoding);
                }
                if (isForceResponseEncoding()) {
                    response.setCharacterEncoding(encoding);
                }
            }
            filterChain.doFilter(request, response);
        }

    }

}

但它无法满足我的请求,因为为 null,if 语句将产生 nullPointerException :(。response.getContentType()

我知道在应用程序中的某个地方,contentType 是通过 springboot 为响应设置的,我想在那之后立即添加 UTF-8 编码字符集标头。

P.S:我想要一个全球解决方案。我知道单独设置每个控制器方法的响应类型是适用的,但是修复所有控制器很耗时。 谢谢。

java 的spring-mvc

评论


答:

-1赞 smeds 11/15/2023 #1

创建自定义过滤器的正确轨道。但是,您面临的问题是,在执行控制器方法之前,不会设置响应的内容类型。因此,当筛选器检查内容类型时,它仍为 null。

若要解决此问题,可以为 并重写该方法创建一个包装器。在此方法中,您可以检查所设置的内容类型是否为“”,如果是,则将字符集添加到响应标头中。HttpServletResponsesetContentTypeapplication/json

下面是如何做到这一点的示例:

public class CharEncodingFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response) {
            @Override
            public void setContentType(String type) {
                if (MediaType.APPLICATION_JSON_VALUE.equals(type)) {
                    super.setContentType(type + ";charset=UTF-8");
                } else {
                    super.setContentType(type);
                }
            }
        };
        filterChain.doFilter(request, responseWrapper);
    }
}

在此代码中,是 Spring 提供的一种过滤器,用于确保每个请求仅应用一次过滤器。在 responseWrapper 上调用该方法时,它会检查类型是否为 “”。如果是,则使用 UTF-8 字符集设置内容类型。否则,它将像往常一样设置内容类型。OncePerRequestFiltersetContentTypeapplication/json

请记住在配置中注册此过滤器:

@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean<CharEncodingFilter> charEncodingFilter() {
        FilterRegistrationBean<CharEncodingFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new CharEncodingFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}