카테고리 없음

* 자바스크립트와 css에서 한글이 깨지지 않도록 필터 생성

두개의 문 2023. 7. 26. 22:28

▪︎ Dynamic Web Project 생성 : FilterEncodingExam

 

 

▪︎ index.jsp 생성 

  - 테스트 시, value 속성을 이용해 초기값 자동으로 설정하기 )

  - CSS 자바스크립트의 주소 : EL 엔진 이용 

 

<link href="${ pageContext.request.contextPath }/css/styles.css" rel="stylesheet" type="text/css" >

 • pageContext.request.contextPath : 웹에서 상대적인 경로를 나타냄 ( 현재 위치의 문서를 기준으로 경로 인식 )

 • pageContext 객체 : javax.servlet.jsp.PageContext 클래스를 상속해 웹 컨테이너가 JSP 실행 시 자동으로 생성해서 제공하는 내장 객체 

 • javax.servlet.http.HttpServletRequest 객체가 제공하는 정보를 활용해 정보 얻을 있음

 

 

 

 

▪︎ styles.css index.js 생성 

 

 

→ 생성 결과 (Package Explorer창)

 

 

 

▪︎ EncodingServlet 생성

 

package apple.orange.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/encoding")
public class EncodingServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
 
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		
		String name = request.getParameter("name");
		String age = request.getParameter("age");
		String place = request.getParameter("place");
		
		// echo 출력 
		out.print("이름은 " + name + "<br />");
		out.print("나이는 " + age + "<br />");
		out.print("장소는 " + place + "<br />");
		out.print("<hr />");
		
	}
}

 

 • 문자열로 입출력할 계획 - 출력 스트림 생성 : PrintWriter ( 응답 객체로부터 얻음 )

 • 요청객체로부터 데이터 얻어오기 : getParameter( ) 메서드 이용 

 받은 데이터 그대로 전송 : echo 출력 

 

 

 

▪︎ 프로젝트 실행 : Run As - Run On Server

 

 • 제출 클릭 시, 한글이 깨지는 현상 발생 

    → 아래의 필터 적용 후 한글이 깨지지 않음 (해결)

    다만, css 수정  다시 재실행할 경우 수정된 내용이 반영이 되지 않음 

    ( 페이지 소스 보기를 통해서도 수정된 내용이 반영 안됨 )

 

▪︎ EncodingFilter에서 정규표현식을 이용해 문제 해결 

 

 

 ▪︎ EncodingFilter 생성 

package apple.orange.filter;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter("/*")
// * 요청이 들어오면, 그 요청을 요청 서블릿이 처리하기 전 또는 서블릿 처리 후에 
//   마지막 추가 처리를 하는 기능 
// * 웹 브라우저 요청 -> 필터 -> 서블릿 -> JSP 뷰 -> 정리 필터 
// * 루트 밑의 모든 경로로 설정 -> 한글 처리 
public class EncodingFilter extends HttpFilter implements Filter {
      
	// * Pattern : 자바에서 정규표현식 객체 
	// pattern 객체에 검색할 원본문자열에서 제거하고 싶은 또는 포함하고 싶은지를 검사하고 있는 비교할 
	// 문자패턴을 등록함 
	// * Pattern.compile() : 비교할 목록 리스트를 만드는 역할 
	//   "^.* : '\n' 개행문자를 제외한 모든 문자들 
	//   ^ : 문자열의 시작을 의미 
	//   . : '\n' 개행문자를 뺀 모든 문자 
	//   * : 앞의 문자패턴을 여러 번 반복 
	//   (...) : () 안의 내용을 그룹으로 묶음 분리 (리스트와 같은 역할)
	//   | : or, () 안의 내용들 중에 하나  
	//   $ : 앞의 그룹문자들로 끝나는지 
	//   CASE_INSENSITIVE : 대소문자 구분하지 않음 
	private static final Pattern excludeUrls = Pattern.compile(
			"^.*/(css|js|images|ckeditor)/.*$",
			Pattern.CASE_INSENSITIVE);
		
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		// * 필터처리를 위한 요청객체와 응답객체를 웹 프로토콜로 다운캐스팅
		//   ServletRequest <- HttpServletRequest 
		// 현재 우리가 다루는 프로토콜은 웹 관련 프로토콜이므로, 
		// 굳이 객체의 타입을 조사해서 자식 클래스 타입으로 변환할 필요는 없음 
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		
		String path = req.getRequestURI().substring(req.getContextPath().length())
						.replaceAll("[/]+$", "");
		// req : 웹 요청 객체 | res : 웹 응답 객체 
		// getRequestURI() 
		//     : 웹 브라우저에서 요청한 요청주소 중에서 프로토콜, 서버주소 및 포트 번호를 뺀 나머지 주소 
		//       → 웹 서버로 요청 시, 요청에 사용된 URL로부터 URI 값을 리턴 
		// 예 ) 'http://localhost:8080/api/index.jsp'에서 
		//     프로토콜 'http://' 제거, 서버주소 'localhost:8080' 제거 후 
		//     나머지 주소인 '/api/index.jsp'가 요청 URI 주소에 해당 
		//     index.jsp : 실제 실행하는 앱 이름 = 요청 애플리케이션 컨텍스트 == request.getContextPath 
		// ...$ : ... 로 끝나는지, 즉 문장의 끝을 의미
		// ^... : ... 로 시작하는지, 즉 문장의 시작을 의미 
		// [...] : [] 안의 ... 문자 어떤 것이든 가능 
		// * : 문자가 0번 이상 반복
		// + : 문자가 1번 이상 반복 
		// [/]+$ : 문자열의 끝이 '/'인 문자를 포함하는 경우 
		// * req.getRequestURI().substring(req.getContextPath().length()).replaceAll("[/]+$", "") 
		//   : URI 주소에서 문장의 끝이 '/'로 끝나는 경우, 요청 애플리케이션 컨텍스트의 길이만큼 대체 
		//     -> 컨텍스트만 남게 됨 (index.jsp)
		
		
		
		// * 공통 필터 적용 
		//   1) 요청객체로부터 읽어오는 데이터를 무조건 UTF-8(유니코드)로 해석해라
		//   2) 나중에 브라우저로 응답할 때 기본 데이터 쓰기 설정을 UTF-8(유니코드)로 설정해라 
		//		-> 이후 출력은 모두 UTF-8로 해석이 됨 
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		
		// * 이후부터 모든 HTML 관련 파일들을 UTF-8로 변환하라 
		//   다만, CSS 및 JS의 경우, 마임 파일 타입이 text/css, text/javascript이므로 문제 발생 
		//   그래서 한글 설정을 하면 CSS 및 JS 파일들이 일부 실행되지 않는 문제가 생김 
		//response.setContentType("text/html; charset: UTF-8"); 
		// 현재 CSS 수정 시 반영이 안되는 문제의 원인 
		// -> 이 부분을 주석처리 시, 한글이 깨지는 현상 다시 발생 
	
		// response.setContentType()
		// 허용불가 경로 포함여부 판별 
		Matcher matcher = excludeUrls.matcher( path );
		boolean isPathExcluded = matcher.find();
		
		// 허용불가 경로가 아니면 
		if(!isPathExcluded) {
			response.setContentType("text/html; charset: UTF-8");
			System.out.println("허용불가 경로 아님 : " + path);
		} else {
			
		}
		
		// 위의 설정으로 필터를 적용하라는 의미 
		chain.doFilter(request, response);
		System.out.println("필터 적용 완료!");
	}
}