- 각 영역에 대한 모든 처리와 테스타가 완료되었다.
- 만일 에러가 발생한다면 모든 문제는 화면 쪽에서만 발생한다고 말할 수 있다.
- 화면에는 JSP와 JavaScript(jQuery), CSS, HTML을 이용해 작성한다.
- 화면을 개발 하기 전 반드시 화면의 전체 레이아웃이나 디자인이 반영된 상태에서 개발하는 것을 추천한다.
- 최근 유행하는 BootStrap을 이용한 무료 디자인을 찾아보는 것도 좋다. (https://themes.getbootstrap.com/)
- 예제에서 사용할 디자인은 'SB Admin2'를 이용한다.
- 스프링 MVC의 JSP를 처리하는 설정은 servlet-context.xml에 아래와 같이 작성되어 있다.
< servlet-context.xml > <resources mapping="/resources/**" location="/resources/" /> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean>
- 스프링 MVC의 설정에서 화면 설정은 ViewResolver라는 객체를 통해 이루어지는데, 위의 설정을 보면 '/WEB-INF/views'라는 폴더를 이용한다.
- '/WEB-INF' 경로는 브라우저에서 직접 접근할 수 없는 경로이음로 반드시 Controller를 이용하는 모델2 방식에서는 기본적으로 사용하는 방식이다.
- 게시물 리스트의 URL은 '/board/list'이므로 최종적인 '/WEB-INF/views/board/list.jsp'가 된다.
- 해당 경로에 list.jsp 파일을 추가한다.
< views/board/list.jsp > <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dte"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>List Page</h1> </body> </html>
- list.jsp는 우선 정상적으로 URL 처리가 되는지 확인해야 하므로 Tomcat으로 실행해서 확인한다.
- 'http://localhost:8080/controller/board/list'로 접근해 아래와 같은 화면이 보이는지 확인한다.
- Eclipse 상에서 실행될 때는 '/'경로로 설정되지 않고, 위의 화면처럼 '/controller' 경로를 가지게 된다.
- 이는 Tomcat의 설정 혹은 프로젝트의 'Web Settings'를 이용해 '/'로 조정한다.
- 위와 같이 절대 경로('/')를 지정한 후 Tomcat을 재시작 해서 'http://localhost:8080/board/list'가 정상적으로 호출되는지 확인한다.
※ 주의 ※
- 정상적으로 '/board/list' 페이지가 동작한다면 SB Admin2의 pages 폴더에 있는 tables.html의 내용을 list.jsp의 내용으로 그대로 복사해서 수정하고 실행한다.
- 수정할 때는 list.jsp의 상단에 JSP의 Page 지시자는 지우지 않아야 한다.
< views/board/list.jsp > <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> ... 이하 생략 ...
- 브라우저에서는 CSS 등이 완전히 깨진 상태이므로 텍스트만 출력된다.
- CSS와 JS 파일들의 경로를 수정하는 작업은 브라우저의 개발자 도구를 통해 확인하여 진행한다.
- 개발자 도구를 통해 현재 브라우저의 Network 부분을 확인하고, 페이지를 '새로고침'하면 잘못된 URL의 정보를 아래와 같이 확인할 수 있다.
- SB Admin2의 CSS 경로는 'http://localhost:8080/vendor/bootstrap/css/bootstrap.in.css' 경로이므로 현재 프로젝트에서는 제대로 서비스될 수 없다.
- org.zerock.config.WebConfig 클래스에는 CSS나 JS 파일과 같이 정적인 (static) 자원들의 경로를 'resources' 라는 경로로 지정하고 있다.
< servlet-context.xml > <resources mapping="/resources/**" location="/resources/" />
- SB Admin2의 압축을 풀어둔 모든 폴더를 프로젝트 내 webapp 밑의 resources 폴더로 복사해 넣는다.
- 파일들을 resources 경로로 넣어도 아직 페이지에서 경로를 수정하지 않았기 때문에 문제가 생기는 것은 동일하다.
- list.jsp 파일에서 CSS나 JS 파일의 경로를 '/resources'로 시작하도록 수정한다.(가장 간단한 방법은 아래와 같이 Find/Replace를 이용하는 것이다.)
- 수정 후 브라우저를 통해 '/board/list'를 호출하면 다음과 같이 CSS가 정상적으로 적용된 화면을 볼 수 있다.
- CSS, JS 파일들의 링크는 모든 페이지에서 사용될 것이므로 화면에서 디자인이 깨지지 않는 것을 확인 후 다음 내용을 진행한다.
- JSP를 작성할 때마다 많은 양의 HTML 코드를 이용하는 것을 피하기 위해 JSP의 include 지시자를 활용해 페이지 제작 시 필요한 내용만 작성할 수 있게 사전에 작업해야 한다.
- 현재 프로젝트 views 폴더에 includes 폴더를 작성하고, header.jsp와 footer.jsp를 선언한다.
- header.jsp는 페이지에서 핵심적 부분이 아닌 영역 중에 위쪽의 HTML 내용을 처리하기 위해 작성한다.
- 브라우저에서 '검사'기능을 활용하면 특정한 < div >가 어떤 부분을 의미하는지 확인할 수 있다.
- SB Admin2는 < div > 들 중에서 id 속성값이 'page-wrapper'부터가 핵심적인 페이지의 내용이므로 list.jsp 파일의 처음 부분에서 < div id='page-wrapper'> 라인까지 잘라서 header.jsp의 내용으로 처리한다.
< header.jsp > <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>SB Admin 2 - Bootstrap Admin Theme</title> <!-- Bootstrap Core CSS --> <link href="/resources/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"> ... 생락 ...
< list.jsp > <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="../includes/header.jsp" %> <div class="row"> <div class="col-lg-12"> <h1 class="page-header">Tables</h1> ... 생략 ...
- @header.jsp를 '<@include...'로 처리한 후에 다시 브라우저 화면이 깨지지 않는지 확인한다.
- < div id="page-wrapper" > 끝나는 태그부터 마지막까지는 footer.jsp의 내용으로 작성한다.
< footer.jsp > </div> <!-- /#page-wrapper --> </div> <!-- /#wrapper --> <!-- jQuery --> <script src="/resources/vendor/jquery/jquery.min.js"></script> <!-- Bootstrap Core JavaScript --> <script src="/resources/vendor/bootstrap/js/bootstrap.min.js"></script> <!-- Metis Menu Plugin JavaScript --> <script src="/resources/vendor/metisMenu/metisMenu.min.js"></script> ... 생략 ....
< list.jsp > ... 생략 ... <!-- /.table-responsive --> </div> <!-- /.panel-body --> </div> <!-- /.panel --> </div> <!-- /.col-lg-6 --> </div> <!-- /.row --> <%@include file="../includes/footer.jsp" %>
- header.jsp와 마찬가지로 수정 뒤 브라우저를 통해 정상적으로 동작하는지 확인한다.
- JSP 페이지를 작상하다 보면 JavaScript로 브라우저 내에서 조작이 필요한 경우가 많다.
- 예제는 jQuery를 이용할 것인데, 문제는 위의 방식대로 처리했을 때 jQuery 라이브러리가 footer.jsp 내에 포함되어 있다는 점이다.
- 성능을 조금 손해 보더라도 jQuery를 header.jsp에 선언해 두면 작성하는 JSP에서 자유롭게 사용할 수 있으므로 수정해야 한다.
- footer.jsp의 상단에 있는 jquery.min.js 파일의 < script > 태그를 제거한다.
< footer.jsp > <!-- jQuery --> <!-- <script src="/resources/vendor/jquery/jquery.min.js"></script> -->
- jQuery는 인터넷을 통해 다운로드 받을 수 있게 jQuery의 링크를 검색해 header.jsp 내에 추가해야 한다.(https://developers.google.com/speed/libraries/와 같은 페이지를 이용한다.)
< header.jsp - jQuery 링크 추가 > <div id="page-wrapper"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
- SB Admin2는 반응형으로 설계되어 있어서 브라우저의 크기에 맞게 모바일 용으로 자동으로 변경되지만 jQuery의 최신 버전을 사용한 상태에서는 모바일 크기에서 '새로고침' 시 메뉴가 펼쳐지는 문제가 발생한다.
- 아래의 그림과 같이 메뉴가 펼쳐져 있는 것을 볼 수 있다.
- 이 문제를 해결하기 위해 includes 폴더 내 footer.jsp에 아래와 같은 코드를 기존 코드 대신에 추가한다.
< footer.jsp > <script> $(document).ready(function() { $('#dataTables-example').DataTable({ responsive: true }); $(".sidebar-nav") .attr("class", "sidebar-nav navbar-collapse collapse") .attr("aria-expanded", 'false') .attr("style","height:1px"); }); </script> </body>