该异常一般是在线上生产环境中产生的请求异常。
产生该异常的缘由:
实际生产中的head请求一般由搜索引擎发出 。
搜索引擎先发送HEAD 请求是为了获得页面的更新时间(即response header 中的Last-Modified 域),
用于判断自从上一次该页面被收入索引库以后有没有被更新过,如果判断页面没有被更新过就忽略该页面,
否则就再用GET 方法获取一次最新的内容并更新到索引库中。
引用:https://www.cnblogs.com/xuan52rock/p/4495233.html
解决方式:
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
* Head请求处理过滤器
* 实际生产中的head请求一般由搜索引擎发出
* 搜索引擎先发送HEAD 请求是为了获得页面的更新时间(即response header 中的Last-Modified 域),
* 用于判断自从上一次该页面被收入索引库以后有没有被更新过,如果判断页面没有被更新过就忽略该页面,
* 否则就再用GET 方法获取一次最新的内容并更新到索引库中
* 可解决Request method 'HEAD' not supported异常
* @author wangjiao
*
*/
public class HttpHeadReqFilter implements Filter{
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if ("HEAD".equals(httpServletRequest.getMethod())) {
//对"HEAD"请求进行处理
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//设置Last-Modified即页面更新时间
httpServletResponse.setDateHeader("Last-Modified", System.currentTimeMillis());
NoBodyResponseWrapper noBodyResponseWrapper = new NoBodyResponseWrapper(httpServletResponse);
//强制使用没有返回体(noBodyResponseWrapper)的"GET"请求
chain.doFilter(new ForceGetRequestWrapper(httpServletRequest), noBodyResponseWrapper);
noBodyResponseWrapper.setContentLength();
} else {
chain.doFilter(request, response);
}
}
private class ForceGetRequestWrapper extends HttpServletRequestWrapper {
public ForceGetRequestWrapper(HttpServletRequest request) {
super(request);
}
public String getMethod() {
return "GET";
}
}
/**
* 无响应体的包装类
* @author wangjiao
*
*/
private class NoBodyResponseWrapper extends HttpServletResponseWrapper {
private final NoBodyOutputStream noBodyOutputStream = new NoBodyOutputStream();
private PrintWriter writer;
public NoBodyResponseWrapper(HttpServletResponse response) {
super(response);
}
public ServletOutputStream getOutputStream() throws IOException {
return noBodyOutputStream;
}
public PrintWriter getWriter() throws UnsupportedEncodingException {
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(noBodyOutputStream, getCharacterEncoding()));
}
return writer;
}
void setContentLength() {
super.setContentLength(noBodyOutputStream.getContentLength());
}
}
private class NoBodyOutputStream extends ServletOutputStream {
private int contentLength = 0;
int getContentLength() {
return contentLength;
}
public void write(int b) {
contentLength++;
}
public void write(byte buf[], int offset, int len) throws IOException {
contentLength += len;
}
}
}