웹5(리다이렉트, get방식과 post방식, request 헤더)

제이·2023년 4월 19일
0

목록 보기
5/15
post-thumbnail
  • 업무가 무엇인지를 결정하는 엄청나게 중요한 정보. 사용자가 해달라는 것을 해줘야 한다. 사용자가 뭐를 해달라고 하는 지가 중요하다.
    파라미터 넘넘 중요하다.

  • 200은 ok
    404오류 - 대상이 존재하는 지 안하는지를 확인해야한다.
    500오류 - 서버 실수.

  • 400번대는 클라이언트의 실수 -> 요청한 게 없는데 왜 요청했니
    500번대는 서버의 실수 -> 서버에서 연산을 하다가 예외가 뜬 것이다.

  • jsp내용이 바뀌었으면, 창을 그대로 놔두고 f5누르면 된다.

<start.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>start.jsp</title>
</head>
<body>
	<!-- 
		아래 정보를 전달받아 id가 choonsik, password가 1234이면 로그인 성공,
		아닌 경우 로그인 실패를 화면에 표시하는 end.jsp를 구현하라.
	 -->
	로그인1
	<form action="end.jsp" method="post">
		<label for ="uid">ID</label>
		<input type="text" name="uid" id="uid"/>
		<br>
		
		<label for = "upw">Password</label>
		<input type ="password" name ="upw" id="upw" />
		<br>
		<input type ="submit" />
	</form>
	
	로그인2	//아이디가 중복되면 안된다. 그래서 id는 다르게 해준다.
	<form action="end2.jsp" method="post">
		<label for ="uid2">ID</label>
		<input type="text" name="uid" id="uid2"/>	
		<br>
		
		<label for = "upw">Password</label>
		<input type ="password" name ="upw" id="upw2" />
		<br>
		<input type ="submit" />
	</form>
</body>
</html>

<end.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%
	//1. 사용자가 입력한 파라미터를 가져온다.
	String uid = request.getParameter("uid");
	String upw = request.getParameter("upw");
	
	//3. 메세지같은걸 만든다.
	String message = "로그인에 실패했습니다.";
	String linkText = "다시 로그인";
	
	//2. uid, upw 검사
	if(uid.equals("choonsik")&&upw.equals("1234")) {
		//이거는 사용자한테 보여줘야해서 body로 가야함
		message = "로그인에 성공했습니다.";
		linkText = "로그아웃";
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>end.jsp</title>
</head>
<body>
	<%= message %>
	<br>
	<a href="start.jsp"><%= linkText %></a>
</body>
</html>

<end2.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>end2.jsp</title>
</head>
<body>
	<%
		boolean success = checkLogin(request.getParameter("uid"), request.getParameter("upw"));
		if(success) {
	%>
			<h1>로그인성공!!!</h1>
			
	<% 
		}else {
	%>
			<h1>로그인 실패!!!</h1>
	<% 
		}
	%>
	
	
</body>
</html>
<%!
	private boolean checkLogin(String uid, String upw) {
		return uid.equals("choonsik") && upw.equals("1234");
}
%>

코드설명

로그인에 성공했는지 판단하려고 할 때, 추가로 필요한 정보가 id,pw이다. 이게 파라미터이다.

  • 스크립트릿이나 선언부는 어느 위치에 있어도 상관없다.
    그러나 표현식은 바디안에 있어야 한다.
    그런데 표현식에서 어떤 변수값을 사용하려고 하면은 반드시 그 위에 스크립트릿이 있어야 한다.
    표현식을 쓰기 전에 스크립트릿이 있어야 한다. 변수를 안쓰면 코드 어디에 있든지 상관없다.
    그래서 위의 코드(end.jsp)처럼 body 밖에 String message로 정의 해놓고 body안에 적는다.
  • message는 보여지는 것이라서 위치에 영향을 미친다.
    그래서 body안에 들어가 있어야 한다.

id는 html에서 쓰는 것이다. 서버에서는 name을 써야한다.

  • 사용자가 뭘 해도 바뀌지 않는 것 = 정적
    사용자가 뭘 하면 바뀌는 부분 = 동적
    로그인에 성공하든 말든 "다시 로그인"이라는 부분이 나온다 이런게 정적.
    근데 로그인에 성공하면 "로그아웃"이라고 바뀌게 만든데 이런게 동적.


<사진설명(먜)>
start.jsp를 구글에 검색해서 서버에 보낸다. 그럼 서버에서 start.jsp 화면을 보내준다. 그 다음 id와 비번을 쳐서 제출을 누르면, end.jsp와 함께 파리미터인 uid:choonsik과 upw:1234를 같이 들고 서버로 간다.
그럼 서버가 로그인에 성공했다는 end.jsp 화면을 보여준다.

get방식과 post방식

읽기의 작업은 get방식을 쓴다.
읽는다고 해서 뭔가 바뀌지 않으니까.
읽기는 제외한 작업들은 post방식을 쓴다.

post방식에서 헤더와 바디는 나누는 기준은 공백처리된 부분이다.

톰캣이 받아서 리퀘스트로 제공해준다.
정의,선언을 안함 -> 아무때나 사용할 수 있어서 기본객체라고 한다.
jsp에서만 기본객체이다.


인코딩

  • 인코딩 : 문자 -> 바이트값
    디코딩 : 바이트값 -> 문자

파일을 저장할 때 어떤 인코딩을 사용하는지..
<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>

  1. 툴자체에서 제공하는 인코딩(타지칠때)-위의 사진에 나오는 것.
  2. pageEncoding : (WAS가 읽어낼때)서버에서 연산이 될때 인코딩
  3. charset : (결과물을 브라우저한테 주는데 브라우저가 그걸 읽을 때 또 인코딩이 한번 더 들어간다.)응답으로 보냈을 때 브라우저가 처리하는 인코딩방식
    이거 3개 다 일치해야지 한글이 깨지지 않는다.
    데이터베이스 인코딩이 나중에 추가될 것이다.
  • 강제로 인코딩을 하는 방식
    String kor = request.getParameter("name");
    kor = new String(kor.getBytes("8859_1), "euc_kr");

  • 만약 웹 브라우저가 인코딩을 할 때 사용한 캐릭터셋과 웹서버가 디코딩할 때 사용한 캐릭터셋이 다르면, 웹서버는 잘못된 파라미터 값을 사용하게 된다. 그럴 때, 브라우저에서 javascript가 한글을 미리 인코딩해서 보내면 한글이 깨지지 않는다 -> 서버에서 안깨진 것으로 받아낼 수 있다.
    (브라우저에서 실행하는 언어-html,css,javascript)

request.setCharacterEncoding("utf-8");
이 부분은 디코딩 하기 전에 설정해줘야 한다.
즉, 코드를 읽기 전에 이걸 적어줘야 한다. 그렇지 않으면 이미 읽은 코드의 설정으로 읽어서 위의 코드가 무용지물이 된다.

request 헤더 정보 처리

request 헤더 메서드

  • getHeader(String name) : 지정한 이름의 헤더 값을 구한다. 리턴타입은 String
  • getHeaders(String name) : 지정한 이름의 헤더 목록을 구한다. 이름은 하나인데 값은 여러개. 리턴타입은 java.util.Enumeration.
  • getHeaderNames() : 모든 헤더의 이름을 구한다.
  • getIntHeader(String name) : 지정한 헤더의 값을 정수 값으로 읽어온다. 숫자로 표시되는 애들을 int값으로 받는거.
  • getDateHeader(String name) : 날짜 관련된 거. 리턴값은 long.

코드

<%@ 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>
	<%
	Enumeration headerEnum = request.getHeaderNames();
	while(headerEnum.hasMoreElements()) {
		String headerName = (String)headerEnum.nextElement();
		String headerValue = request.getHeader(headerName);
	%>
	<%= headerName %> = <%= headerValue %> <br>
	<%
	}
	%>
</body>
</html>

<결과>

셋째줄부터 끝까지가 클라이언트 정보이다.

response객체

: 응답을 나타내는 객체

응답 정보와 관련해서 제공하는 기능

  • 헤더정보입력
  • 리다이렉트하기⭐⭐⭐

response 기본 객체 헤더 메서드

: 크게 중요하지는 않은 듯.

  • addDateHeader(String name, long date)
  • addHeader(String name, String value)
  • addIntHeader(String name, int value)
  • setDateHeader(String name, Strin value).....

메서드들이 이번에는 add로 시작함 : 메소드 이름만 보더라도 기존에 헤더 정보에 추가하는거.
브라우저에서 우리가 추가한다고 해도, 한계가 있기 때문에 영향을 많이 안받는다.

대부분의 정보는 WAS가 헤더정보를 다채워주는데 저런 메소드 통해서 뭔가 추가되고 바꿀 수 있다는 것만 알면되고 WAS가 response정보를 알아서 해주기때문에 쓸일은 별로 없다.

정보를 만들어내는 애여서 이름도 벨류도 내가 정한다.


캐시

:동일한 데이터를 중복해서 로딩하지 않도록 할 때 사용한다.
네이버화면을 켰을 때 새로운 화면이 아니라, 내 컴퓨터에 저장되어있는 화면을 보여준다. 그때 잠깐 저장한 공간을 캐시라고 한다.
서버로부터 받아 온 게 아니라서 동기화가 깨질 수 있다.

캐시에 저장하지 말라고 하는 코드

: 이 코드가 적힌 페이지는 캐시에 저장하지 말라고 하는 코드이다.
: 다음에 캐시가 필요없는 부분을 짤 때 저기 4개의 코드를 다 사용하면 된다.
: 첫째줄은 HTTP 1.1버전이다.
: 마지막줄에서 "Expires"은 만료기간이고, 1L은 1/1000초라는 뜻이어서, 그냥 캐시가 걍 스쳐지나가는 느낌이다.

response.setHeader("Cache-Control","no-cache"
response.setHeader("Cache-Control","no-store");
response.setHeader("Pragma","No-cache");
response.setDateHeader("Expires",1L);

  • 캐시사용O : 게시판에서 글을 읽고 뒤로갈 때 -> 내가 저장했던 이전페이지를 다시 보는 거 이전에 저장했던 정보를 그대로 놔두는거.
  • 캐시사용X : 목록으로 돌아갈 때 -> 목록을 새로 받음

리다이렉트⭐⭐

<first.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>first.jsp</title>
</head>
<body>
	<h1>first.jsp</h1>
	<%
	/*1.*/ response.sendRedirect("second.jsp");
    
    //리다이렉트라고 한다. 
    //나는 분명히 first를 실햇는데 사용자는 second를 보게 된다. 
    //원래는 사용자에게 보여줘야되는데 안보여주고 다시 서버에 세컨드를 요청한다. 
        
	/*2.*/response.sendRedirect("second.jsp?some=abc");
    System.out.println(request.getParameter("myvalue"));
    
	%>
	
</body>
</html>

<second.jsp>

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>second.jsp</title>
</head>
<body>
	<h1>second.jsp</h1>
	<%
	/*1.*/response.sendRedirect("second.jsp?some=abc");	
    // 이렇게 하면.. 값만 빼올 수 있다??? 
    //이거 있는 파라미터 값(abc)은 우리(서버측)가 결정한다. 
    //사용자가 결정한 거 아니다. 
    //그래서 오류가 나는 한글로 쓸 필요가 없다. 
    //어차피 내가 저하는 거라서. 
    //아래의 <a>태그도 여기서 우리가 페이지를 작성하기 때문에 
    //한글을 써서 오류같은거 낼 필요 없다. "myvalue=def"부분.

<hr>
    /*2.*/<%= request.getParameter("some") %>
	<a href="first.jsp?myvalue=def">go first</a>
	%>
</body>
</html>

<각 2번 코드 결과>

리다이렉트 설명

<first.jsp>설명과 함께 리다이렉트 설명

⭐리다이렉트

  • 정보가 수정이 되었다면, 중복 요청을 막기위해 리다이렉트를 해줘야 한다.

  • 나는 분명히 first를 실행했는데 사용자는 second를 보게 된다.
    원래는 사용자에게 보여줘야 되는데 사용자에게 보여주지않고 다시 서버에 second.jsp를 요청한다.

  • 요청이 무엇인가?
    요청은 사용자의 의도를 담고 있는 것이다. 서버가 뭘 해야되는 지 결정해주는 게 리퀘스트다.

  • c,r,u,d 만들 때 무조건 들어간다.
    새로고침막기라고 검색하면 나온다.

도대체 왜 사용하나?
반드시 필요한 상황이 있다.
post방식으로 바디에 넣어놔도 결제가 될 수 있는 경우가 있는데 그게 '새로고침'이다. 마지막 요청을 다시 한번 보내는 게 새로고침이다.
결제완료를 하고 난 후에 '새로고침'을 한번 더 하면 또 한번 결제된다.
우리가 파라미터를 결정하는 게 아니라 브라우저가 기억하고 있다가 다시 요청하는 것이다. (서버측에서 해결할 수 없는 문제인 듯)
그리고 또 결제 완료했다가 '뒤로가기'하면 또 결제된다.

뭔가 리다이렉트를 사용하는 이유가 요청같은 것이 변할 때(수정이 일어나는 일)인데, 이 수정이 일어나는 것 중 하나가 post방식이니까 결론적으로 보면 post방식 쓰면 리다이렉트를 쓰는 거인 것 같음.

즉, '새로고침' 과 '뒤로가기'를 눌렀을 때 문제가 생길 수 있는 경우에 리다이렉트를 사용한다!

리다이렉트를 설정 한 후 결제하고 뒤로가기 하면 '만료된 페이지입니다.' 라고 나온다.
수정할 때 사용한다.

⭐⭐⭐'post방식'이랑 '리다이렉트'는 한세트로 가야한다. post방식이어도 새로고침, 뒤로가기로 다시 정보가 요청되니까 리다이렉트로 막아야 한다.

리다이렉트하더라도 끝까지 코드를 끝까지 다 읽고 값을 보내기 때문에
리다이렉트코드 밑에 코드를 적어도 다 읽힌다.
리다이렉트 밑에 쓴다고 해서 실행이 안되는 게 아니다. 실행이 된다.
그래서 System.out.println(request.getParameter("myvalue"));하면 값이 읽힌다.
나중에 포워드라는 게 나온다. 실행되는 과정의 절차같은 게 다르다. 이건 포워드가 나오면 밑의 코드가 읽히지 않는 느낌.

<second.jsp> 설명
브라우저한테 전달되는 것은 리스폰스객체가 아니다.
WAS가 response의 라인,헤더,바디 다 채워놓고 그냥 텍스트형태로 바꿔서 전송해준다.
브라우저는 자바를 못 읽는다. 즉, 리스폰스 객체를 못 읽는다.
웹서버는 그냥 접속만 받는 애다. 큰의미없다. 실제로는 WAS가 다한다.
WAS가 자바를 실행할 수 있는 게 다 가지고 있다.

http://localhost:8080/04_19/second.jsp?some=abc
그리고 "first.jsp"로 들어가면 위의 주소가 나온다.
리다이렉트 했기때문에 클라이언트가 알 수는 없지만, 리다이렉트 주소로 secon.jsp라고 지정해 놓아서 저렇게 주소에는 second.jsp라고 남아 있다.

<퍼온거>
페이지 이동 방법에는 다양한 방법이 있는데 리다이렉트는 다음과 같은 차이가 있다.

  1. 클라이언트에서 이동경로 결정한다.
    <a> / 태그
    submit / 타입

  2. 서버가 이동경로를 결정한다.
    sendRedirect / 메소드

profile
Hello :)

0개의 댓글