JAVA过滤器可以改变请求的内容或者重新设置请求 这里的请求就是这个servlet 或者jsp或
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA过滤器可以改变请求的内容或者重新设置请求 这里的请求就是这个servlet 或者jsp或相关的知识,希望对你有一定的参考价值。
JAVA过滤器可以改变请求的内容或者重新设置请求 这里的请求就是这个servlet 或者jsp或者 html。。。。的这样的web资源吗
可以。随意跳转。HttpServletResponse res = (HttpServletResponse) response;
res.sendRedirect(redirectURL);//这里是你的新请求路径 参考技术A 可以拦截这些请求,但是你说的改变是指什么?追问
就是 dofilter对请求操作阿 不就能改变请求内容了
参考技术B 指request对象追问可request对象也是存在servlet jsp里啊
参考技术C 可以设置拦截器,判断条件,然后按你设定的规则跳转到别的地址。java在filter中修改一个http请求出入参内容
response保存了请求的返回信息,里面有个outputstream,你要返回给页面的流,都在这个地方保存.
之前遇到一个问题,想把outputstream修改一下.因为这是个输出流,想要改这个里面的东西不是这么简单的.
sun为我们提供了这么一个工具HttpServletResponseWrapper抽象类,利用这个类的子类把servletresponse包装一下,在过滤器中使用,就可以去除response的文件流,对其作出修改.给出一个实现:
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;
/**
* ResponseWrapper
*
* @author wuweifeng
* @version 1.0
* @date 2021-08-16
*/
public class ResponseWrapper extends HttpServletResponseWrapper
/**
* ByteArrayOutputStream
*/
private ByteArrayOutputStream buffer;
/**
* ServletOutputStream
*/
private ServletOutputStream out;
/**
* writer
*/
private PrintWriter writer;
/**
* ResponseWrapper
*/
public ResponseWrapper(HttpServletResponse resp) throws IOException
super(resp);
buffer = new ByteArrayOutputStream();//真正存储数据的流
out = new WrapperOutputStream(buffer);
writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding()));
//重载父类获取outputstream的方法
@Override
public ServletOutputStream getOutputStream() throws IOException
return out;
//重载父类获取writer的方法
@Override
public PrintWriter getWriter() throws UnsupportedEncodingException
return writer;
//重载父类获取flushBuffer的方法
@Override
public void flushBuffer() throws IOException
if (out != null)
out.flush();
if (writer != null)
writer.flush();
@Override
public void reset()
buffer.reset();
/**
* 获取response的字符串
*/
public String getContent() throws IOException
flushBuffer();//将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据
return new String(buffer.toByteArray());
//内部类,对ServletOutputStream进行包装
private class WrapperOutputStream extends ServletOutputStream
/**
* ByteArrayOutputStream
*/
private ByteArrayOutputStream bos;
/**
* WrapperOutputStream
*/
WrapperOutputStream(ByteArrayOutputStream stream)
bos = stream;
@Override
public void write(int b)
bos.write(b);
@Override
public boolean isReady()
return false;
@Override
public void setWriteListener(WriteListener writeListener)
然后在你的过滤器中这么使用:
public class UserFilter implements Filter
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
HttpServletResponse resp = (HttpServletResponse) servletResponse;
ResponseWrapper mResp = new ResponseWrapper(resp);// 包装响应对象 resp 并缓存响应数据
filterChain.doFilter(servletRequest, mResp);
String content = mResp.getContent();//response流的内容
System.out.println(content);
//此处可以对content做处理,然后再把content写回到输出流中
servletResponse.setContentLength(-1);
PrintWriter out = servletResponse.getWriter();
out.write(content);
out.flush();
out.close();
关于入参request的,如果只是key-value型的,对应客户端是form那种传过来的,在filter里直接获取没事。但如果是application/json型的,如果这个输入流被提前读取了,则后续真正的controller就取不到了,也需要做个包装类。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import static com.alibaba.fastjson.util.IOUtils.UTF8;
public class RequestWrapper extends HttpServletRequestWrapper
/**
* log
*/
private static final Logger log = LoggerFactory.getLogger(RequestWrapper.class);
/**
* application/json型的入参
*/
private final String body;
/**
* key-value型所有的入参
*/
private Map<String, String[]> params = new HashMap<>();
public RequestWrapper(HttpServletRequest request)
super(request);
this.params.putAll(request.getParameterMap());
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try
inputStream = request.getInputStream();
if (inputStream != null)
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF8));
char[] charBuffer = new char[512];
int bytesRead;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0)
stringBuilder.append(charBuffer, 0, bytesRead);
catch (IOException ex)
log.error("requestBody read error ignore,message:" + ex.getMessage());
finally
if (inputStream != null)
try
inputStream.close();
catch (IOException e)
log.error("requestBody inputStream close error,ignore");
if (bufferedReader != null)
try
bufferedReader.close();
catch (IOException e)
log.error("requestBody bufferedReader close error,ignore");
body = stringBuilder.toString();
@Override
public ServletInputStream getInputStream() throws IOException
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes(UTF8));
ServletInputStream servletInputStream = new ServletInputStream()
@Override
public boolean isFinished()
return false;
@Override
public boolean isReady()
return false;
@Override
public void setReadListener(ReadListener readListener)
@Override
public int read() throws IOException
return byteArrayInputStream.read();
;
return servletInputStream;
@Override
public BufferedReader getReader() throws IOException
return new BufferedReader(new InputStreamReader(this.getInputStream(), UTF8));
public String getBody()
return this.body;
@Override
public String getParameter(String name)
String[] values = params.get(name);
if (values == null || values.length == 0)
return null;
return values[0];
@Override
public String[] getParameterValues(String name)
return params.get(name);
@Override
public Enumeration<String> getParameterNames()
return Collections.enumeration(params.keySet());
以上是关于JAVA过滤器可以改变请求的内容或者重新设置请求 这里的请求就是这个servlet 或者jsp或的主要内容,如果未能解决你的问题,请参考以下文章
Java web start:如何根据客户端可以管理的内容来改变 jnlp 中的堆内存请求?