웹7(application,web.xml)

제이·2023년 4월 22일
0

목록 보기
7/15

application 기본 객체

application은 '기본객체'중에 하나이다. 기본객체는 따로 만들지 않아도 된다.

application 기본 객체는 웹 어플리케이션 전반에 걸쳐서 사용되는 정보를 담고 있다. 예를 들어, application 기본 객체를 사용해서 초기 설정 정보를 읽어올 수 있고, 서버 정보, 웹 어플리케이션이 제공하는 자원(파일)을 읽어올 수도 있다.

Context Root는 웹 어플리케이션을 웹 서버에서 실행시킬 때, 해당 어플리케이션의 최상위 URL 경로를 말한다. 예를 들어, Context Root가 "/myapp"이면 해당 웹 어플리케이션의 최상위 URL은 "http://localhost:8080/myapp"이 된다. 자동으로 설정되어 있지만 이걸 변경하고 싶을 때 web.xml에서 바꾼다.

web.xml : web application 설정을 위한 deployment descriptor(배포설명자)

: web.xml 파일에 초기화 파라미터를 추가하면, JSP는 application 기본 객체가 제공하는 메서드를 사용해서 초기화 파라미터를 사용할 수 있다. jsp에서 어디든 초기화 파라미터를 사용할 수 있다. 초기화 파라미터를 추가하는 방법이 <context-param>.

: WebContent/WEB-INF/web.xml
위치 :여기 안에 있어야 한다 고정이 되어있다. 약속이 되어 있는 거.

  • welcomfile
    💡 프로젝트 루트로 들어오면 너 처음에 뭐 보여줄래? 가 된다. -> 이 이걸 지정하는게 welcome file인듯.
    사용자가 url를 넣고 검색했을 때, welcomfile에 넣은 파일을 보여주는 것인듯.
    '처음 시작하는 페이지'라고 생각하면 될 듯.
    💡 따로 지정 안하고 루트로 들어왔을 때. restart해줘야 한다. -> 톰캣은 .jsp말고 다른 web.xml, javaclass 얘네가 바뀌었을 때는 수동으로 재시작을 해줘야 한다.
    ->근데 이클립스에서 자동으로 물어봄
    (퍼온거)
    일반적으로 웹에서 메인페이지를 보여줄때 메인페이지를 보여주는 url을 'main.do'형태로 설정할경우 사용자가 http://localhost:8080/main.do 형태의 url로 접근하기보다는 http://localhost:8080/ 형태의 주소로 들어오는 경우가 대부분일 텐데 이 경우에는 페이지가 없기 때문에 404에러가 발생할 것입니다. 하지만 <welcome-file-list>를 설정해놓고index.jsp 의 코드를 아래와 같이 작성하여 자연스럽게 main.do페이지로 리다이렉트 시켜준다면 사용자가 비록http://localhost:8080/ 로 접근했을지라도 자연스럽게 메인페이지로 이동하게 됩니다.
    (/퍼온거)

  • context-param : 웹 어플리케이션에서 사용할 수 있는 초기화 파라미터는 web.xml에 <context-param> 태그를 사용하여 추가한다.

  • 클래스도 만들 수 있는데 javaREsources - src - 안에 생긴다.

import해서 쓰면 됨. 메소드같은것도 휴먼클래스에 쓴다. -> jsp(서블렛)는 'view'의 역할이기 때문에 여기서 연산을 하면 안된다. 왜냐하면 이 안의 기능들은 재사용이 안된다. (그래서 선언부를 잘 안쓴다고 했던 것)

application 기본객체의 메서드⭐⭐

  • getInitParameter(String name) : 리턴값Stirng - 이름이 name인 파라미터의 값을 읽어온다.
  • getInitParameterNames() : 리턴값Enumeration - 파라미터의 이름 목록을 리턴함.
    위의 메서드 사용하기 전에 초기화 파라미터를 web.xml 파일에 추가해야한다.
    이 메서드들은 web.xml에서 정의된 파라미터들을 읽어온다!!

<web.xml>

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>04.21</display-name>
  👉<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  👉<context-param>	
  // 어플리케이션 객체로 context-param을 꺼내올 수 있다.
  	<description>로깅여부</description>
  	<param-name>logEnabled</param-name>
  	<param-value>true</param-value>
  </context-param>
  
  <context-param>
  	<description>디버깅 레벨</description>
  	<param-name>debugLevel</param-name>
  	<param-value>5</param-value>
  </context-param>
</web-app>

<readInitParam.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import = "java.util.Enumeration" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>초기화 파라미터 읽어오기</title>
</head>
<body>
초기화 파라미터 목록 :
<ul>
<%
Enumeration<String> initParamEnum = application.getInitParameterNames();👈
// param-name을 다 들고 오는 것이다. 다꺼내오는거
while(initParamEnum.hasMoreElements()){	
// 있습니까? 들고오세용
	String initParamName = initParamEnum.nextElement();	
	%>
<li> <%= initParamName %> = <%= application.getInitParameter(initParamName) %>	
// 이름 알고 있으면 이름이 맞는 value들고오는 거 .다이렉트로 바로 끌고 오는 거. 
//바로 설정했기 때문에 name을 모를 수가 없다. 이거 진짜 많이 쓴다!!!!!
 <%= initParamName %> = <%= application.getInitParameter("logEnable") %>	
 // 이렇게 쓰인다.
<%
}
%>
</ul>
</body>
</html>

<결과>


웹 어플리케이션 초기화 파라미터는 언제 사용할까?

웹 어플리케이션 초기화 파라미터는 이름처럼 웹 어플리케이션을 초기화하는 데 필요한 설정 정보를 저정하기 위해 사용된다. 파일 경로같은 거 지정할 때 초기화 파라미터를 사용한다.

서버 정보 읽어오기

서버정보 : <%= application.getServerInfo()%>
서블릿 규약 메이저 버전 : <%= application.getMajorVersion()%>
서블릿 규약 마이너 버전 : <%= application.getMinorVersion()%>

서블릿 3.1 버전이라는 뜻.

- 로그메시지기록하기(잘 사용되지 않는다.)-중요X

로그는 기록하는 것. 로그 남기는 행위 : 로깅
로깅이 무조건 들어가 있다. -> 어플리케이션 차원에서 기본적으로 로그를 제공해준다.
application.log("application log")
log("JSP log") : jsp로그
로그가 이클립스에서 사용하면 콘솔에 찍히는데 실제로는 파일에 남는다.

-웹어플리케이션 자원구하기(127페이지)⭐⭐⭐

jsp 페이지에서 웹 어플리케이션 폴더에 위치한 파일을 사용해야 할 때가 있다.
개발을 할 때는 내가 어디에 파일이 있는 지 알 수 있는데, 이걸 '배포'했을 때는 어디에 저장이 될 지 알 수 없다.

application 자원 접근 메서드

  • getRealPath(String path) : 웹 어플리케이션 내에서 지정한 경로에 해당하는 자원의 시스템상에서의 경로를 리턴한다. 리턴타입 - String
    배포를 하기 전까지는 알 수가 없다. 내부경로를 실제 디스크상의 경로로 구해온다. 읽기쓰기 둘 다 된다. 개발을 할 때 저게 어디있는 지 알아야 해서 이 메서드를 써준다.
  • getResource(String path) : 웹 어플리케이션 내에서 지정한 경로에 해당하는 자원에 접근할 수 있는 URL객체를 리턴한다. 리턴타입 - java.net.URL
  • getResourceAsStream(String path) : 웹 어플리케이션 내에서 지정한경로에 해당하는 자원으로부터 데이터를 읽어올 수 잇는 InputStream을 리턴한다.

getResourceAsStream() 메소드를 사용하여 리소스 파일을 읽어오면, 파일 시스템에 접근하는 것이 아니므로 보안에 유리하다.
getRealPath() 메소드를 사용하면 리소스 파일의 실제 경로를 구하지 않아도 되므로, 이식성이 높은 코드를 작성할 수 있습니다.

  • 내부경로 : 절대경로같은 거인 듯.
  • 실제경로(디스크상 경로) : 웹 어플리케이션이 배포된 서버의 파일 시스템 상의 경로. 어플리케이션 내부경로와는 달리, 특정 서버의 파일 시스템 구조에 의존하기 때문에 웹 어플리케이션이 배포된 서버에서만 사용할 수 있다.

<readfileDirectly.jsp> - 절대경로

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import = "java.io.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>절대 경로 사용하여 자원 읽기</title>
</head>
<body>

<%
	char[] buff = new char[128];
    한번에 128바이트의 문자열을 읽어들이기 위해 char 배열 buff를 선언
	int len = -1;
	
	String filePath = "C:\\test\\notice.txt";
    //이건 절대경로.
    // 이렇게 넣음! 근데 배포 후에는 알 수 없다.
	FileInputStream fis = null;
	InputStreamReader isr = null;
	try{
		fis = new FileInputStream(filePath);
		isr = new InputStreamReader(fis);
		while( (len = isr.read(buff)) != -1) {
			out.print(new String(buff,0,len));
		}
        
	} catch(IOException ex) {
		out.println("익셉션 발생: " + ex.getMessage());
	} finally {
		try{
			isr.close();
		}catch(Exception e) {}
		try{
			fis.close();
		}catch(Exception e) {}
	}
%>

</body>
</html>

<readFileUsingApplication.jsp> - getRealPath(),getResourceAsStream()

<%@page import="java.io.IOException"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
    <%@ page import = "java.io.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>application 기본 객체 사용하여 자원 읽기</title>
</head>
<body>
<%
	String resourcePath = "/message/notice.txt" ; 
    //이건 절대경로인데 디스상의 경로가 아니라 어플리케이션 내부 경로이다. 
    //문제가 뭐냐면, 디스크상의 경로를 가질 수있으면 좋은데 어디로 배포될지 알 수 없다.
    // '/'앞에는 어디있는지 알 수 없다 그냥 내부에 넣어둔 것이다.
%>
자원의 실제 경로 :<br>
<%= application.getRealPath(resourcePath) %> 👈
// 이게 실제로 디스크상의 경로를 알려준다. 
<br>
------------<br>
<%= resourcePath %>의 내용<br>
------------<br>
<%
	char[] buff = new char[128];
	int len = -1;
	InputStream is = null;
	InputStreamReader isr = null;
	
	try {
		is = application.getResourceAsStream(resourcePath);👈
        //리소스 파일을 읽어와서 출력하는 코드.
		isr = new InputStreamReader(is);
		while((len = isr.read(buff)) != -1) {
			out.print(new String(buff,0,len));
		}
	}catch(IOException e) {
		out.println("익셉션 발생:" + e.getMessage());
	}finally {
		try {
			isr.close();
		}catch(Exception e) {}
		try {
			is.close();
		}catch(Exception e) {}
	}
%>
</body>
</html>

<결과>

<readFileUsingURL.jsp> - getSource()

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
    <%@ page import = "java.io.*" %>
    <%@ page import = "java.net.URL" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>application 기본 객체 사용하여 자원 읽기2</title>
</head>
<body>
<%
	String resourcePath = "/message/notice.txt";
	char[] buff = new char[128];
	int len = -1;
	URL url = application.getResource(resourcePath);👈
	InputStream is = null;
	InputStreamReader isr = null;
	try {
		is = url.openStream();
		isr = new InputStreamReader(is);
		while((len = isr.read(buff)) != -1) {
			out.print(new String(buff, 0 , len));
		}
	}catch(IOException ex) {
		out.println("익셉션 발생" + ex.getMessage());
		
	}finally {
		try{
			isr.close();
		}catch(Exception e) {}
		try{
			is.close();
		}catch(Exception e) {}
	}

%>
</body>
</html>

<결과>

<readFileUsingURL.jsp>

D:\am\kjw\web.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\04.21\message\notice.txt
-> 이게 이클립스에서만 이렇게 나온다.
D:\am\kjw\web.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\04.21\message 이까지만 적고 탐색기에 넣으면 텍스트파일이 나온다.

실제로는 저 위의 경로가 이클립스의 워크스페이스에 있는 것을 web.metadata여기에 복사를 해놓고 web.metadata여기에서 작업을 수행하다. 서비스 내부적으로 그냥 이렇게 사용한다.

경로와 파일을 분리해놓는다. 나중에 파일같은 것이 바뀔 수도 있으니까.
붙어있으면 경로가 바뀌든 파일이 바뀌든 무조건 수정해야한다.
경로가 만약 바뀌면 여러개가 똑같은 위치를 갖고 있는데 하나라도 잘못하면 일관성이 무너진다.
경로 하나만 바꾸면 된다.
경로는 경로대로, 파일은 파일대로 설정하기.
properties로 정보를 따로 두면 컴파일 대상이 아니라서 코드에 부담이 안가고, 코드를 안바꾸고도 값을 구할 수 있다.

web.xml안에 comf/path.txt 를 param-context에 넣고, txt파일의 내용만 바꾸면 restart할 필요없이 경로와 파일을 바꿀 수 잇다. : 설정에 설정을 둔다.

라이브러리,프레임워크 차이는 통제권을 누가 가지고 있느냐?
라이브러리는 순수하게 개발자가 다 결정한다.
프레임워크는 약속대로 뭔가를 해야한다. -> Ioc, 제어의 역전, 통제권을 또 다른 프로그램에게 주는 것.


<wirte, main, Article, doWrite, ArticleUtil.jsp>

먜)
write-> doWrite -> main으로 이어진다.
write에서 적은 값을 doWrite로 넘겨주고, doWrite는 read()해서 그걸 파일에 저장하고 다시 write()해서 main에 값을 넘겨준다. 중간에 doWrite가 들어간 이유는 직접적으로 값을 넘기면 새로고침할 때마다 값이 2번씩 넘어간다. 그래서 중간에 doWrite를 줘서 리다이렉트를 만들어서 넣는다.

<write.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>write.jsp</title>
</head>
<body>
	<a href="main.jsp">목록보기</a>
	<hr>
	<form action="doWrite.jsp" method="post">
		내용 : <input type="text" name="saying" />
		<br>
		글쓴이 : <input type="text" name="writer" />
		<br>		
		<input type="submit" value="글쓰기" />
		<input type="reset" value="초기화" />
	</form>
</body>
</html>

<main.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import="java.io.*" %>   
<%@ page import="java.util.Vector" %> 
<%@ page import="kr.ac.green.*" %>

<%
	String fileName = "articles.dat";
	String tempPath = "/data/" + fileName;
	String realPath = application.getRealPath(tempPath);	
	
	Vector<Article> list = ArticleUtil.read(realPath);	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>main.jsp</title>
</head>
<body>
	<a href="write.jsp">글쓰기</a>
	<hr>
	<table>
		<tr>
			<th>날짜</th><th>내용</th><th>글쓴이</th>
		</tr>
		<%
			if(list != null) {
				for(int i=list.size()-1; i>=0; i--) {
					Article temp = list.get(i);
		%>
		<tr>
			<td><%= temp.getDateString() %></td><td><%= temp.getSaying() %></td><td><%= temp.getWriter() %></td>
		</tr>
		<%
				}
			} else {
		%>
		
		<tr>
			<th colspan="3">아직 등록한 글이 없어요 ㅠ.ㅠ</th>
		</tr>
		<%
			}
		%>
	</table>
</body>
</html>

<dowrite.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import="java.io.*" %>   
<%@ page import="java.util.Vector" %> 
<%@ page import="kr.ac.green.*" %>
<%-- doWrite.jsp --%>
<%
	request.setCharacterEncoding("EUC-KR");

	String fileName = "articles.dat";
	String tempPath = "/data/" + fileName;
	String realPath = application.getRealPath(tempPath);
		
	// 쓰기		
	String saying = request.getParameter("saying");
	String writer = request.getParameter("writer");
	
	Article article = new Article(saying, writer);
	
	Vector<Article> list = ArticleUtil.read(realPath);
	if(list == null) {
		list = new Vector<Article>();
	}		
	FileOutputStream fos = null;
	ObjectOutputStream oos = null;		
	try {
		fos = new FileOutputStream(realPath);
		oos = new ObjectOutputStream(fos);
		list.add(article);
		oos.writeObject(list);
		oos.flush();
		oos.reset();
	} catch(Exception e) {
		e.printStackTrace();
	} finally {
		try {
			oos.close();
		} catch(Exception e){}
		try {
			fos.close();
		} catch(Exception e) {}
	}
		
	response.sendRedirect("main.jsp");	
%>

<Article.java>

package kr.ac.green;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Article implements Serializable{
	private String saying;
	private String writer;
	private Date date;
	
	public Article(String saying, String writer) {
		setSaying(saying);
		setWriter(writer);
		setDate(new Date());
	}

	public String getSaying() {
		return saying;
	}

	public void setSaying(String saying) {
		this.saying = saying;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
	
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
	
	public String getDateString() {
		return sdf.format(date);
	}
}

<ArticleUtil.java>

package kr.ac.green;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Vector;

public class ArticleUtil {
	public static Vector<Article> read(String realPath) {
		FileInputStream fis = null;
		ObjectInputStream ois = null;
		
		Vector<Article> list = null;
		try {
			fis = new FileInputStream(realPath);
			ois = new ObjectInputStream(fis);
			list = (Vector<Article>)ois.readObject();
		} catch(Exception e) {
			
		} finally {
			try {
				ois.close();
			} catch(Exception e) {}
			try {
				fis.close();
			} catch(Exception e) {}
		}
		return list;
	}
}

<결과>

profile
Hello :)

0개의 댓글