본문 바로가기
Today I learned

1월25일

by soheemon 2019. 1. 25.

*MVC 패턴

어플리케이션의 확장을 위해서 Model View Controller 세가지 영역으로 분리

컴포넌트의 변경이 다른 영역 컴포넌트에 영향을 미치지 않음

컴포넌트 간의 결합성이 낮아 프로그램 수정이 용이


장점

 - 화면과 비즈니스 로직을 분리해서 작업 가능

 - 영역별 개발로 인하여 확장성이 뛰어남

 - 표준화된 코드를 사용하므로 공동작업이 용이하고 유지보수성이 좋음

단점

 - 개발과정이 복잡해 초기 개발속도가 늦음


*SpringMVC

 

1)DispatcherServlet이 모든 요청을 수신한다.

- 요청을 수신하여 처리를 다른 컴포넌트에 위임 - 어느 컨트롤러에 요청을 전송할지 결정.

2) DispatcherServlet은 Handler Mapping에 어느 컨트롤러를 사용할 것인지 문의 - URL과 맵핑

3) DispatcherServlet은 요청을 컨트롤러에게 전송하고 컨트롤러는 요청을 처리한 후 결과 리턴

- 비즈니스 로직 수행 후 결과 정보(Model)가 생성되어 JSP와 같은 뷰에서 사용됨

4)ModelAndView 오브젝트에 수행결과가 포함되어 dispatcherServlet에 리턴

5)ModelAndView는 실제 JSP정보를 갖고 있지 않으며, ViewResolver가 논리적 이름을 실제 JSP이름으로 변환

6) View는 결과정보를 사용하여 화면을 표현함



HandlerMapping DispatcherServlet에 들어온 요청을 Controller와 맵핑할 규칙을 만든다.

<각각의 URL과 메서드 맵핑 (Request 맵핑) 정보는 생성한 XML을 넣어주면 끝난다.>

따라서 Controller에 전달하게 된다.

Spring에서의 컨트롤러는 기존에 사용하던 Action과 동작이 비슷하다.

컨트롤러의 동작은 1) 비즈니스로직을 실행하고 2) 데이터를 설정하고 3) 어떤 view갈지 설정한다.

=> 이 결과는 ModelAndView에서 뷰의 정보와 데이터를 담을 수 있다.

DispatcherServlet은 그것을 받으면 View로 가게되는데, 이때 ViewResolver는 뷰의 종류를 나타낸다.

=> Spring에서는 View와 ViewResolver가 하나다.


*Spring @MVC 실습

.do로 요청이 들어오면 Spring Mvc가 요청을 받게 함.

*기본적으로 servlet-name-servlet.xml파일에서 어플리케이션 컨텍스트 정보를 로드 = xml파일이 하나일때!

<url-pattern>은 DispatcherServlet이 처리하는 URL매핑 패턴을 정의.


<servlet>

   <servlet-name>dispatcher</servlet-name>

   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

   <load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

   <servlet-name>dispatcher</servlet-name>

   <url-pattern>*.do</url-pattern>

</servlet-mapping>


여러개일때


<servlet>

   <servlet-name>dispatcher</servlet-name>

   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

   <init-param>

      <param-name>contextConfigLocation</param-name>

      <param-value>

         /WEB-INF/dispatcher.xml

         /WEB-INF/test.xml

      </param-value>

   </init-param>

   <load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

   <servlet-name>dispatcher</servlet-name>

   <url-pattern>*.do</url-pattern>

</servlet-mapping>


DispatcherServlet은 여러개 설정 가능

각 DispatcherServlet마다 각각의 ApplicationCentext를 생성해야 한다.

<DispatcherServlet은 Servlet Container! 기억하기>

예>

<servlet>

   <servlet-name>dispatcher</servlet-name>

   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

   <load-on-startup>1</load-on-startup>

</servlet>

<servlet>

   <servlet-name>dispatcher2</servlet-name>

   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping>

   <servlet-name>dispatcher</servlet-name>

   <url-pattern>*.do</url-pattern>

</servlet-mapping>

<servlet-mapping>

   <servlet-name>dispatcher2</servlet-name>

   <url-pattern>*.action</url-pattern>

</servlet-mapping>


*MVC 간단 예제

SpringMVC를 이용한 어플리케이션 작성 스탭 

1. 컨트롤러 작성

2. 컨텍스트 설정파일([ServletName]-servlet.xml)에 컨트롤러 설정

3. 컨트롤러와 JSP의 연결을 위해 View Resolver 설정

4. JSP 코드 작성

5. 실행


*MVC 예제 실습

1)Web.xml에 Dispatcher Servlet 등록


2)Context 설정파일 컨트롤러(XML로)을 만든다. 

-dispatcher는 API로써 어떤 요청이 들어왔을때 어떤 컨트롤러로 연결 해야 할지를 모르기 때문.

이 정보를 Context 설정파일에 넣어줘야 한다.

- spring beanconfiguration file을 생성한다. <이름 중요!>

3)Default annotation handler Mapping 방식을 사용한다.

4) 컨트롤러를 만든다.

- 클래스 하나를 만들어서 @Controller로 지정해주면 컨트롤러가 된다.

- @RequestMapping("/hello.do")로 선언을 하는데, hello.do로 요청이 들어오면 아래 메서드를 실행한다.

5) ModelAndView를 return하는 메서드를 작성한다.

6) Dispatcher Servlet에서 ModelAndView를 받기전에 View의 종류와 경로를 알아야 하기 때문에 Context 설정파일에서 ViewResolver를 등록해준다.



package kosta.service;

 

public class HelloService {

        public HelloService(){};

       

        public String getMessage() {

               return "Hello Spring2!!!!";

        }

}


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 

<!-- Dispatcher서블릿을 통해 웹어플리케이션스프링컨테이너를 생성하고 컨테이너가 Hellocontroller 대한 정보를 가지고 있다.  -->

<bean id="helloService" class="kosta.service.HelloService"></bean>

 

<bean id="helloController" class="kosta.controller.HelloController">

        <constructor-arg ref="helloService"/>

</bean>

 

<!-- Dispatcher서블릿을 통해 웹어플리케이션 스프링 컨테이너를 생성하는데, 컨테이너가  ViewResolver 객체를 가지고 있다.-->

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/view/"/>

        <property name="suffix" value=".jsp"/>

</bean>

</beans>



package kosta.controller;

 

import org.springframework.stereotype.Controller;

//컨트롤러 어노테이션 해야함

//디스패처에게 알려줘야함 컨트롤러의 존재를. => xml 하기

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;

 

import kosta.service.HelloService;

@Controller

public class HelloController {

        public HelloController(){};

        //construct-arg 방식으로 의존성 주입

        private HelloService service = null;

        public HelloController(HelloService service) {

               this.service = service;

        }

       

        //property 방식으로 의존성 주입

//     private HelloService service = null;

//     public setService (HelloService service) {

//             this.service = service;

//     }

       

        @RequestMapping("/hello.do")

        //View이름과 Data 가지고 간다.

 

        public ModelAndView hello(HelloService service) {

               ModelAndView mav = new ModelAndView();

              

               //view 경로 정해주기. jsp인지 어느 폴더에 있는지... 정해주지 않아도 된다.

               //view resolve 해준다.

               mav.setViewName("hello");

               mav.addObject("message", service.getMessage());

              

               return mav; // dispatcherServlet으로 간다.

               //View 가기전에 Viewresolver에서 View 종류과 경로를 알아야 한다.

        }

}


//같은 url을 요청할때, method Type으로 구분 할 수 있다.

package kosta.controller;

 

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.servlet.ModelAndView;

 

import kosta.service.HelloService;

 

@Controller

public class BoardController {

       

        //url 같을때엔 method Type으로 구분 있다.

        //Form Page 갈때

        @RequestMapping(value="/board_insert.do", method=RequestMethod.GET)

        public String insertForm(Model model) { // Modal & Data 안쓰고 data 전달한다.

               model.addAttribute("title", "글쓰기");

               return "insert_form";

        }

       

        //글을 등록할때

        @RequestMapping(value="/board_insert.do", method=RequestMethod.POST)

        public String board_insert() { // Modal & Data 안쓰고 data 전달한다.

               return "";

        }

}

 


//componentscan 방식으로 package를 지정해서 @으로 지정한 객체를 전부 가져온다.

//controller는 등록이 되어있으므로, 서비스로 만든 클래스에만 등록해준다.

//또한 컨트롤러에서 의존성 주입받는 메서드 위에 @AutoWired 해준다. 


//springapp-servlet.xml


<?xml version="1.0" encoding="UTF-8"?>

<!-- componentscan방식으로 pakege밑에있는 @되어있는 객체를 전부 가져온다. -->

 

<context:annotation-config/>

        <context:component-scan base-package="kosta"/>

       

 

<!-- Dispatcher서블릿을 통해 웹어플리케이션스프링컨테이너를 생성하고 컨테이너가 Hellocontroller 대한 정보를 가지고 있다-->  

<!--

<bean id="helloService" class="kosta.service.HelloService"></bean>

 

<bean id="helloController" class="kosta.controller.HelloController">

        <constructor-arg ref="helloService"/>

</bean>

 

<bean id="boardController" class="kosta.controller.BoardController">

</bean>

 -->

 

<!-- Dispatcher서블릿을 통해 웹어플리케이션 스프링 컨테이너를 생성하는데, 컨테이너가  ViewResolver 객체를 가지고 있다.-->

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/view/"/>

        <property name="suffix" value=".jsp"/>

</bean>

 


web.xml

아래와 같이 입력하면 /이하로 들어오는 요청은 모두 스프링컨트롤러로 보내게 된다.

만약 springapp 디스패처서블릿에서 해당요청에 대한 컨트롤러가 없으면 에러가 나게 된다.

<!-- / 들어오는건 모두 스프링 요청이야라고 쓰는것.. =>.html 스프링이 처리하려고 하기때문에 오류남!-->

<servlet-mapping>

        <servlet-name>springapp</servlet-name>

        <url-pattern>/</url-pattern>

   </servlet-mapping>


따라서, springapp 디스패처서블릿에서 들어온 요청에 대해 일치하는 컨트롤러가 없을경우

에러를 발생시키지 말고 TOMCAT을 실행하라는 내용을 적어야 한다.

sprintapp-servlet.xml에. 

<!-- spring 없는 controller요청이 왔을때에도, 404에러 내보내지 말고 tomcat 실행하도록 한다. -->

<mvc:annotation-driven/>

        <mvc:default-servlet-handler/>


커맨드 객체 : 뷰에서 입력한 데이터를 자바빈 객체를 이용해서 전송.

<예를들어, 게시판에 글을 등록하는 Form에서 input name이 name, title, contents가 있다고 하자.

submit했을경우 url이 맵핑되는 컨트롤러로 가면 이 컨트롤러에서는 Board객체를 받을 수 있어야 한다.

Spring프레임워크를 사용하지 않았을때에는 일일히 Board 객체를 생성하고 request.getAttribute -해와서 값을 하나하나 넣어줘야 했지만,


Spring에서는 이를위해 간편하게'커맨드 객체'를 제공한다.

즉, 

Board라는 DTO용 클래스를 하나 선언해주고, 이 Class의 멤버필드를 form의 name과 일치시킨다.

Form에있는 name과, command객체의 필드명이 서로 일치해야 커맨드객체로 전달되어진다.


그러면 자동으로 맵핑하여 객체로 넣어준다.


        //글을 등록할때

        @RequestMapping(value="/board_insert.do", method=RequestMethod.POST)

        public String board_insert(Board board) { // Board 커맨드객체.

        System.out.println("title:" + board.getTitle());

               return "";

        }





//web.xml에 필터 등록

filter mapping - 모든 요청에 대해 url encoding을 해준다.

<filter>

        <filter-name> encodingFilter</filter-name>

        <filter-class>

               org.springframework.web.filter.CharacterEncodingFilter

        </filter-class>

        <init-param>

               <param-name>encoding</param-name>

               <param-value>UTF-8</param-value>

        </init-param>

  </filter>

 

  <filter-mapping>

  <filter-name>encodingFilter</filter-name>

  <url-pattern>/*</url-pattern>

  </filter-mapping>


*

스프링은 유효성 검사를 위한 Validator인터페이스오 ㅏ유효성 검사 결과를 저장할 Errors인터페이스를 제공한다.

Validator인터페이스를 이용하면 폼 입력값 검증이 가능하다.


//BoardValidator

package kosta.model;


import org.springframework.validation.Errors;

import org.springframework.validation.Validator;


public class BoardValidator implements Validator {


@Override

public boolean supports(Class<?> arg0) {

if(Board.class.isAssignableFrom(arg0)){

return true;

}

return false;

}


//board객체와 error객체를 입력받는다. BoardController클래스 안에 파라미터로 @valid Board board, Bindingresult error로 입력함.

@Override

public void validate(Object arg0, Errors errors) {

Board board = (Board)arg0;

if(board.getTitle() == null || board.getTitle().length() == 0){

errors.rejectValue("title", "require", "제목을 입력하세요.");

}

}

}



//validator 라이브러리

<dependency>

         <groupId>org.hibernate</groupId>

         <artifactId>hibernate-validator</artifactId>

         <version>4.3.2.Final</version>

</dependency>


//Board 컨트롤러.

WebDataBinder를 받아서 binder에 BoardVlidater객체를 넘겨준다.


<뷰가 컨트롤러에게 데이터를 넘겨주는것 => 커맨드 객체>

이때 컨트롤러가 뷰에 데이터를 전달하기 위해 @ModelAttribute(<커맨드객체>)를 선언 후, Board 객체를 넘겨준다.


@Controller

public class BoardController {

       

        //url 같을때엔 method Type으로 구분 있다.

        //Form Page 갈때

        @RequestMapping(value="/board_insert.do", method=RequestMethod.GET)

        public String insertForm(@ModelAttribute("boardCommand")Board board, Model model) { // Modal & Data 안쓰고 data 전달한다.

               model.addAttribute("title", "글쓰기");

               return "insert_form";

        }

       

        //글을 등록할때

        @RequestMapping(value="/board_insert.do", method=RequestMethod.POST)

        public String board_insert(@ModelAttribute("boardCommand") @Valid Board board, BindingResult errors) { // Board 커맨드객체.

               //ModelAttribute 컨트롤러가 커맨드객체를 다시 view 준다. 객체의 이름은 boardCommand 된다.

              

               if(errors.hasErrors()) {

                       System.out.println("에러 발생");

                       return "insert_form"; //다시 form으로 간다. 에러 메시지를 가지고.

               }

               return "";

        }

       

        //validation 객체 생성

        @InitBinder

        protected void InitBinder(WebDataBinder binder) {

               binder.setValidator(new BoardValidator()); // Board객체에 Board데이터가 들어갈때 호출해야한다.

              

        }

}

 

//validation 객체를 사용할때 initBinder를 해준다.


//자세히 뜯어보자. 만약 Valid 체크후.. error가 발생하면.. error 객체로 그 내용이 전달되고...

여기서 errors객체를 확인해서 에러가 확인되면 console에 에러가 발생했다고 찍고 return "insert_form"함으로써 form으로 다시 이동한다.

자동으로 view/insert_form.jsp로 이동한다.


지금은 정상적인 글을 등록했을때 아무런 처리도 안해주고 있지만.. 그 이후에 DB에 입력하는 코드를 입력하겠지.

        //글을 등록할때

        @RequestMapping(value="/board_insert.do", method=RequestMethod.POST)

        public String board_insert(@ModelAttribute("boardCommand"@Valid Board board, BindingResult errors) { // Board 커맨드객체.

               //ModelAttribute 컨트롤러가 커맨드객체를 다시 view 준다 객체의 이름은 boardCommand 된다.

              

               if(errors.hasErrors()) {

                       System.out.println("에러 발생");

                       return "insert_form"//다시 form으로 간다에러 메시지를 가지고.

               }

               return "";

        }


//insert_form은 다음과 같이 입력한다.

//에러 메시지를 출력하기 위해 커스텀 태그를 하나 추가한다. => form

form:form에 commandName속성을 입력하고 위에서 입력했던 ModelAttribute이름을 정해주고

<form:input> 으로 입력한다.

<%@ page language="java" contentType="text/html; charset=utf-8"

    pageEncoding="utf-8"%>

   

    <!-- 에러메시지를 출력하기 위해 커스탬 태그 하나를 추가 해야한다. -->

   <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>Insert title here</title>

<style type="text/css">

        .error{

               color: #ff0000;

        }

</style>

</head>

<body>

<h3>${title }</h3>

<hr>

 

<form:form action="board_insert.do" method="post"

                       commandName="boardCommand">

        작성자 : <form:input type="text" path="writer"/><br>

        제목 : <form:input type="text" path="title"/>

               <form:errors path="title" cssClass="error"/><br>          

        내용 <br>

        <form:textarea rows="6" cols="70" path="contents"/>

        <br>

        <input type="submit" value="등록">

</form:form>

 

</body>

</html>



validation 객체 만들지 말고 jsr303방식으로 처리하기!

//Command클래스에 아래와 @으로 작성 하면된다.

//form에서 해줘야 할 내용은 validation객체를 만드는것과 같다.

//이때는 너무나 당연하게 Controller에 InitBinder가 없어도 되겠지. 왜냐 Validation객체가 필요 없으니까.

public class Board implements Serializable{

        private int seq;

       

        @NotEmpty(message="작성자를 입력하세요.") //값이 없을때

        @Size(min=2, max=5, message="2자이상 5 미만")

        private String writer;

       

        @Pattern(regexp="[0-9a-zA-Z-]*", message="특수문자는 입력하시면 안됩니다.") //특수문자는 안된다.

        private String title;

        private String contents;

        private String regdate;

        private int hitcount;



*MyBatis 연동

필요한 라이브러리 

- spring-jdbc

- mybatis

- mybatis-spring


// server.xml에 JDBC설정한것. 프로젝트 단위별로 넣기.

 <Resource auth="Container" driverClassName="oracle.jdbc.driver.OracleDriver" maxIdle="30" maxTotal="100" maxWaitMillis="10000" name="jdbc/oracle" password="1234" type="javax.sql.DataSource" url="jdbc:oracle:thin:@localhost:1521:XE" username="kosta192"/>


// WEB-INF 밑에 mybatis-config.xml 위치시키기.

<mapper namespace="kosta.mapper.BoardMapper">

        <cache />

 

        <insert id="insertBoard" parameterType="Board">

               insert into board(

               seq, title, writer, contents, regdate, hiscount

               )values(

               board_seq.nextval, #{title}, #{writer}, #{contents}, sysdate, 0

               )

        </insert>

       

        <select id="listBoard" resultType="Board">

               select * from board

        </select>

       

</mapper>


//BoardMapper

package kosta.mapper;

 

import java.util.List;

 

import kosta.model.Board;

 

public interface BoardMapper {

        int insertBoard(Board board);

        List<Board> listBoard();

        Board getBoard(int seq);

        int updateBoard(Board board);

}


//세션 생성 (springapp-servlet.xml) 관련 설정

<!-- MyBatis Setting -->

        <!-- 생성 순서 -->

        <!-- 1)dataSource 2)sqlSession팩토리 3)SqlSessionTemplate 4)최종적으로 DAO Template 사용-->

       

        <!-- sqlSessionFactory 만들어서 dataSource 넣고.. config파일도 넣는다.Mybatis.conf -->

        <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">

               <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />

        </bean>

        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

               <property name="dataSource" ref="dataSource" />

               <property name="configLocation" value="/WEB-INF/mybatis-config.xml" />

        </bean>

 

        <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

               <property name="jndiName" value="jdbc/oracle" />

               <property name="resourceRef" value="true" />

        </bean>

//BoardDao

자동으로 객체화하기 위해 @Repository


package kosta.model;

 

import java.util.List;

 

import org.mybatis.spring.SqlSessionTemplate;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Repository;

 

import kosta.mapper.BoardMapper;

 

@Repository

public class BoardDao {

        private SqlSessionTemplate sqlTemplate;

 

        public SqlSessionTemplate getSqlTemplate() {

               return sqlTemplate;

        }

       

        @Autowired

        public void setSqlTemplate(SqlSessionTemplate sqlTemplate) {

               this.sqlTemplate = sqlTemplate;

        }

       

        //Spring에서는 트랜잭션 처리 필요 없음.

        public void insert(Board board){

               sqlTemplate.getMapper(BoardMapper.class).insertBoard(board);

        }

       

        public List<Board> listBoard() {

               return sqlTemplate.getMapper(BoardMapper.class).listBoard();

        }

}

 


package kosta.controller;

 

import java.util.List;

 

import javax.validation.Valid;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.validation.BindingResult;

import org.springframework.web.bind.WebDataBinder;

import org.springframework.web.bind.annotation.InitBinder;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.servlet.ModelAndView;

 

import kosta.model.Board;

import kosta.model.BoardDao;

import kosta.model.BoardValidator;

import kosta.service.HelloService;

 

@Controller

public class BoardController {

        private BoardDao dao;

       

        public BoardDao getDao() {

               return dao;

        }

       

        @Autowired

        public void setDao(BoardDao dao) {

               this.dao = dao;

        }

 

        //url 같을때엔 method Type으로 구분 있다.

        //Form Page 갈때

        @RequestMapping(value="/board_insert.do", method=RequestMethod.GET)

        public String insertForm(@ModelAttribute("boardCommand")Board board, Model model) { // Modal & Data 안쓰고 data 전달한다.

               model.addAttribute("title", "글쓰기");

               return "insert_form";

        }

       

        //글을 등록할때

        @RequestMapping(value="/board_insert.do", method=RequestMethod.POST)

        //jsr303방식

        public String board_insert(@ModelAttribute("boardCommand") @Valid Board board, BindingResult errors) { // Board 커맨드객체.

               //ModelAttribute 컨트롤러가 커맨드객체를 다시 view 준다. 객체의 이름은 boardCommand 된다.

              

               if(errors.hasErrors()) {

                       System.out.println("에러 발생");

                       return "insert_form"; //다시 form으로 간다. 에러 메시지를 가지고.

               }

              

               dao.insert(board);

              

               //spring에서 redirect 하는법.

               return "redirect:board_list";

        }

        @RequestMapping("/board_list")

        public String board_list(Model model) { //Model&View 대신 model 쓴다.

               List<Board> list = dao.listBoard();

               model.addAttribute("list", list);

               return "list"; // view/list.jsp 가자

        }


}

 


<%@ page language="java" contentType="text/html; charset=EUC-KR"

    pageEncoding="EUC-KR"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>   

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">

<title>Insert title here</title>

</head>

<body>

        <h3>글목록보기</h3>

        <table border="1">

               <tr>

                       <td>번호</td>

                       <td>제목</td>

                       <td>작성자</td>

                       <td>조회수</td>

                       <td>등록일</td>

               </tr>

              

               <c:forEach var="board" items="${list }">

                       <tr>

                              <td>${board.seq }</td>

                              <td>${board.title }</td>

                              <td>${board.writer }</td>

                              <td>${board.hitcount }</td>

                              <td>${board.regdate }</td>

                       </tr>

               </c:forEach>

              

        </table>

</body>

</html>


















































'Today I learned' 카테고리의 다른 글

URI와 URL  (0) 2019.01.28
1월28일  (0) 2019.01.28
1월24일 봄이오나봄, Spring 프레임워크  (0) 2019.01.24
프런트 컨트롤러 디자인 패턴  (0) 2019.01.21
Ajax & Javascript 정리  (0) 2019.01.21

댓글