有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何修改http头(如果已设置)?

我需要根据页面内容修改此标题

这是一个精心设计的例子,因为它是被要求的。我无法深入了解特定标题的详细信息 servlet/页面根据访问的后端系统设置一个标题specialheader=xyz。如果设置了此特殊标题,则过滤器会将其修改为xyz+abc。如果未设置标题,则过滤器将其设置为123

我可以使用一个过滤器来创建一个包装的HttpServletResponse,并在返回的过程中对其进行修改。不过,我对细节不太清楚

我知道在我的过滤器完成它的工作之前,我必须防止输出被发送回客户端。为了做到这一点,我是否需要将它传递给我自己的OutputStream并缓冲输出

我真的需要这样做吗?我是否可以避免缓冲可能会给服务器带来负载的输出

基本问题是-如果我需要在doFilter调用之后修改头部,我需要做的最小值是什么? 是否有其他方法可以防止提交输出,例如过度刷新等


共 (2) 个答案

  1. # 1 楼答案

    只需实现getHeader和getHeaderNames就可以忽略要丢弃的头,并将包装器设置为过滤器

    import java.io.ByteArrayOutputStream;
    import java.io.PrintWriter;
    import java.util.Collection;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpServletResponseWrapper;
    
    public class GenericResponseWrapper extends HttpServletResponseWrapper {
    
    
    
        public GenericResponseWrapper(final HttpServletResponse response) {
            super(response);    
        }
    
        @Override
        public String getHeader(String name) {
            // TODO Auto-generated method stub
            return super.getHeader(name);
        }
        @Override
        public Collection<String> getHeaderNames() {
            // TODO Auto-generated method stub
            return super.getHeaderNames();
        }
    }
    
    
    public class Wrapper implements Filter {
    
        @Override
        public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
            final HttpServletRequest httpRequest = (HttpServletRequest) request;
            final HttpServletResponse httpResponse = (HttpServletResponse) response;
                final GenericResponseWrapper wrapper = new GenericResponseWrapper(httpResponse);
                wrapper.getResponse().setCharacterEncoding("UTF-8");
    
                chain.doFilter(request, wrapper);
    }
    }
    
  2. # 2 楼答案

    每当我搜索“如何修改已设置的servlet响应中的标题”时,这篇帖子会首先出现,即使问题描述不同,我(可能和其他许多人一样)也想知道如何修改已设置的servlet响应中的标题。在这方面,我想为那些正在寻找答案的人发布我的答案(而不是写一个问题/答案)

    public class SameSiteCookieHeaderFilter implements Filter {
    
    
    private static final String LOCALE_ID_COOKIE = "locale";
    
    
    private static final String SET_COOKIE_HEADER = "Set-Cookie";
    
    @Override
    public void destroy() {
    }
    
    @Override
    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
                         final FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        final HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        final Collection<String> setCookieHeaders = httpServletResponse.getHeaders(SET_COOKIE_HEADER);
    
        for (final String setCookieHeader : setCookieHeaders) {
            httpServletResponse.addHeader(SET_COOKIE_HEADER, setCookieHeader + "; Secure; SameSite=None");
        }
    
        if (setCookieHeaders.size() == 0) {
            final Cookie[] cookies = httpServletRequest.getCookies();
    
            for (final Cookie cookie : cookies) {
                if (cookie.getName().equals(LOCALE_ID_COOKIE)) {
                    httpServletResponse.addHeader(SET_COOKIE_HEADER, buildSessionIdCookie(cookie.getValue()));
                }
            }
        }
    
        filterChain.doFilter(servletRequest, servletResponse);
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    
    
    private String buildSessionIdCookie(final String value) {
        return LOCALE_ID_COOKIE + "=" + value + "; " + "Path=/; " + "SameSite=None; " + "Secure; HttpOnly;";
    }
    

    网络。xml

    <filter>
        <filter-name>SameSiteCookieHeaderFilter</filter-name>
        <filter-class>de.chemmedia.kw.core.filter.SameSiteCookieHeaderFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SameSiteCookieHeaderFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    

    因此,它检测Set-Cookie头并添加SameSite=None属性,或者获取Cookie并在每个响应中使用SameSite=None构造Set-Cookie。这样,将有两个具有相同值的Set-Cookie头,第二个将覆盖前一个,**或修改响应中已经存在的**头

    Set-Cookie: locale=EN; Path=/; HttpOnly;
    Set-Cookie: locale=EN; Path=/; SameSite=None; Secure; HttpOnly;
    

    仅供参考:tomcat 7.0.104、Servlet 3.1和Spring 4.2。x