2013년 10월 21일 월요일

아래 Spring Framework 게시판 리스트 보기 예제를 따라해 보도록

아래 Spring Framework 게시판 리스트 보기 예제를 따라해 보도록 하세요~
 
감사합니다.
 
Spring 게시판 구현:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
      
-  1차 목표 기능
 
기본 게시판 기능(리스트보기답글커멘트게시물 입력수정)
게시물 내용 미리보기(Ajax연동)

기술요소 : Ajax, Spring MVC, Spring JDBC, Spring DI
 
- 2차 목표 기능
 
기본 게시판 기능(리스트보기답글커멘트게시물 입력수정)
로그인 기능(인증한 경우에만 글읽기입력수정삭제 가능)
파일업로드
DB Spring AOP를 이용한 로깅
SQL문을 MyBatis를 이용하여 별도 XML로 관리

기술요소 : Ajax, Spring MVC, Spring JDBC, Spring DI, Spring AOP, MyBatis 결합
 
 
1.     시작하기
 
-       이클립스 프로젝트명(Context) onjboard1
-       이클립스 STS Plug-In을 설치 하였으며 MAVEN, MAVEN Plug-In도 설치하였음
-       Spring MVC Project를 작성(프로젝트 이름은 onjboard1)
-       Spring Version 3.2.3
-       오라클에 접속하여 scott 계정에서 게시판용 테이블 및 데이터 2건 만들자
 
 
drop table board
create table board (
    seq number(10),
    name varchar2(20),
    passwd varchar2(20),
    title varchar2(500),
    content varchar2(4000),
    filename varchar2(100),
    regdate date default sysdate,
    readcount number(10),
    reply number(10),
    reply_step number(10),
    reply_level number(10)
)
 
drop table comment_t
create table comment_t(
    seq number(10),
    name varchar2(20),
    comm varchar2(4000)
)
 
drop sequence board_seq
create sequence board_seq start with 1 increment by 1
 
insert into board (seq, name, passwd, title, content, readcount, reply_step)
values (board_seq.nextval, '오엔제이''1111''질문입니다''SQL 배울 있는 과정이 뭐죠?', 0, 0)
 
insert into board (seq, name, passwd, title, content, readcount, reply_step)
values (board_seq.nextval, '오엔제이2''1111''Spring강좌질문'과정 추천해 주세요?', 0, 0)
 
commit;
 
 
2.     /WEB-INF/web.xml 만들기
 
web.xml 파일은 웹 애플리케이션(Web Application)에 대한 전체 설정 파일이다. Web Application Deployment Descriptor 파일이다. XML 형식의 파일인데 주로 내용은 서블릿 컨텍스트의 초기파라미터세션 타임아웃 시간 설정서블릿 매핑에러 페이지 정의한글 필터링을 위한 필터 서블릿 정의스프링 이나 스트럿츠 프레임워크의 프론트 컨트롤러 정의 등을 주로 설정 한다. <web-app> 태그로 시작하고 웹 애프리리케이션의 WEB-INF 아래에 위치한다는 것 명심!!
 
우리가 만들 게시판에서 web.xml에 스프링 프레임워크의 컨텍스트로더 리스너디스패처서블릿(front controller)을 정의하고 한글 변환을 위한 인코딩 필터를 정의 했다. *.html 요청에 대해 디스패 서블릿을 할당했다즉 만들어질 게시판을 실행시키기 위해서는 *.html 형태로 브라우저에 실행해야 할 것이다.
 
web.xml 파일에보면 ContextLoaderListener DispatcherServlet이 보이는데 이들의 개념에 대해서 명확히 알 필요가 있다우선 각각 WebApplicationContext의 인스턴스를 생성하는데 ContextLoaderListener가 생성한 컨텍스트가 ROOT Context가되고 DispatcherServlet이 생성한 인스턴스는 ROOT Context를 부모로 하는 자식 컨택스트가 된다.
 
여기에서 WebApplicationContext가 무얼까스프링 프레임워크는 자바 빈을 관리할 관리자가 필요한데 최고 상위에  BeanFactory가 있다하는 일은 자바빈 인스턴스를 만들고 배포객체간의 연관관계를 관리해 준다이를 상속 한 것이 ApplicationContext 인데 BeanFactory와 비슷한 일을 하는데 좀 더 기능이 많다.  이를 확장 한 것이 WebApplicationContext 이며 WebAppilcationContext 인터페이스는 웹 어플리케이션을 위한 ApplicationContext이다하나의 ServletContext(Web Application) 마다 하나의 WebApplicationContext가 존재한다.
 
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

이 설정에 의해 ContextLoaderListener가 서블릿 컨텍스트로 등록되면서 XmlWebApplicationContext 객체가 생성되는데 contextConfiglocation에 정의한 경로의 XML 파일을 읽어 WebApplicationContext를 생성한다이렇게 함으로써 XML 설정파일에 있는 자바빈 등을 메모리로 올리고 객체들간의 관계도 설정한다.
 
DispatcherServlet Spring MVC에서 Front Controller 역할을 하는데  Dispatcher Servlet이 로드되면 default로 서블릿의 이름과 연관된 XML 파일로부터 ApplicationContext를 로딩 한다.
( WEB-INF/서블릿이름-servlet.xml, 본 게시판에서는 /WEB-INF/action-servlet.xml)
 
DispatcherServlet 설정파일에는 스프링 MVC 컴포넌트와 관련된 <bean>정의를 주로 포함하는데 본 게시판에서는 DB접속을 위한 DataSource 정의만 두기로 하자.
 
서비스 계층(onj-service.xml)과 데이터 계층(onj-data.xml)에 속하는 빈 역시  DispatcherServlet의 설정파일에 포함할 수 있지만 별도의 설정파일을 두도록 하고 이름은 configBoard.xml로 하자.
 
이렇게 여러 개의 설정 파일이 있다면(물론 실제 프로젝트에는 더 많이 있다)설정파일들이 모두 로드 되도록 하기 위해 컨텍스트 로더(ContextLoader)를 설정하는데 컨텍스트 로더는 Dispatcher Servlet이 로드 하는 것 이외의 컨텍스트 설정파일을 로드 여기서는configBoard.xml을 로드 시키자게시판에서 사용될 서비스쪽 및 모델쪽의 자바빈 로드를 위해
 
아래는 완성된 web.xml 파일이다.
 
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
       <display-name>OnJSpringBoard1.0, 오엔제이프로그래밍실무교육센터</display-name>
      
       <filter>
             <filter-name>encodingFilter</filter-name>
             <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
             <init-param>
                    <param-name>encoding</param-name>
                    <param-value>EUC-KR</param-value>
             </init-param>
       </filter>
 
       <filter-mapping>
             <filter-name>encodingFilter</filter-name>
             <url-pattern>/*</url-pattern>
       </filter-mapping>
      
       <!--  ContextLoaderListener 설정 -->
       <listener>
               <listener-class>
                          org.springframework.web.context.ContextLoaderListener
               </listener-class>
        </listener>
      
       <!--  ContextLoaderListener 설정 파일 -->
       <context-param>
             <param-name>contextConfigLocation</param-name>
                    <param-value>/WEB-INF/boardConfig.xml,
                                 /WEB-INF/action-servlet.xml
                    </param-value>
       </context-param>
 
       <!-- 디스패처 서블릿 정의 설정 -->
       <servlet>
             <servlet-name>action</servlet-name>
             <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
             <load-on-startup>1</load-on-startup>
       </servlet>
      
       <servlet-mapping>
             <servlet-name>action</servlet-name>
             <url-pattern>*.html</url-pattern>
       </servlet-mapping>
      
 
       <!--  게시물 미리 보기 기능을 위한 ajax 처리용 서블릿 정의 -->
       <servlet>
             <servlet-name>preView</servlet-name>
             <servlet-class>onj.board.ajaxpreview.ContentPreview</servlet-class>
       </servlet>  
 
       <servlet-mapping>
             <servlet-name>preView</servlet-name>
             <url-pattern>/preView</url-pattern>
       </servlet-mapping>
 
</web-app>
 
 
 
 
3.     /WEB-INF/action-servlet.xml 파일을 만들자.
 
action-servlet.xml 파일에서는 Spring MVC와 관련된 오라클에 접속하기 위한 DataSource 정의요청 파라미터 URL에 따른 컨트롤러컨트롤러의 실행 메소드 정의뷰 해석을 위한 뷰리졸버 등에 대해 정의하고 있다
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
 
<bean id="dataSource"
       class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
       <property name="driverClassName">
           <value>oracle.jdbc.driver.OracleDriver</value>
       </property>
       <property name="url">
           <value>jdbc:oracle:thin:@127.0.0.1:1521:onj</value>
       </property>
       <property name="username">
           <value>scott</value>
       </property>
       <property name="password">
           <value>tiger</value>
       </property>      
    </bean>         
      
       <!-- 넘어오는 URL 따라 컨트롤러에서 실행될 메소드 매핑 -->
       <!--  PropertiesMethodNameResolver prop key 넘어오는 url 대해 실행할 컨트롤러의 메소드 정의 -->
       <bean id="userControllerMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
             <property name="mappings">
                           <props>
                               <!--  list.html 요청이 오면 컨트롤러의 list 메소드 실행 -->
                                 <prop key="/list.html">list</prop>  
                                
                           </props>
             </property>
       </bean>
 
       <!--  리졸버 -->
       <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
             <property name="prefix">
                    <value>/jsp/</value>
             </property>
             <property name="suffix">
                    <value>.jsp</value>
             </property>
       </bean>     
 
       <!-- 컨트롤러 매핑 -->
       <bean name="/list.html" class="board.controller.BoardMultiController">
             <property name="methodNameResolver">
                           <ref local="userControllerMethodNameResolver"/>
             </property>
             <property name="boardService">
                    <ref bean="boardService"/>
             </property>
       </bean>     
</beans>
 
 
 게시판에서는 다중 액션 컨트롤러(MultiActionController) 이용하여 스프링컨트롤러를 정의하는데비슷하거나 관련 있는 로직을 수행하는 다수의 액션을 가지고  있을  용이하게 이를 처리하는 컨트롤러이다. (글읽기글쓰기수정하기삭제하기 등을 하나의 컨트롤러에서 처리)
 
action-servlet.xml정의 에서 사용된 PropertiesMethodNameResolver 요청 URL 넘어오는 값을 기준으로 다중 액션 컨트롤러의 실행 메소드를 결정하는 역할을  한다. ParameterMethodNameResolver 사용한다면 요청 파라미터를 기초로 하여컨트롤러의 실행 메소드 이름을 정할  있다.
 
 
<props>
             <!-- /list.html 요청이 오면 컨트롤러의 list 메소드 실행 -->
             <prop key="/list.html">list</prop>
 
      </props>
 
이번에는 뷰 리졸버에 설정에 관해 알아보자.
 
ViewResolver는 컨트롤러의 메소드에서 리턴되는 ModelAndView의 뷰 이름을 취하여 실제 클라이언트에 보여질 뷰와 매핑 하는데 prefix 특성의 값과 suffix 특성의 값을 각각 접두어와  접미어로서 붙인다.
 
아래 문장을 해석하면 접두사로 “/jsp/”, 접미어로 “.jsp”가 붙는데 만약 View이름이 list라면 /jsp/list.jsp라고 해석되어 /list.jsp가 뷰 로서 사용자의 화면에 처리 결과로써 보여진다.
 
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
             <property name="prefix">
                    <value>/jsp/</value>
             </property>
             <property name="suffix">
                    <value>.jsp</value>
             </property>
       </bean>     
 
 
다음은 실제 컨트롤러를 매핑 하는 과정인데,
 
<bean name="/list.html" class="board.controller.BoardMultiController">
             <property name="methodNameResolver">
                           <ref local="userControllerMethodNameResolver"/>
             </property>
             <property name="boardService">
                    <ref bean="boardService"/>
             </property>
       </bean>
 
디스패처 서블릿에서 사용하는 기본적인 URL과 컨트롤러의 매핑 방법은 빈 이름에 기초하여 컨트롤러와 URL과 매핑한다위 구문을 보면 /list.html 이라는 빈 이름을 가진 경우 컨트롤러는 board.controller.BoardMultiController 라는 뜻이다. methodNameResolver BoardMultiController가 상속받은 MultiActionController의 속성값으로 다중액션 컨트롤러의 메소드 이름을 넘어오는 URL로부터 어떻게 해석할 것인지를 결정하는데위에서 정의 한 userControllerMethodNameResolver를 넣어 준다즉 요청 URL 넘어오는 값을 기준으로  다중 액션 컨트롤러의 실행 메소드를 결정하겠다는 것인데 /list.html 요청이 오면컨트롤러인 BoardMultiController list 메소드 실행하겠다는 것이다.
 
다음 boardService 게시판에서 서비스할 기능에 대해 인터페이스로 정의한 부분인데 다음에 구현하면서 살펴보자.
 
 
 
 
 
 
 
4.     /WEB-INF/boardConfig.xml
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
 
       <bean id="boardDAO"  class="onj.board.dao.SpringBoardDAO">
             <property name="dataSource">
                    <ref bean="dataSource"/>
             </property>
       </bean>
 
       <bean id="boardService" class="onj.board.service.BoardServiceImpl">
             <property name="boardDAO">
                    <ref bean="boardDAO"/>
             </property>
       </bean>
</beans>    
 
 
클래스 두 개에 대해 빈 정의 하였고 dataSource setter 주입하였다. SpringBoardDAO는 실제 DataBase 관련 작업을 하는  DAO 클래스이고 BoardServiceImpl은 게시판에서 필요한 서비스 기능을 구현한 클래스 이다각각 BoardDAO, BoardService 인터페이스를 구현한 구현체임.
 
 
5.     게시판 리스트 제작을 먼저 하기로 하고 BoardDTO 부터 만들어 보자.
 
BoardDTO는 게시판 테이블과 구조가 같은 도메인객체로서 게시판 리스트 보기 같은 곳에서 전체 게시물을 읽어 하나씩 BoardDTO에 담아서 LIST 객체를 이용하여 JSP로 전송해 준다. DTO라는 이름처럼 웹 애플리케이션에서 서로 다른 Layer 에서 데이터를 전송하기 위한 객체로서의 역할을 하는 클래스이다.
 
[BoardDTO.java]
 
package onj.board.model;
 
public class BoardDTO {
       private int seq;
       private String name;
       private String passwd;
       private String title;
       private String content;
       private String fileName;
       private String regdate;
       private int readCount;
       private int reply;
       private int reply_step;
       private int reply_level;
      
       public BoardDTO() {}
      
       public BoardDTO(String name, String passwd, String title, String content, String fileName) {
             this.name = name;
             this.passwd = passwd;
             this.title = title;
             this.content = content;
             this.fileName = fileName;
       }
      
       public BoardDTO(String name, String passwd, String title, String content, String fileName, int readCount) {
             this.name = name;
             this.passwd = passwd;
             this.title = title;
             this.content = content;
             this.fileName = fileName;
             this.readCount = readCount;
       }
 
       public int getSeq() {
             return seq;
       }
 
       public void setSeq(int seq) {
             this.seq = seq;
       }
 
       public String getName() {
             return name;
       }
 
       public void setName(String name) {
             this.name = name;
       }
 
       public String getPasswd() {
             return passwd;
       }
 
       public void setPasswd(String passwd) {
             this.passwd = passwd;
       }
 
       public String getTitle() {
             return title;
       }
 
       public void setTitle(String title) {
             this.title = title;
       }
 
       public String getContent() {
             return content;
       }
 
       public void setContent(String content) {
             this.content = content;
       }
 
       public String getFileName() {
             return fileName;
       }
 
       public void setFileName(String fileName) {
             this.fileName = fileName;
       }
 
       public String getRegdate() {
             return regdate.substring(0, 10);  //2013-07-15 형태
       }
 
       public void setDate(String regdate) {
             this.regdate = regdate;
       }
 
       public int getReadCount() {
             return readCount;
       }
 
       public void setReadCount(int readCount) {
             this.readCount = readCount;
       }
 
       public int getReply() {
             return reply;
       }
 
       public void setReply(int reply) {
             this.reply = reply;
       }
 
       public int getReply_step() {
             return reply_step;
       }
 
       public void setReply_step(int reply_step) {
             this.reply_step = reply_step;
       }
 
       public int getReply_level() {
             return reply_level;
       }
 
       public void setReply_level(int reply_level) {
             this.reply_level = reply_level;
       }     
      
}
 
 
 
6.  데이터베이스 SQL문장을 실행하기 위한 DAO클래스를 만들어 보자. 우선 BoardDAO라는
인터페이스를 만든  이를 구현한 SpringBoardDAO 만들자. SpringBoardDAO configBoard.xml 파일에서 빈으로 등록되어 스프링 프레임워크가 기동될  WebApplicationContext 의해 boardDAO라는 이름의 빈으로 등록되어 서비스 된다.
 
BoardDAO 인터페이스 에서는 게시판 리스트 보기를 위한 boardList() 정의한다.
 
[BoardDAO.java]
 
package onj.board.dao;
 
import java.util.List;
import onj.board.model.BoardDTO;
import org.springframework.dao.DataAccessException;
 
public interface BoardDAO {
       public List<BoardDTO> boardList() throws DataAccessException;
}
 
 
 
아래 SpringBoardDAO에서 setDataSource 통해 DataSource 세터주입 받는데 boardConfig.xml 다음 구문에 의해 주입 받는다.
(property name값에 대한 set method 있어야 하는데 SpringBoardDAO setDataSource 메소드가 정의되어 있어야 한다.)
 
 
 
<bean id="boardDAO"  class="onj.board.dao.SpringBoardDAO">
             <property name="dataSource">
                    <ref bean="dataSource"/>
             </property>
       </bean>
 
 
Spring DI 하나인 세터주입(Setter Inject) 대해서는 다음 URL 참고하자.
http://www.onjprogramming.co.kr/oraclejavanew/oraclejava/bbs/board.php?bo_table=LecSpring&wr_id=193&page=3
 
 
 
jdbcTemplate객체의 query 명령문에 의해 SELECT문장을 실행하며 인자로 넘겨  RowMapper maprow 구현에 의해 실행된 결과를  건씩 BoardDTO 담으며 최종결과물을 boardList 담아서 리턴해 준다 모든 게시물을 읽기 위해서 new RowMapper()에서 mapRow 구현  것이다.
 
 
다음은 전체 소스코드이다.
 
[SpringBoardDAO.java]
 
package onj.board.dao;
 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import onj.board.model.BoardDTO;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
 
public class SpringBoardDAO implements BoardDAO {
       private JdbcTemplate jdbcTemplate;
      
       public void setDataSource(DataSource dataSource){                
                    this.jdbcTemplate = new JdbcTemplate(dataSource);
       }
 
       @Override
       public List<BoardDTO> boardList() throws DataAccessException {
             List<BoardDTO> boardList = null;
            
             String sql = "select * from board";
            
             boardList = jdbcTemplate.query(sql, 
                                 new RowMapper() {
                           public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
       BoardDTO board = new BoardDTO();
                                             
                                             board.setSeq(rs.getInt("seq"));                                         board.setName(rs.getString("name"));                                    board.setPasswd(rs.getString("passwd"));                                board.setTitle(rs.getString("title"));                                  board.setContent(rs.getString("content"));                               board.setFileName(rs.getString("filename"));
       board.setDate(rs.getString("regdate"));
       board.setReadCount(rs.getInt("readcount"));
       board.setReply(rs.getInt("reply"));
       board.setReply_step(rs.getInt("reply_step"));
       board.setReply_level(rs.getInt("reply_level"));
                                             
       return board;
                                        }
             });
            
             return boardList;
       }
 
}
 
 
 
7.     이번에는 구현된 DAO를 이용하는 service쪽 인터페이스클래스를 작성해 보자.
 
 
컨트롤러에서 실행하는 모든 서비스에 대해 BoardService 인터페이스가 정의하고 있으며 이를 구현한 구현체가 BoardServiceImpl이며 BoardServiceImple boardConfig.xml에 빈으로 정의되어 있다.
 
 [BoardService.java]
 
package onj.board.service;
 
import java.util.List;
import onj.board.model.BoardDTO;
 
/*
 * 게시판에서 구현할 기능을 인터페이스로 정의
 */
public interface BoardService {
       //게시판 리스트 보기
       public List<BoardDTO> boardList();           
}
 
 
 
[BoardServiceImple.java]
 
package onj.board.service;
 
import java.util.List;
import onj.board.dao.BoardDAO;
import onj.board.model.BoardDTO;
 
public class BoardServiceImpl implements BoardService {
    private BoardDAO boardDAO;
   
    public void setBoardDAO(BoardDAO boardDAO) {
        this.boardDAO = boardDAO;
    }
   
    //게시물 보기
    public List<BoardDTO> boardList() {
        return boardDAO.boardList();
    }
}
 
 
BoardServiceImpl setBoardDAO 메소드가 있는데 이를 통해 SpringBoardDAO주입 받는다(세터 주입). 물론 SpringBoardDAO BoardDAO 인터페이스를 구현한클래스 이므로 TYPE 인터페이스인 BoardDAO 해도 가능한 것이다 부분은 boardConfig.xml 다음 구문에 의해 실행된다.
 
 
<bean id="boardService" class="onj.board.service.BoardServiceImpl">
             <property name="boardDAO">
                    <ref bean="boardDAO"/>
             </property>
       </bean>
 
 
boardList() 메소드에서 SpringBoardDAO쪽의 boardList() 메소드를 호출하고 그 결과를 List 객체 형태로 돌려받는다BoardServiceImpl 모든 메소드는 우리가 앞으로 작성 스프링 컨트롤러에서 호출하게 된다.
 
 
 
8.     스프링 컨트롤러를 만들자.
 
Spring framework front controller web.xml에서 설정한 dispatcher servlet인데 클라이언트의 URL 요청 패턴에 따라 디스패처서블릿이 실제 사용자 요청을 처리를 위해 xml에서 정의된 사용자 컨트롤러로 위임하게 되는데 … 이 사용자 컨트롤러를 만들어 보자.
 
[BoardMultiController.java]
 
package onj.board.controller;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import onj.board.service.BoardService;
import org.springframework.web.servlet.ModelAndView;
importorg.springframework.web.servlet.mvc.multiaction.MultiActionController;
 
/*
 * MultiActionController 비슷하거나 관련있는 로직을 수행하는
 * 다수의 액션을 가지고 있을  사용하는 컨트롤러
 * 연관된 요청(Request) 묶을  용이함
 */
public class BoardMultiController extends MultiActionController {
       private BoardService boardService;
      
       public void setBoardService(BoardService boardService) {
             this.boardService = boardService;
       }
      
       //게시판 리스트 보기페이징 기능은 구현 안함 
       public ModelAndView list(HttpServletRequest req, HttpServletResponse res) throws Exception {               
            
             ModelAndView mv = new ModelAndView("list" , "list" , boardService.boardList());
 
             return mv;         
       }     
}
 
 
MultiActionController를 상속 받았는데 비슷한 기능을 하는 다수의 액션을 처리할 수 있는 스프링 컨트롤러 이다.
 
action-servlet.xml정의 에서 사용된 PropertiesMethodNameResolver 요청 URL 넘어오는 값을 기준으로 다중 액션 컨트롤러의 실행 메소드를 결정하는 역할을  한다.
 
 
 
<bean id="userControllerMethodNameResolver"
              class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
             <property name="mappings">
                    <props>
                           <!-- list.html 요청이 오면 컨트롤러의 list 메소드 실행 -->
                           <prop key="/list.html">list</prop>
 
                    </props>
             </property>
      </bean>
 
 
다음은 우리가 작성  컨트롤러를 매핑하는 부분이다. /list.html 요청에 대해 BoardMultiController  매핑하고 methodNameResolver 위에서 정의한userControllerMethodNameResolver 정의했다.
 
<bean name="/list.html" class="onj.board.controller.BoardMultiController">
             <property name="methodNameResolver">
                    <ref local="userControllerMethodNameResolver" />
             </property>
             <property name="boardService">
                    <ref bean="boardService" />
             </property>
       </bean>
 
 
9.     컨트롤러와 모델쪽은 작성이 다 되었으니 게시판 리스트 보기에서 뷰 역할을 하는/jsp/list.jsp를 작성하자.
 
 
<%@ page contentType="text/html; charset=euc-kr" language="java"import="java.sql.*" errorPage="" %>
<%@ page import = "javax.rmi.* , javax.naming.* , java.util.* , onj.board.model.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>오엔제이 프로그래밍 실무학원</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
</head>
<body>
<div style="width:500px;">
<div style="float:right;">
<H3>오엔제이 프로그래밍 실무교육센터 게시판</H3>
<h5> ${list.size()}</h5>
<table width="600" border="1" align="left">
  <tr align="left">
    <td width="10%" align="center">번호</td>
    <td width="40%" align="center">제목</td>
    <td width="20%" align="center">이름</td>
    <td width="20%" align="center">날짜</td>
    <td width="10%" align="center">조회</td>
  </tr>
<!—컨트롤러에서 돌려주는 게시판 리스트를 담은 list 가져와서 board 명명   만큼 반복 -->
             <c:forEach var="board" items="${list}">      
  <tr>
    <td align="center">
                    <c:if test="${board.reply_step == 0}">
                                 ${board.seq}
                    </c:if>
                    <c:if test="${board.reply_step != 0}">
                                  
                    </c:if>                  
    </td>
    <td>      <!-- 게시물은 덧글에 따른 번호와 덧글 존재 유무로 정렬됨 -->
                    <c:choose>                
                           <c:when test="${board.reply_step != 0}"><!-- 게시글이 덧글일 경우 -->
                                 <c:forEach var="i" begin="1"end="${board.reply_level}" step="1"><!-- 레벨의 수만큼 글을 뒤로 민다 -->
                                          
                                 </c:forEach>
                                        <a href="read.html?seq=${board.seq}" onmouseover="contentprev('${board.seq}');showlayer('layer1');" onmouseout="hidelayer('layer1');">${board.title}</a>
                                        <!-- 마우스를 올리면 게시물 번호에  따른 showlayer(게시물 미리보기 ) 실행됨 -->
                           </c:when>
                           <c:when test="${board.reply_step == 0}">
                                        <a href="read.html?seq=${board.seq}" onmouseover="contentprev('${board.seq}');showlayer('layer1');" onmouseout="hidelayer('layer1');">${board.title}</a>                    
                           </c:when>
                    </c:choose>
   </td>
    <td align="center">${board.name}</td>
    <td align="center">${board.regdate}</td>
    <td align="center">${board.readCount}</td>
  </tr>
             </c:forEach>
 
  <tr>
    <td align="center"><input type="button" value="쓰기" onclick="location.href='write.html';"></td>
    <td> </td>
    <td> </td>
    <td> </td>
    <td> </td>
  </tr>
</table>
</div>
</div>
</body>
</html>
 
 
 
 
 
10.   파일 작성이 다 되었으니 이제 실행하고 결과를 확인하자.
 
http://localhost:8080/onjboard1/list.html
 
:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
 
 
 









클래스패키지 다이어그램.

댓글 없음:

댓글 쓰기