我有一个扩展block
类的类,它看起来像:
*block
问题是我可以向Filter
添加自定义@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
System.out.println("--------------------------------------");
HttpServletRequest request = (HttpServletRequest) req;
req.setAttribute("test", "test");
final HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
response.setHeader("Access-Control-Max-Age", "3600");
if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
吗?我浏览了header
和request
中可用的所有方法,但找不到任何方法。但是在request
模式下,我发现req
内部是debug
的列表。如何添加我的自定义CoyoteRequest
?
答案 0 :(得分:2)
您无法在HttpServletRequest
对象中设置标题,但可以使用包装类。
请参阅本指南:http://wilddiary.com/adding-custom-headers-java-httpservletrequest/
答案 1 :(得分:1)
我遵循了 Guy Smorodinsky 的回答,它对我有用,但我不得不向 MutableHttpServletRequest 添加另一个方法:
@Override
public Enumeration<String> getHeaders(String name) {
Set<String> set = new HashSet<>();
Optional.ofNullable(customHeaders.get(name)).ifPresent(h -> set.add(h));
Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaders(name);
while (e.hasMoreElements()) {
// add the names of the request headers into the list
String n = e.nextElement();
set.add(n);
}
Optional.ofNullable(customHeaders.get(name)).ifPresent(h -> set.add(h));
return Collections.enumeration(set);
}
答案 2 :(得分:0)
Guy Smorodinsky的答案还可以,但是例如对于Spring,您可能想覆盖一些其他方法,例如Enumeration<String> getHeaders(String name)
,因为Spring在获取带有@RequestHeader
批注的标头值时会使用此方法。
示例代码可能如下所示:
@Override
public Enumeration<String> getHeaders(String name) {
Set<String> headerValues = new HashSet<>();
headerValues.add(this.headers.get(name));
Enumeration<String> underlyingHeaderValues = ((HttpServletRequest) getRequest()).getHeaders(name);
while (underlyingHeaderValues.hasMoreElements()) {
headerValues.add(underlyingHeaderValues.nextElement());
}
return Collections.enumeration(headerValues);
}
答案 3 :(得分:0)
示例如何在春季通过过滤器将OAuth2Authentication的值中的用户名设置为自定义标头X-Login,并在控制器中将其用作参数@RequestHeader(X_LOGIN) String login
import static java.util.Collections.enumeration;
import static java.util.Collections.singleton;
@Component
public class HeaderLoginFilter extends GenericFilterBean {
public static final String X_LOGIN = "X-Login";
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
OAuth2Authentication auth = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
if (auth.getUserAuthentication() == null) {
//ignore, header value is set in my case
chain.doFilter(request, response);
return;
}
//filling custom header with value from auth
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper((HttpServletRequest) request) {
@Override
public Enumeration<String> getHeaders(String name) {
if (X_CLIENT_LOGIN.equals(name))
return enumeration(singleton(auth
.getUserAuthentication()
.getName()));
return super.getHeaders(name);
}
};
chain.doFilter(wrapper, response);
}
}
答案 4 :(得分:0)
我在实现REST Client with Quarkus时遇到类似的问题,ClientRequestFilter对此问题进行了解决
@Provider
public class AddAuthHeadersRequestFilter implements ClientRequestFilter {
private static final Logger LOG = Logger.getLogger(AddAuthHeadersRequestFilter.class);
@Override
public void filter(ClientRequestContext context) throws IOException {
context.getHeaders().add("Authorization", "Bearer XXXXXXXXXXX");
}
}
答案 5 :(得分:0)
如果出于任何原因添加新的过滤器或拦截器不是一种选择,反射和丑陋的代码是可以的。您可以执行以下操作以在控制器方法的主体中以编程方式修改现有标头:
<块引用>警告!这很丑陋,绝对不应该在生产中使用!
private void modifyHeaders(HttpServletRequest request, String headerToFind, String valueToReplace) {
Field field = request.getHeaderNames().getClass().getDeclaredField("val$names");
field.setAccessible(true);
Field field2 = field.get(request.getHeaderNames()).getClass().getDeclaredField("headers");
field2.setAccessible(true);
Field field3 = field2.get(field.get(request.getHeaderNames())).getClass().getDeclaredField("headers");
field3.setAccessible(true);
Object objects = field3.get(field2.get(field.get(request.getHeaderNames())));
List array = new ArrayList();
int length = Array.getLength(objects);
for (int i = 0; i < length; i++) {
array.add(Array.get(objects, i));
}
for (Object obj : array.toArray()) {
field = obj.getClass().getDeclaredField("nameB");
field.setAccessible(true);
Object headerKey = field.get(obj);
if (headerKey.toString().equalsIgnoreCase(headerToFind)) {
field = obj.getClass().getDeclaredField("valueB");
field.setAccessible(true);
MessageBytes messageBytes = MessageBytes.newInstance();
messageBytes.setString(valueToReplace));
field.set(obj, messageBytes);
break;
}
}
}