Oimb
172
2018-08-10 17:54:09
10
121

<jsp : forward> 의 경우 context path 가 자동으로 붙나요??


viewPageURI = request.getContextPath() + "/chap07/view/b.jsp";


이러한 형태로 할경우 경로 에러가 뜨는데 원인을 보면


webApp/webApp/chap07/view....


이런형태로 context path 가 중복되어 뜹니다.

원래 forward는 이런가요??

0
0
  • 답변 10

  • 아야로
    597
    2018-08-10 21:40:01 작성 2018-08-10 21:40:48 수정됨

    컨텍스트 패스는 클라이언트에서 웹에 요청하기 위해 필요한 것으로 서버에서 사용되고 끝나는 액션태그에는 불필요합니다.

    현재 액션태그에 쓰신 URL은 /{contextPath}/chap07/view/b.jsp와 같으며,

    위 코드를 해석한 서블릿 컨테이너는 자신의 웹컨텐츠 최상위 경로부터 시작해 그대로 검색하게 됩니다. 그 결과 아래처럼 없는 경로라는 에러가 뜨겠구요.

    /{최상위 경로}/{contextPath}/chap07/view/b.jsp

    또한 웹 최상위 경로와 컨텍스트 패스의 이름을 동일하게 지었다면 혼동을 주니 변경하는게 좋습니다.

    request.getContextPath()는 "/resources/img04.png" 와 같이 클라이언트에서 해석할 주소들 앞에 붙여주는 용도로 사용하십시오.

    0
  • Oimb
    172
    2018-08-13 16:11:03

    컨텍스트 패스이름은 relay 로   최상위 경로와 이름을 다르게 지은 상태입니다. 다만 예를 들다보니 저렇게 됬네요

    그런데 제가 잘이해가 되질 않아서 다시 질문드리는데요

    말씀하신 경로

    /{최상위 경로}/{contextPath}/chap07/view/b.jsp  이것은 이해가 됩니다. 실제로 다른곳에서 컴파일 되면서 저렇게 경로가 변하니까요

    그런데 다른곳에서는 저 경로를 이해하고 잘되는데 forward 태그에서만 되질 않아서 질문드립니다.
    forward 태그에서만 저렇게 코드를 써주면 /contextPath}/{contextPath}/chap07/view/b.jsp 

    이런식으로 인식 합니다.....

    0
  • 아야로
    597
    2018-08-13 16:47:29

    Oimb

    괜찮으시다면 해당 jsp파일만 통째로 올려주셨으면 합니다.

    어렵다면 suphiapusils@gmail.com 쪽으로 보냇 도 좋습니다.

    확인후에 말씀드리겠습니다.

    0
  • Oimb
    172
    2018-08-13 17:27:05 작성 2018-08-13 17:27:43 수정됨

    최대한 간추려서 올립니다!

    select.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <%=request.getContextPath()%> <!-- ch07-10-->
    	<form action="<%=request.getContextPath()%>/chap07/view.jsp"> <!-- /ch07-10/chap07... -->
    		보고 싶은 페이지 선택:
    		<select name="code">
    			<option value="A">A</option>
    			<option value="B">B</option>
    			<option value="C">C</option>
    		</select>
    		<input type="submit" value="이동">
    	</form>
    	
    </body>
    </html>


    view.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%	request.setCharacterEncoding("utf-8"); %>
    <%
    	String code = request.getParameter("code");
    	String viewPageURI = null;
    	
    	
    	if("A".equals(code)){
    		viewPageURI = request.getContextPath()+"/chap07/view/a.jsp"; // 이 부분에서 404 에러
    	}else if("B".equals(code)){
    		viewPageURI = "/chap07/view/b.jsp";
    	}else if("C".equals(code)){
    		viewPageURI = "/chap07/view/c.jsp";
    	}
    	
    %>
    <%=viewPageURI %>  <!--  이 부분은 한번 찍어보시길  아래 jsp forward를 주석처리하신다음에-->
    <jsp:forward page="<%=viewPageURI %>"></jsp:forward>


    참고로 server.xml 의 context path는 디폴트입니다. 건든것 없습니다.

    이후 각각 a.jsp b.jsp c.jsp 를 만들어줬습니다. 걍 비어있는 파일이에요

    0
  • 아야로
    597
    2018-08-13 18:34:50

    이런 구조가 있다면 여기서의 웹 최상위 경로는 WebContent 입니다.


    WebContent/chap07/view/a.jsp

    즉 위의 경로로 검색이 이루어져야 하는데 현재 코드는

    <jsp:forward page="{contextPath}/chap07/view/a.jsp"></jsp:forward>
    ▼
    WebContent/{contextPath명}/chap07/view/a.jsp

    위 처럼 엉뚱한 폴더를 훑고 있습니다.

    첫글에 말씀드렸듯 서버에서의 동작에는 컨텍스트 패스가 불필요합니다.


    view.jsp에서의 옳은 코드는 아래와 같아야지요.

    <jsp:forward page="/chap07/view/a.jsp"></jsp:forward> // 절대 경로
    <jsp:forward page="./view/a.jsp"></jsp:forward> // 상대 경로




    0
  • Oimb
    172
    2018-08-14 09:43:58

    그렇다면 select.jsp 에서 form 태그의  action의 속성값은 왜 절대경로가 저렇게 될수 있는 것인가요??

    0
  • 아야로
    597
    2018-08-14 10:04:46

    Oimb

    action 속성에 적은 값은 브라우저에서 쓰이는 값입니다.

    서버의 구조를 모르는 브라우저 입장에서는 컨텍스트 패스가 필요하지요.


    <form action="<%=request.getContextPath()%>/chap07/view.jsp">

    위와 같이 적은 값은 서버에서 아래의 코드로 변환되어 브라우저에 전송됩니다.

    <form action="/{contextPath명}/chap07/view.jsp" >


    위 코드를 해석한 브라우저는 아래와 같이 URL을 재조합해 서버로 요청을 보냅니다.

    프로토콜://도메인:포트번호 + /{contextPath명}/chap07/view.jsp


    만약 아래와 같이 '점'을 이용해 상대 경로로 URL을 작성했다면

    <form action="./chap07/view.jsp">

    브라우저는 아래와 같이 재조합해 요청을 보내게 됩니다.

    프로토콜://도메인:포트번호 + /{컨텍스트 패스를 포함한 현재 URL 바로 전 슬래시까지} + /chap07/view.jsp


    다시 말씀드리지만 서버에선 컨텍스트 패스가 불필요하고, 브라우저에선 필요합니다.

    서버사이드와 클라이언트 사이드의 영역을 정확히 이해하면 좋겠습니다.

    0
  • Oimb
    172
    2018-08-14 10:49:07

    흐음... 그런데 에러에서는 왜 WebContent 붙어  훑지 않고 프로젝트 파일 부터 경로를 탐색한것처럼 나오나요?

    viewPageURI = request.getContextPath()+"/chap07/view/a.jsp";  이렇게 기술 할 경우


    message 에서  저런 경로 오류가 나는데 여기서 ch07-10 은 프로젝트 파일입니다. 답변해주시는 분의 test 프로젝트 처럼요

    이것 때문에  제가 헷갈려 하는 것인데...

    일단은... 

    '절대 경로'로 기입시

    브라우저가 아닌 서버단에서는 자동으로 contextpath를 아니까 자동으로 붙여준다.. 정도로 이해하고 있습니다.(맞나....)

    다만 form 의 액션 태그는 브라우저 입장이므로 contextpath를 알지 못하니 붙여줘야만 경로가 붙는다...

    (form 태그의 action 부분을 <form action="/chap07/view.jsp"> 이렇게 줄여버리면 역시 에러가납니다.)


    그리고 

    상대 경로로 기입시

    말씀하신대로 /contextpath/.... 이러한 형태로 재해석 하는 것이구요


    흐음 제가 이해한게 맞았으면 좋겠네요... 이 부분이 자세하게 설명되어있질 않아서 이해하는데 어려움이 있네요!!


    0
  • 아야로
    597
    2018-08-14 11:52:16 작성 2018-08-14 11:53:51 수정됨

    Oimb

    한 질문에 다섯 번 답해드리는 경우가 다 있네요 ㅎㅎ

    의문을 풀어가는 모습이 보기 좋습니다.


    먼저 url이 '/' 슬래시로 시작하면 최상위 경로부터 검색하라는 뜻이 됩니다.

    서버입장에서의 최상위 경로는 WebContent고, 브라우저 입장에서는 포트번호 까지 입니다.

    그렇기에 브라우저에서 쓸때는 포트번호 다음에 쓸 컨텍스트 패스를 붙여주는 것이고,

    서버에선 WebContent 밑을 바로 조회 할 수 있기에 컨텍스트 패스가 불필요합니다.


    둘째, 그럼 왜 /ch07-10/WebContent/ch07-10/chap07/view/a.jsp라고 에러가 안뜨고

    /ch07-10/ch07-10/chap07/view/a.jsp라고 에러가 뜨느냐.

    이건 저 경로를 검색하고 에러페이지를 뱉어낸것이 그렇게 짜여진 서블릿 컨테이너 이기 때문입니다.

    구조 자체가 현재 내 컨텍스트 패스내의 웹 최상위 경로에서 /ch07-10/chap07/view/a.jsp 를 훌어보도록 되어있고, 에러메시지도 저렇게 뱉도록 되어있습니다.

    에러 메시지의 목적이 잘못된 요청임을 알려주고 올바른 경로로 요청하도록 돕기 위함인데 자동으로 검색되는 WebContent를 넣어주면 혼란만 초래하지요.



    너가 http://localhost:8080/ch07-10/ch07-10/chap07/view/a.jsp 로 요청을 보내서 에러가 났으니

    http://localhost:8080/ch07-10/chap07/view/a.jsp로 다시 요청을 해봐라 라고 유도할 수 있습니다.

    서버입장에서 브라우저가 위 URL로 요청을 보내면 알아서 WebContent부터 검색을 해주는데 쓸데없이 에러메시지에 WebContent라는 경로를 노출할 이유가 없습니다.

    0
  • Oimb
    172
    2018-08-14 13:19:36

    자세한 설명 감사합니다.

    되게 많은 질문을 했는데 하나하나 꼬집어서 알려주셔서 감사합니다.!

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.