필터 응용 [인 코딩, 민감 어, 압축, 전의 필터]
위의 블 로그 에서 우 리 는 필터 의 기본 개념, 사용 및 간단 한 Servlet 응용 을 설명 했다.이 박문 은 주로 필터 의 고급 응용 을 설명 한다.
인 코딩 필터
목적: 전체 사이트 의 난 장 판 문 제 를 해결 합 니 다.
필터 개발
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
// request response http
HttpServletRequest httpServletRequest = (HttpServletRequest) req;
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
httpServletRequest.setCharacterEncoding("UTF-8");
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("text/html;charset=UTF-8");
chain.doFilter(httpServletRequest, httpServletResponse);
}
첫 번 째 테스트
Servlet 1 에서 브 라 우 저 에 중국어 데 이 터 를 응답 하 였 으 며, 오류 가 발생 하지 않 았 습 니 다.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write(" !");
}
분석 하 다.
위의 필 터 는 완벽 하지 않 습 니 다. 브 라 우 저 는 get 방식 으로 서버 에 제출 한 중국어 데 이 터 를 위 에 있 는 필터 만 으로 는 완성 할 수 없습니다!
그럼 저희 가 어떻게 해 야 되 죠?우리 가 이전에 해결 한 get 방식 의 인 코딩 문 제 는 다음 과 같 습 니 다. request 를 사용 하여 전 달 된 데 이 터 를 가 져 오고 ISO 8859 - 1 인 코딩 을 통 해 인 코딩 이 아 닌 데 이 터 를 얻 을 수 있 습 니 다.
나의 이전의 박문 을 참고 하 다.https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=100000001&idx=6&sn=b0c346d7f17a097525ad106291aad28c&chksm=6bd740005ca0c916f72872122dff3bad8c49f9f690ea51b442b542dbbb654382bb663a01473b&mpshare=1&scene=1&srcid=0206hvswcHK67to1b4tr46AK#rd
Servlet 에서 브 라 우 저 를 가 져 와 GET 방식 으로 제출 한 중국어 가 난 장 판 의 근본 원인 은 getParameter () 방법 은 ISO 8859 - 1 의 인 코딩 으로 브 라 우 저가 전달 한 데 이 터 를 가 져 오 는 것 이 고 난 장 판 을 얻 는 것 이다.
근본 적 인 원인 을 알 았 으 니 하기 쉽 습 니 다. 필터 가 전달 하 는 request 대상 은 getParameter () 방법 을 사용 할 때 정상 적 인 중국어 데 이 터 를 얻 을 수 있 습 니 다.
즉, sun 회사 가 우리 에 게 제공 하 는 request 대상 은 부족 합 니 다. sun 회사 가 제공 하 는 request 대상 은 getParameter () 를 사용 하여 get 방식 으로 제출 한 데 이 터 를 가 져 오 는 것 은 어 지 러 운 코드 이기 때문에 우 리 는 request 대상 을 강화 해 야 합 니 다 (getParameter () 가 가 져 오 는 것 은 중국어 입 니 다)!
증강 request 대상
request 대상 을 강화 하려 면 포장 디자인 모델 을 사용 해 야 합 니 다!
포장 디자인 모델 의 다섯 가지 절차:
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
public MyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = this.request.getParameter(name);
if (value == null) {
return null;
}
// get ,
if (!this.request.getMethod().equalsIgnoreCase("get")) {
return value;
}
try {
// get ,
value = new String(value.getBytes("ISO8859-1"), this.request.getCharacterEncoding());
return value ;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(" ");
}
}
}
강 화 된 request 대상 을 대상 자원 에 전달 합 니 다. 그러면 대상 자원 이 request 를 사용 하여 getParameter () 방법 을 호출 할 때 얻 은 것 은 중국어 데이터 입 니 다. 난호 가 아 닙 니 다!
// request response http
HttpServletRequest httpServletRequest = (HttpServletRequest) req;
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
httpServletRequest.setCharacterEncoding("UTF-8");
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("text/html;charset=UTF-8");
MyRequest myRequest = new MyRequest(httpServletRequest);
// request 。
chain.doFilter(myRequest, httpServletResponse);
이차 테스트
민감 한 단어의 필터
만약 에 사용자 가 민감 한 단어 (바보 b, 니 마, 개 떡 같은 문명 하지 않 은 언어 를 입력 했 을 때) 를 입력 하면 우 리 는 이런 문명 하지 않 은 것 을 차단 하고 기호 로 바 꿔 야 합 니 다!
이러한 기능 을 실현 하 는 것 도 간단 합 니 다. 사용자 가 입력 한 민감 한 단 어 는 getParameter () 에서 얻 은 것 이 분명 합 니 다. 우 리 는 getParameter () 에서 이 데 이 터 를 얻 었 을 때 민감 한 단어 가 있 는 지 없 는 지 판단 하고 있 으 면 교체 하면 됩 니 다!쉽게 말 하면 request 대상 을 강화 해 야 한다.
증강 request 대상
class MyDirtyRequest extends HttpServletRequestWrapper {
HttpServletRequest request;
//
private List list = Arrays.asList(" b", " ", " ");
public MyDirtyRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = this.request.getParameter(name);
if (value == null) {
return null;
}
// list ,
for (String s : list) {
if (s.equals(value)) {
value = "*****";
}
}
return value ;
}
}
필터 개발
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
// request response http
HttpServletRequest httpServletRequest = (HttpServletRequest) req;
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
MyDirtyRequest dirtyRequest = new MyDirtyRequest(httpServletRequest);
// request
chain.doFilter(dirtyRequest, httpServletResponse);
}
테스트
압축 자원 필터
필터 의 실행 순서: 대상 자원 을 실행 하면 필터 뒤의 코드 가 실 행 됩 니 다.따라서 우 리 는 필터 에서 목표 자원 을 실행 한 후의 response 대상 을 가 져 올 수 있 습 니 다!
sun 회사 가 제공 하 는 response 대상 이 write () 방법 을 호출 하 는 것 은 브 라 우 저 에 직접 데 이 터 를 되 돌려 주 는 것 임 을 알 고 있 습 니 다.압축 기능 을 실현 하려 면 write () 방법 으로 데 이 터 를 브 라 우 저 에 직접 쓸 수 없습니다!
이것 은 위 와 유사 합 니 다. 필 터 를 대상 자원 에 전달 하 는 response 대상 은 우리 가 강화 해 야 합 니 다. 대상 자원 이 writer () 방법 을 호출 할 때 데 이 터 를 브 라 우 저 에 직접 쓰 지 않도록 해 야 합 니 다!
증강 응답 대상
response 대상 은 PrintWriter 나 ServletOutputStream 대상 을 사용 하여 writer () 방법 을 호출 할 수 있 습 니 다. 따라서 response 대상 을 강화 할 때 getOutputSteam 과 getWriter () 를 다시 써 야 합 니 다.
class MyResponse extends HttpServletResponseWrapper{
HttpServletResponse response;
public MyResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return super.getOutputStream();
}
@Override
public PrintWriter getWriter() throws IOException {
return super.getWriter();
}
}
다음은 ServletOutputSteam 에서 writer () 방법 을 사용 하여 브 라 우 저 에 데 이 터 를 쓰 지 않도록 해 야 합 니 다.이것 은 또 우리 가 한 번 증강 해 야 한다!
증강 ServletOutputSteam
/* ServletOutputSteam, writer */
class MyServletOutputStream extends ServletOutputStream{
private ByteArrayOutputStream byteArrayOutputStream;
public MyServletOutputStream(ByteArrayOutputStream byteArrayOutputStream) {
this.byteArrayOutputStream = byteArrayOutputStream;
}
// write() , byteArrayOutputSteam
@Override
public void write(int b) throws IOException {
this.byteArrayOutputStream.write(b);
}
}
증강 PrintWriter
PrintWriter 대상 은 쉽게 처리 할 수 있 습 니 다. 그것 은 원래 포장 류 입 니 다. 구조 방법 을 보면 우 리 는 ByteArray OutputSteam 을 PrintWriter 에 직접 전달 할 수 있 습 니 다.
@Override
public PrintWriter getWriter() throws IOException {
printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, this.response.getCharacterEncoding()));
return printWriter;
}
캐 시 데이터 가 져 오기
우 리 는 데 이 터 를 모두 ByteArray OutputSteam 에 썼 습 니 다. 외부 캐 시 에 있 는 데 이 터 를 제공 하 는 방법 을 제공 해 야 합 니 다!
public byte[] getBuffer() {
try {
// , !
if (printWriter != null) {
printWriter.close();
}
if (byteArrayOutputStream != null) {
byteArrayOutputStream.flush();
return byteArrayOutputStream.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
response 의 전체 코드 강화
class MyResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private PrintWriter printWriter ;
private HttpServletResponse response;
public MyResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
// ServletOutputSteam write() , byteArrayOutputSteam
return new MyServletOutputStream(byteArrayOutputStream);
}
@Override
public PrintWriter getWriter() throws IOException {
printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, this.response.getCharacterEncoding()));
return printWriter;
}
public byte[] getBuffer() {
try {
// , !
if (printWriter != null) {
printWriter.close();
}
if (byteArrayOutputStream != null) {
byteArrayOutputStream.flush();
return byteArrayOutputStream.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
필터
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
MyResponse myResponse = new MyResponse(response);
// response , write()
chain.doFilter(request, myResponse);
//
byte[] bytes = myResponse.getBuffer();
//
System.out.println(" :"+bytes.length);
// GZIP ,
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
gzipOutputStream.write(bytes);
gzipOutputStream.flush();
//
byte[] gzip = byteArrayOutputStream.toByteArray();
System.out.println(" :" + gzip.length);
// , , !
response.setHeader("content-encoding", "gzip");
response.setContentLength(gzip.length);
response.getOutputStream().write(gzip);
}
테스트
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("fdshfidsuhfidusfhuidsfhuidshdsuifhsd" +
"uifhsduifffffdshfidsuhfidusfhuidsfhuidshdsuif" +
"hsduifhsduifffffdshfidsuhfidusfhuidsfhuidshd" +
"suifhsduifhsduifffffdshfidsuhfidusfhuidsfhuidsh" +
"dsuifhsduifhsduifffffdshfidsuhfidusfhuidsfhuids" +
"hdsuifhsduifhsduifffffdshfidsuhfidusfhuidsfhuid" +
"shdsuifhsduifhsduiffdshfidsuhfidusfhuidsfhuids" +
"hdsuifhsduifhsduifffffdshfidsuhfidusfhuidsfhui" +
"dshdsuifhsduifhsduifffffdshfidsuhfidusfhuidsfh" +
"uidshdsuifhsduifhsduifffffdshfidsuhfidusfhuids" +
"fhuidshdsuifhsduifhsduifffffdshfidsuhfidusfhuid" +
"sfhuidshdsuifhsduifhsduifffffdshfidsuhfidusfhui" +
"dsfhuidshdsuifhsduifhsduifffffdshfidsuhfidusfh" +
"uidsfhuidshdsuifhsduifhsduifffffdshfidsuhfidusf" +
"huidsfhuidshdsuifhsduifhsduifffffdshfidsuhfidus" +
"fhuidsfhuidshdsuifhsduifhsduifffffdshfidsuhfid" +
"usfhuidsfhuidshdsuifhsduifhsduifffffdshfidsuhf" +
"idusfhuidsfhuidshdsuifhsduifhsd" +
"uifffffdshfidsuhfidusfhuidsfhuidshdsuifhsduifhsduifffffff");
}
getParameter () 에서 얻 은 데 이 터 를 한 번 만 바 꾸 면 기능 을 완성 할 수 있 습 니 다.
증강 요청
class MyHtmlRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyHtmlRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = this.request.getParameter(name);
return this.Filter(value);
}
public String Filter(String message) {
if (message == null)
return (null);
char content[] = new char[message.length()];
message.getChars(0, message.length(), content, 0);
StringBuffer result = new StringBuffer(content.length + 50);
for (int i = 0; i < content.length; i++) {
switch (content[i]) {
case '':
result.append(">");
break;
case '&':
result.append("&");
break;
case '"':
result.append(""");
break;
default:
result.append(content[i]);
}
}
return (result.toString());
}
}
필터
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
MyHtmlRequest myHtmlRequest = new MyHtmlRequest(request);
// request!
chain.doFilter(myHtmlRequest, response);
}
테스트
jsp 코드:
Servlet 코드:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String value = request.getParameter("username");
response.getWriter().write(value);
}
메모리 에 데 이 터 를 캐 시 합 니 다.
앞에서 우 리 는 브 라 우 저가 데 이 터 를 캐 시 하지 않도록 했 습 니 다. [인증 코드 의 그림 은 캐 시 하지 말 아야 합 니 다.]
지금 우리 가 해 야 할 일 은 캐 시 데 이 터 를 메모리 에 저장 하 는 것 입 니 다.
이것 은 데 이 터 를 압축 한 Filter 와 매우 유사 합 니 다. 데 이 터 를 브 라 우 저 에 직접 출력 하지 않 고 용기 (ByteArray OutputSteam) 로 저장 하기 때 문 입 니 다.캐 시 가 있 으 면 캐 시 를 가 져 옵 니 다.캐 시 없 이 대상 자원 을 실행 합 니 다!
증강 응답 대상
class MyResponse extends HttpServletResponseWrapper {
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private PrintWriter printWriter ;
private HttpServletResponse response;
public MyResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
// ServletOutputSteam write() , byteArrayOutputSteam
return new MyServletOutputStream(byteArrayOutputStream);
}
@Override
public PrintWriter getWriter() throws IOException {
printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, this.response.getCharacterEncoding()));
return printWriter;
}
public byte[] getBuffer() {
try {
// , !
if (printWriter != null) {
printWriter.close();
}
if (byteArrayOutputStream != null) {
byteArrayOutputStream.flush();
return byteArrayOutputStream.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
// ServletOutputSteam, writer
class MyServletOutputStream extends ServletOutputStream {
private ByteArrayOutputStream byteArrayOutputStream;
public MyServletOutputStream(ByteArrayOutputStream byteArrayOutputStream) {
this.byteArrayOutputStream = byteArrayOutputStream;
}
// write() , byteArrayOutputSteam
@Override
public void write(int b) throws IOException {
this.byteArrayOutputStream.write(b);
}
}
필터
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
// Map ,key ,value
Map map = new HashMap<>();
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//
String uri = request.getRequestURI();
byte[] bytes = map.get(uri);
// , ,
if (bytes != null) {
response.getOutputStream().write(bytes);
return ;
}
// ,
MyResponse myResponse = new MyResponse(response);
chain.doFilter(request, myResponse);
//
byte[] b = myResponse.getBuffer();
//
map.put(uri, b);
//
response.getOutputStream().write(b);
}
테스트
새로 고침 에 도 불구 하고 캐 시 에서 얻 은 데 이 터 를 가 져 옵 니 다!
글 에 잘못된 부분 이 있 으 면 지적 을 환영 하고 서로 교류 합 니 다.위 챗 에서 기술 문장 을 보 는 습관 이 있 는 학생 들 은 위 챗 공식 번호: 자바 3y 에 주목 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
조건자로 필터링프로그래밍에서 컬렉션이 있을 때 요구 사항을 충족하는 부분을 필터링하고 나머지는 버려야 하는 경우가 있습니다. 자세한 예는 환자 기록 목록이 있고 미성년 환자 목록을 가져오려는 경우입니다. 이 코드를 자바 파일에 복...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.