JSP 피피티

JSP피피티 05강 WebHelper, 페이지 강제이동

전설의개발자 2020. 8. 18. 18:58

WebHelper

-공통 기능들을 구현해 놓은 모듈

  • 모듈이란 본디 프로그램 구현에 사용되는 부품들을 이르는 용어.(레고블럭같은)
  • 프로그래밍을 하는 과정에서 빈번하게 자주 등장하는 구현 코드를 간단하게 호출할 수 있도록 클래스로 구현해 놓은 형태.
  • 모든 개발자들이 자신만의 모듈을 갖고 있다.
  • 이점
    -코드가 축약된다.
    -개발자는 페이지를 구현하는데 필요한 데이터 처리 로직에만 집중하고 그 밖의 부가적인 처리들은 모듈이 맡아서 수행한다.
  • 웹에서 사용될 공통 기능들을 모듈화 해 놓은 싱글톤 클래스(ex> 페이지 강제이동, JSON데이터 처리등)

/src/study.jsp.model1.helper/WebHelper.java

package study.jsp.model1.helper;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class WebHelper {
	/* 기본 인코딩 타입 설정 */
	private String encType="UTF-8";
	
	/* JSP의 request 내장 객체 */
	//-> import javax.servlet.http.HttpServletRequest;
	private HttpServletRequest request;
	
	/* JSP의 reponse 내장 객체 */
	//-> import javax.servlet.http.HttpServletResponse;
	private HttpServletResponse response;
	
	//--------------싱글톤 객체 생성 시작----------
	private static WebHelper current;
	
	//JSP의 내장 객체는 일반 JAVA클래스가 생성할 수 없기 때문에
	//JSP 페이지로부터 request와 response 객체를 전달받아야 한다.
	//--> import javax.servlet.httpServletRequest;
	//--> import javax.servlet.httpServletResponse;
	//getInstance()  : 싱글턴패턴, 하나의 인스턴스만 가지고 공유해서 쓴다.

	public static WebHelper getInstance(HttpServletRequest request, HttpServletResponse response) {
		if(current == null) {
			current = new WebHelper();
		}
		
		//JSP 내장객체를 연결하기 위한 메서드를 호출
		current.init(request, response);
		return current;
	}
	
	public static void freeInstance() {
		current = null;
	}
	
	private WebHelper() {
		super();
	}
	/**
	 * 싱글톤 객체가 생성될 때 호출되는 메서드로 JSP의 주요 내장객체를 멤버변수에 연결한다.
	 * @param request
	 * @param response
	 */
	public void init(HttpServletRequest request, HttpServletResponse response) {
		this.request = request; //JSP내장 객체 참조하기
		this.response = response; // JSP내장객체 참조하기
		
		String methodName = request.getMethod();			//Get방식인지, Post방식인지 조회한다.
		String url = request.getRequestURL().toString();	//현재 URL을 획득한다.
		String queryString = request.getQueryString(); 		//URL에서 "?" 이후의 Get파라미터 문자열을 모두 가져온다.
		
		if (queryString != null) {
			url = url +"?" +queryString;
		}
		
		log.debug(String.format("[%s] %s",methodName, url)); //획득한 정보를 로그로 표시한다.
		/* 내장객체 초기화 -> utf-8설정 */
		//--> import java.io.UnsupportedEncodingException;
		try {
			this.request.setCharacterEncoding(this.encType);
			this.response.setCharacterEncoding(this.encType);
		}catch(UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		
	}
	
	public void redirect(String url, String msg) {
		
		//획득한 정보를 로그로 표시한다.
		 log.debug(String.format("-->[redirect] %s >> %s",url, msg));
		 
		 //가상의 view로 만들기 위한 HTML 태그 구성
		 String html ="<!doctype html>";
		 html +="<html>";
		 html +="<head>";
		 html +="<meta charset='" + this.encType + "'>";
		 
		 //메시지 표시
		 if(msg != null) {
			 html += "<script type='text/javascript'>alert('" +msg+"');</script>";
		 }
		 
		 //페이지 이동
		 if(url != null) {
			 html +="<meta http-equiv='refresh' content='0; url=" +url+"'>";
		 }else {
			 html +="<script type='text/javascript'>history.back();</script>";
		 }
		 
		 html +="</head>";
		 html +="<body></body>";
		 html +="</html>";
				 
		 //구성된 HTML을 출력하낟.
		 try {
			 //브라우저에 결과값을 출력하기 위한 out객체를 생성한다. (예외처리 필요)
			 PrintWriter out = this.response.getWriter();
			 
			 //준비된 html태그를 출력한다.
			 out.print(html);
		 }catch(IOException e) {
			 e.printStackTrace();
		 }
		
	}

	public String getencType() {
		return encType;
	}

	public void setencType(String encType) {
		this.encType = encType;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}
}
  • 클래스를 추가하고 필요한 멤버변수를 정의 (WebHelper클래스)
    -기본 인코딩 타입 설정
    -JSP의 request 내장 객체
    -JSP의 response 내장 객체
  • 싱글톤 객체 구성
    -대부분의 모듈들은 프로그램 전역에서 공통으로 사용되는 기능들의 모음이므로 매번 객체를 생성하기 보다는 하나의 객체를 재사용하는 것이 효율적
  • JSP 내장객체를 주입받기 위한 메서드 추가 (init())
    -자바 클래스에서는 JSP내장 객체를 생성할 수 없기 때문에 JSP 페이지로부터 내장 객체를 주입받기 위한 메서드를 준비해야 한다.
  • 현재 페이지의 실행 위치를 로그로 기록하기 위한 기능 추가 (init()메서드 안에)
    -로그에 쌓이는 정보는 매우 방대하기 때문에 어떤 페이지에 사용자들이 접속했는지 쉽게 파악하기 어려움
    -실행되는 페이지의 URL을 로그로 기록해 놓으면 향후 이 값을 분석하여 사용자들이 가장 많이 열람한 컨텐츠에 대한 데이터 분석이 가능하다.

*JSP 페이지의 내장 객체(더보기)

더보기

 

 내장 객체

리턴 타입(Return Type) 

설명 

request 

javax.servlet.http.HttpServletRequest 

웹 브라우저의 요청 정보를 저장하고 있는 객체 

response 

javax.servlet.http.HttpServletResponse 

웹 브라우저의 요청에 대한 응답 정보를 저장하고 있는 객체 

out 

javax.servlet.jsp.jsp.jspWriter 

JSP 페이지에 출력할 내용을 가지고 있는 출력 스트림 객체이다. 

session 

javax.servlet.http.HttpSession 

하나의 웹 브라우저의 정보를 유지하기 위한 세션 정보를 저장하고 있는 객체 

application 

javax.servlet.ServletContext 

웹 어플리케이션 Context의 정보를 저장하고 있는 객체 

pageContext 

javax.servlet.jsp.PageContext 

JSP 페이지에 대한 정보를 저장하고 있는 객체 

page 

java.lang.Object 

JSP 페이지를 구현한  자바 클래스 객체

config 

javax.servlet.ServletConfig 

JSP 페이지에 대한 설정 정보를 저장하고 있는 객체 

exception 

java.lang.Throwable 

JSP 페이지서 예외가 발생한 경우에 사용되는 객체 

출처: https://hyeonstorage.tistory.com/78 [개발이 하고 싶어요]JSP 페이지의 내장 객체

 

 

webhelper.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ page import="study.jsp.model1.helper.WebHelper" %>
<%
	WebHelper webHelper = WebHelper.getInstance(request, response);
//위의 코드가 있으면 웹페이지 주소칸에 어떤 주소를 입력했고, 어떤 방식으로 접근했는지 알려준다.
//주소끝에 변수까지도.

%>
<!doctype html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Hello JSP</title>
</head>
<body>
    <h1>webhelper.jsp</h1>
</body>
</html>

 

위와 같이 주소가 'webhelper.jsp'인 (WebHelper가 참조 되어있는)HTML 코드가 있을때 사용자(클라이언트)가 도메인에 webhelper.jsp라고 주소를 입력하면 바로 WebHelper.java가 실행된다.

 

WebHelper.java

package study.jsp.model1.helper;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class WebHelper {
	/* 기본 인코딩 타입 설정 */
	private String encType="UTF-8";
	
	/* JSP의 request 내장 객체 */
	//-> import javax.servlet.http.HttpServletRequest;
	private HttpServletRequest request;
	
	/* JSP의 reponse 내장 객체 */
	//-> import javax.servlet.http.HttpServletResponse;
	private HttpServletResponse response;
	
	//--------------싱글톤 객체 생성 시작----------
	private static WebHelper current;
	
	//JSP의 내장 객체는 일반 JAVA클래스가 생성할 수 없기 때문에
	//JSP 페이지로부터 request와 response 객체를 전달받아야 한다.
	//--> import javax.servlet.httpServletRequest;
	//--> import javax.servlet.httpServletResponse;
	//getInstance()  : 싱글턴패턴, 하나의 인스턴스만 가지고 공유해서 쓴다.

	public static WebHelper getInstance(HttpServletRequest request, HttpServletResponse response) {
		if(current == null) {
			current = new WebHelper();
		}
		
		//JSP 내장객체를 연결하기 위한 메서드를 호출
		//필요한 값들의 초기화 함수에 자주 사용
		current.init(request, response);
		return current;
	}
	
	public static void freeInstance() {
		current = null;
	}
	
	private WebHelper() {
		super();
	}
    //--------------싱글톤 객체 생성 끝----------
	/**
	 * 싱글톤 객체가 생성될 때 호출되는 메서드로 JSP의 주요 내장객체를 멤버변수에 연결한다.
	 * @param request
	 * @param response
	 */
	public void init(HttpServletRequest request, HttpServletResponse response) {
		this.request = request; //JSP내장 객체 참조하기
		this.response = response; // JSP내장객체 참조하기
		
		String methodName = request.getMethod();		 //Get방식인지, Post방식인지 조회한다.
		String url = request.getRequestURL().toString(); //현재 URL을 획득한다.
		String queryString = request.getQueryString(); 	 //URL에서 "?" 이후의 Get파라미터 문자열을 모두 가져온다.
		
		if (queryString != null) {
			url = url +"?" +queryString;
		}
		
		log.debug(String.format("[%s] %s",methodName, url)); //획득한 정보를 로그로 표시한다.
		/* 내장객체 초기화 -> utf-8설정 */
		//--> import java.io.UnsupportedEncodingException;
		try {
			this.request.setCharacterEncoding(this.encType);
			this.response.setCharacterEncoding(this.encType);
		}catch(UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		
	}

 

싱글톤 객체가 생성될때 init()함수가 실행되어 이클립스 콘솔에 아래와같이 로그가 남고 webhelper.jsp가 로드된다.

 

[2020-08-20 09:37:44.328][DEBUG] WebHelper.init(WebHelper.java:68) [GET] http://localhost:8080/Model1/01_strart/webhelper.jsp

-기본인코딩 타입 설정하고

-JSP의 내장객체 request와 response를 가지고 싱글톤객체 생성

-request(요청)객체로 사용자가 도메인에 입력한 주소와, 접속방식(Get or Post), URL에서 ?이후의 파라미터 문자열 까지 로그로 출력(확인)할 수 있다.

 

싱글톤패턴??(더보기클릭)

더보기

 Single Ton 디자인 패턴

  • 프로그램 내의 여러 곳에서 반복적으로 사용되어야 하는 객체에 대해 전역적인 범위를 갖도록 객체를 생성하고, 이 객체를 여러곳에서 공유하기 위한 클래스 작성 패턴. 
  • 이러한 패턴을 통해 생성된 객체를 싱글톤 객체라고 한다.

Single Ton 객체의 이점

  • 프로그램의 전역에서 활용할 재료로 사용되는 공유 기능을 하나만 생성하여 여러곳에서 재사용함으로 해서 메모리를 효율적으로 사용할 수 있다.
  • 단 한번만 객체를 생성하면 다시 객체를 생성할 필요가 없기 때문에 해당 기능을 사용할 때마다 객체를 일일이 생성해야 하는 번거로움을 피할수 있다.

[선생님 자바 ppt07 35p 참조]

여기서 싱글톤 부분은 WebHelper클래스 안에 있지만 독립된 객체이다.

getInstance()

new()와 getInstance()의 차이

new()            : 객체를 계속계속 만들 수 있다.

getInstance()  : 싱글턴패턴, 하나의 인스턴스만 가지고 공유해서 쓴다.

 

싱글턴패턴

: 생성자를 private로 선언하여 다른클래스에서 해당 클래스의 인스턴스를 

new로 생성하지 못하게 하고, getInstance()함수를 통해서 인스턴스를 갖도록 한다.

 

싱글턴패턴쓴다고 하면 getInstace() 하는것 같다.

아 선생님꺼 싱글톤 예제를 보니 싱글톤객세를 사용하는 방법으로 getInstance()하네

ex) Clac loader1 = Calc.getInstance();

     loader1.plus(100, 50);

 

    Calc.getInstance().minus(100,50);

 

init()

필요한 값들을 초기화에 init()를  많이 사용합니다.

출처: https://selectwiggle.tistory.com/24 [위글위글]

 

 

페이지 강제이동

before.jsp ↓

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ page import="study.jsp.model1.helper.WebHelper" %>
<%
	WebHelper webHelper = WebHelper.getInstance(request, response);
%>
<!doctype html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Hello JSP</title>
</head>
<body>
    <a href="after.jsp">after.jsp로 이동</a>
</body>
</html>

after.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ page import="study.jsp.model1.helper.WebHelper" %>
<%
	WebHelper webHelper = WebHelper.getInstance(request, response);

	//메시지 없이 이전 페이지로 이동
	//webHelper.redirect(null, null);
	
	//메시지 표시이후 이전 페이지로 이동
	webHelper.redirect(null, "이전 페이지로 돌아갑니다.");
	
	//메시지 없이 webhelper.jsp 페이지로 이동
	//webHelper.redirect("webhelper.jsp", null);
	
	//메시지 표시 후 webhelper.jsp 페이지로 이동
	//webHelper.redirect("webhelper.jsp", "Hello World");
%>
<!doctype html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Hello JSP</title>
</head>
<body>
    
</body>
</html>
  • 정상적인 데이터 전송의 경우
    -<meta>태그를 확용하여 페이지 이동을 구현해야 한다.

  • 파라미터가 정상적이지 않거나 유효성 검사를 통과하지 못한 경우 Javsscript를 활용하여 이전 페이지로 돌려보내야 한다. 이 경우 대부분 메시지 박스를 표시해야만 한다.
입력폼
(after.jsp)
submit
----------------------->
Action
(WebHelper.java에서 redirect())
<meta>
----------------------->
페이지 강제 이동시
JSP의"response.sendRedirect()" 를 사용하면 JS와의 병행 사용이 불가능하므로 <meta>태그를 사용하는것이 좋다.
결과확인
[js]history.back()
문제가 생겼을 경우
<----------------------

사용자가 before.jsp 페이지에서 'after.jsp로 이동'을 눌렀을때 webHelper 객체가 생성되고 redirect()함수가 실행된다.

전달되는 파라미터의 값에 따라 결과가 바뀐다.

(아래의 코드는 위의 WebHelper클래스와 이어지는 코드이다.)

public void redirect(String url, String msg) {
		
		//획득한 정보를 로그로 표시한다.
		 log.debug(String.format("-->[redirect] %s >> %s",url, msg));
		 
		 //가상의 view로 만들기 위한 HTML 태그 구성
		 String html ="<!doctype html>";
		 html +="<html>";
		 html +="<head>";
		 html +="<meta charset='" + this.encType + "'>";
		 
		 //메시지 표시
		 if(msg != null) {
			 html += "<script type='text/javascript'>alert('" +msg+"');</script>";
		 }
		 
		 //페이지 이동
		 if(url != null) {
			 html +="<meta http-equiv='refresh' content='0; url=" +url+"'>";
             						//↗대기시간 0초 후에 url로 이동하라
		 }else {
			 html +="<script type='text/javascript'>history.back();</script>";
		 }
		 
		 html +="</head>";
		 html +="<body></body>";
		 html +="</html>";
				 
		 //구성된 HTML을 출력하낟.
		 try {
			 //브라우저에 결과값을 출력하기 위한 out객체를 생성한다. (예외처리 필요)
			 PrintWriter out = this.response.getWriter();
			 
			 //준비된 html태그를 출력한다.
			 out.print(html);
		 }catch(IOException e) {
			 e.printStackTrace();
		 }
		
	}

	public String getencType() {
		return encType;
	}

	public void setencType(String encType) {
		this.encType = encType;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}
}

redirect 함수는 이동할 페이지의 url과 화면에 표시할(alert로) 메세지를 파라미터로 가져간다.

 

redirect함수가 호출되어 실행되면 

 

  • 모든 메서드가 어떻게 동작하는지 확인할 로그를 남기기 위해 이클립스 콘솔에 log를 쓰고 
  • 가상의 view(html페이지)가 만들어지기 시작한다.
  • 만약 redirect에 파라미터로 받은 url과 msg의 값에 따라 if문이 실행되고 

    -여기 'url' if문에서 meta 태그로 페이지가 이동되는데 meta 태그로 이동시키는 이유는

    예를들어

    *회원가입 하고 action에서 결과페이지로 이동할때 자바스크립트로 '완료되었습니다.' 메세지를 보낼수도 있지만 response.sendRedirect()를 써서 페이지를 이동하면 모든 알럿창이 죽는다 그래서 안씀

    *결제페이지에서 window.location()을 쓰면 결제가 완료되었습니다. 알럿창 띄우고 결과 화면으로 가는데 window.location()은 페이지 이동내역이 history에 남는다 그래서 뒤로가기를 누를 경우 또 결제가 될 수도 있다.그래서 meta태그로 화면 이동 구현(자바스크립트와 병행 가능)

    - ↑이런 이유에서 meta 태그로 페이지 이동해야 한다고 하셨는데 막 받아 적느라 정확한지 모르겠다.
  • response.getWriter() 해가지고 결과출력
    (response[응답].[을]getWriter()[출력할겁니다] 라고 이해하기로 했다.)