ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2022-03-02 Spring 게시판 만들기 #1
    학원/Spring 2022. 3. 2. 15:49

     

    ~복습~

     

    새로운 스프링 프로젝트 생성

     

     

     

     

     

    프로젝트 생성이 완료 되면 pom.xml 수정

     

     

     

     

    설정 한 후 프로젝트 우클릭 -> run 해주면 

     

     

    기본으로 세팅된 페이지가 나온다 

     

    한글 깨지지 않도록 설정 하기

     

     

    좌측 위치에 </servlet-mapping> 과 </web-app> 사이에 <filter> 태그 추가 

     

    <filter>
        <filter-name>CharacterEncodingFilter</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>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

     

     

    저장한 후 다시 프로젝트를 실행하면 

     

     

     

    깨지지 않고 잘 나온다 

     

     

    이 페이지를 출력하게 하는 클래스 

     

     

     

     

    import 생략
    
    /**
     * Handles requests for the application home page.
     */
    
    //서버에 요청되는 리퀘스트들을 다루는 클래스
    //클래스 이름 위에 @Controller - 어노테이션을 표시하면 그 안에 사용되는 @RequestMapping에서 리퀘스트가 검색, 선택, 실행된다. 
    //첫페이지의 주소 http://localhost:8090/springmvc/ 는 localhost의 8090 포트 중 springmvc로 대표되는 프로젝트에 요청을 보낸 상태이고 
    //요청 키워드는 '/' 이다 -> 클래스 안에 있는 메서드 중 @RequestMapping('/')을 찾아 실행하고 리턴한다. 
    
    @Controller
    public class HomeController {
    	
    	//log 출력을 위한 준비
    	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
    	
    	/**
    	 * Simply selects the home view to render by returning its name.
    	 */
    	
    	//method=RequestMethod.GET은 생략 가능, POST 는 반드시 기재할 것
    	@RequestMapping(value = "/", method = RequestMethod.GET)
    	public String home(Locale locale, Model model) {
    		logger.info("Welcome home! The client locale is {}.", locale);
    		
    		Date date = new Date();
    		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
    		
    		String formattedDate = dateFormat.format(date);
    		
    		model.addAttribute("serverTime", formattedDate );
            //request.setAttribute를 대신 할 정보 전달 객체 : model
            //addAttribute로 저장만 하면 목적지에 자동 전달됨
    		
    		return "home";
            //String 형 리턴
            //리턴 된 스트링은 servlet-context.xml에 정의된 경로와 파일 확장자가 조립되어
            //"WEB-INF/veiws/" + "home" + ".jsp"
    	}
    }

     

     

    prefix 로 설정된 문자열 과 suffix로 설정된 문자열 사이에 리턴된 문자열이 조립된다 

     

     

     

    /main, /other 리퀘스를 받는 클래스 두개를 추가했다 

    Attribute 사용법은 jsp와 같다 ${어트리부트 이름}

     

     

     

    만들어진 클래스를 스프릴 컨테이너에 넣기 -> 어노테이션 @Repository

     

     

     

    사용 방법 -> 클래스 객체를 @Autowired와 함께 전역 변수로 지정 한 후 사용 (getInstance() 필요 x)

     

     

    Service 클래스를 스프링 컨테이너에 넣기해서 @Service 사용 

    @Repository 를 사용해도 무리는 없으나 실행 시점과 기타의 이유로 구분하여 사용하는게 보통의 경우 

     

    @Service
    public class HomeService {
    	
    	@Autowired
    	HomeDao hdao;
    	
    	public String getMessage() {
    		String message = hdao.getMessage();
    		return message;
    	}
    }

     

     

    HomeDao 를 HomeService에서 호출하여 사용하는 방식으로 controller에서 직접 Dao 를 호출할 수 없도록 수정

     

     

    변경 후 실행해도 

     

     

    같은 결과를 보여준다면 성공

     

     


     

    스프링 게시판 만들기 

     

     

    * 프로젝트 생성 

     

    * pom.xml 버전 수정 + 추가할 사항 (하술) 

     

     

     

    <repositories>
        <repository>
            <id>oracle</id>
            <name>ORACLE JDBC Repository</name>
            <url>http://maven.jahia.org/maven2</url>  	
        </repository>
    </repositories>

     

     

     

    <!-- DataBase -->
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>12.1.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.1.6.RELEASE</version>
    </dependency>   
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5</version>
    </dependency>
    
    <!-- fileUpload -->
    <dependency> 
        <groupId>servlets.com</groupId> 
        <artifactId>cos</artifactId> 
        <version>05Nov2002</version> 
    </dependency>

     

     

    해당 위치에 코드들을 추가한다 

     

    - mchange : server.xml 에 추가했던 <resources>에 해당하는 부분

     

     

    * web.xml에 fitter 추가 (utf-8) - 위에 적었으므로 생략

     

    *HomeController.java 와 Home.jsp는 사용하지 않으므로 삭제해줌

     

    *사용할 패키지 생성

     

     

     

     

    *사용할 파일 생성

     

     

    위에서 부터 순서대로 @Controller/@Repository/없음/@Service 어노테이션을 달아준다 

     

     

    * SQL 

     

    -BOARD 테이블 

     

     

    전에 만들었던 bord 테이블을 그대로 사용할 것 

     

     

    CREATE TABLE BOARD(
    	NUM NUMBER(5) PRIMARY KEY,
    	PASS VARCHAR2(30), --게시물 수정 삭제를 위한 비밀번호 
    	USERID VARCHAR2(30),
    	EMAIL VARCHAR2(30),
    	TITLE VARCHAR2(50),
    	CONTENT VARCHAR2(1000),
    	READCOUNT NUMBER(4) DEFAULT 0, --조회수 
    	WRITEDATE DATE DEFAULT SYSDATE --작성일자
    	REPLYCNT NUMBER(3) DEFAULT 0,
    	IMGFILENAME VARCHAR2(50)
    )

     

    참고용 create 문

     

     

    -MEMBER TABLE

     

    CREATE TABLE MEMBER2(
    	NAME VARCHAR2(30),
    	USERID VARCHAR2(30) PRIMARY KEY,
    	PWD VARCHAR2(30),
    	EMAIL VARCHAR2(30),
    	PHONE VARCHAR2(30),
    	ADMIN CHAR(1) DEFAULT 0,
    	ZIP_NUM VARCHAR2(10),
    	ADDRESS VARCHAR2(100)
    );

     

     

    -REPLY 테이블

     

    CREATE REPLY2(
    	NUM NUMBER(7) PRIMARY KEY,
    	BOARDNUM NUMBER(5), --게시물 번호
    	USERID VARCHAR2(20),
    	WRITEDATE DATE DEFAULT SYSDATE,
    	CONTENT VARCHAR2(1000)
    );

     

     

    프로젝트에서 REPLY, MEMBER 테이블을 사용하고 있어서 그냥 REPLY2, MEMBER2라는 이름으로 테이블을 새로 만들었다.

     

     

    *프로젝트를 실행하면 loginForm.jsp 혹은 main.jsp 로 이동하기 

     

    Controller 

     

    @Controller
    public class MemberController {
    
    	@RequestMapping(value="/", method=RequestMethod.GET)
    	//프로젝트를 실행하면 보여질 페이지 
    	public String firstRequest(HttpServletRequest request, Model model) {
    		//session이 필요하기 때문에 전달인수로 HttpServletRequest를 받도록 함
    		
    		HttpSession session = request.getSession();
    		String url = "";
    		if(session.getAttribute("loginUser")!=null) {
    			url = "Member/main";
    		} else {
    			url = "Member/loginForm";
    		}
    		
    		return url;
    	}
    }

     

     

    main페이지로 이동할 때 모든 게시물들을 읽어서 이동해야하기 때문에 Model을 전달인수로 두었다

     

     

    jsp

     

    webapp 폴더 안에 있는 resources 폴더에 새로운 폴더를 생성하여 css, js 파일을 만든다. upload폴더는 파일 업로드를 위한 폴더

     

     

     

    위에 main 폴더 하위에 있는 resources는 시스템에서 사용하는 리소스이므로 헷갈리지 말고 webapp안에 resources안에 생성하도록 한다 

     

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>로그인</title>
    <link rel="stylesheet" type="text/css" href="resources/css/board.css"/>
    <script scr="resources/script/board.js"></script>
    </head>
    <body>
    <form action="login" method="post" name="frm">
    	<div class="box"> <div id="title">로그인</div></div>
    	<div class="box">
    		<div class="attr1">아이디</div>
    		<div class="attr2">&nbsp;&nbsp;
    			<input type="text" size="20" name="id" style="width:200px; height:20px;">
    		</div>
    	</div>
    	<div class="box">
    		<div class="attr1">비밀번호</div>
    		<div class="attr2">&nbsp;&nbsp;
    			<input type="password" size="20" name="pw" style="width:200px; height:20px;">
    		</div>
    	</div>
    	<div class="box">
    		<div  id="footer">
    			<input type="submit" value="로그인" onclick="return loginCheck();"/>
    			<input type="reset" value="다시작성"/>
    			<input type="button" value="회원가입" onclick="location href='memberJoinForm'"/>
    		</div>
    	</div>
    	
    	<div class="box2"><div id="footer">${message}</div></div>
    </form>
    </body>
    </html>

     

     

    CSS

     

    @charset "UTF-8";
    
    .box{
    	position:relative;
    	width: 500px; height: 50px; 
    	margin: 0 auto; text-align: center; line-height: 50px;
    }
    
    .temp {
    	position:relative;
    	width: 500px; height: 50px; 
    	margin: 0 auto;
    }
    
    .attr1 {
    	position:relative;
    	width: 248px; height: 48px; 
    	float:left; background: yellowgreen; font-size: 110%;
    	color: white; text-align: center; line-height: 48px; font-weight: bold; border: 1px solid green;
    }
    
    .attr2{
    	position:relative;
    	width: 248px; height: 48px; 
    	float:left; boarder: 1px solid green; font-size: 110%; text-align: center; line-height: 48px;
    }
    
    #footer{
    	position: relative; 
    	width: 500px; height: 50px; 
    	text-align: center; line-height: 50px; 
    }
    
    #wrap {
    	width: 971px;  margin: 0; margin-left: auto; margin-right: auto;
    }
    
    h1 {
    	color: green;
    }
    
    table {
    	width: 100%; 
    	border-collapse: collapse; 
    	font-size: 12px; line-height: 24px;
    }
    
    table td, th{
    	boarder: #d3d3d3 solid 1px; padding 5px;
    }
    
    th{
    	background: yellowgreen;
    }
    
    a{
    	text-decoration: none; color:black;
    }
    
    a:hover{
    	text-decoration: underline; color: green;
    }

     

     

    JS

     

    function loginCheck() {
    	if(document.frm.id==""){
    		alert("아이디를 입력하세요");
    		document.frm.id.focus();
    		return false;
    	} else if (document.frm.pw==""){
    		alert("비밀번호를 입력하세요");
    		document.frm.pw.focus();
    		return false;
    	} else { 
    		return true;
    	}
    }

     

     

     

    js가 적용이 안되는데 왜 안되는지 모르겠다...

     

     

    실제 데이터를 불러오기

     

    Service

     

    @Service
    public class MemberService {
    
    	@Autowired
    	MemberDao mdao;
    	
    	public MemberDto getMember(String id) {
    		MemberDto mdto = mdao.getMember(id);
    		return mdto;
    	}
    }

     

    DAO에서 멤버 정보를 가지고 옴

     

     

     

    Dao 

     

    @Repository
    public class MemberDao {
    	
    	Connection con = null;
    	PreparedStatement pstmt = null;
    	ResultSet rs = null;
    	
    	@Autowired
    	DataBaseManager dbm;
    
    	public MemberDto getMember(String id) {
    		MemberDto mdto = null;
    		String sql = "select * from member2 where userid=?";
    		con = dbm.getConnection();
    		try {
    			pstmt = con.prepareStatement(sql);
    			pstmt.setString(1, id);
    			rs = pstmt.executeQuery();
    			if(rs.next()) {
    				mdto = new MemberDto();
    				mdto.setEmail(rs.getString("email"));
    				mdto.setName(rs.getString("name"));
    				mdto.setPhone(rs.getString("phone"));
    				mdto.setPwd(rs.getString("pwd"));
    				mdto.setUserid(rs.getString("userid"));
    			}
    		} catch (SQLException e) { e.printStackTrace();
    		} finally { dbm.close(con,pstmt,rs); } 
    		return mdto;
    	}
    
    }

     

    dbm에서 연결 정보를 가져옴

     

     

    Dto 

     

    package com.ezen.board.dto;
    
    public class MemberDto {
    	private String userid;
    	private String pwd;
    	private String name;
    	private String email;
    	private String phone;
    	
    	public String getUserid() {
    		return userid;
    	}
    	public void setUserid(String id) {
    		this.userid = id;
    	}
    	public String getPwd() {
    		return pwd;
    	}
    	public void setPwd(String pwd) {
    		this.pwd = pwd;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public String getEmail() {
    		return email;
    	}
    	public void setEmail(String email) {
    		this.email = email;
    	}
    	public String getPhone() {
    		return phone;
    	}
    	public void setPhone(String phone) {
    		this.phone = phone;
    	}
    }

     

     

    Dbman

     

    @Repository
    public class DataBaseManager {
    	
    	@Autowired
    	DataBaseUserInfo uif;
    
    	public Connection getConnection() {
    		Connection con = null;
    		try {
    			Class.forName(uif.getDriver());
    			con = DriverManager.getConnection(uif.getUrl(), uif.getId(), uif.getPw());
    		} catch (ClassNotFoundException e) { e.printStackTrace();
    		} catch (SQLException e) { e.printStackTrace();
    		}
    		return con;
    	}
    
    	public void close(Connection con, PreparedStatement pstmt, ResultSet rs) {
    		try {
    			if(con!=null) con.close();
    			if(pstmt!=null) pstmt.close();
    			if(rs!=null) rs.close();
    		} catch (SQLException e) { e.printStackTrace();
    		}
    	}
    }

     

    uif에서 db 유저 정보를 가져옴

     

     

    DataBaseUserInfo

     

    @Repository
    public class DataBaseUserInfo {
    
    	private String driver = "oracle.jdbc.driver.OracleDriver";
    	private String url = "jdbc:oracle:thin:@localhost:1521:xe";
    	private String id = "scott";
    	private String pw = "tiger";
    	
    	public String getDriver() {
    		return driver;
    	}
    	public void setDriver(String driver) {
    		this.driver = driver;
    	}
    	public String getUrl() {
    		return url;
    	}
    	public void setUrl(String url) {
    		this.url = url;
    	}
    	public String getId() {
    		return id;
    	}
    	public void setId(String id) {
    		this.id = id;
    	}
    	public String getPw() {
    		return pw;
    	}
    	public void setPw(String pw) {
    		this.pw = pw;
    	}
    }

     

     

    Controller 수정

     

    @Controller
    public class MemberController {
    	
    	@Autowired
    	MemberService ms;
    
    	@RequestMapping(value="/", method=RequestMethod.GET)
    	//프로젝트를 실행하면 보여질 페이지 
    	public String firstRequest(HttpServletRequest request, Model model) {
    		//session이 필요하기 때문에 전달인수로 HttpServletRequest를 받도록 함
    		
    		HttpSession session = request.getSession();
    		String url = "";
    		if(session.getAttribute("loginUser")!=null) {
    			url = "board/main";
    		} else {
    			url = "Member/loginForm";
    		}
    		
    		return url;
    	}
    	
    	@RequestMapping(value="/login", method=RequestMethod.POST)
    	public String login(HttpServletRequest request, Model model) {
    		String url = "Member/loginForm";
    		String id = request.getParameter("id");
    		String pw = request.getParameter("pw");
    		String message = "";
    		
    		MemberDto mdto = ms.getMember(id); //id로 회원 조회 후 정보를 리턴 받음
    		if(mdto == null) {
    			message = "id를 조회할 수 없습니다.";
    		} else if (mdto.getPwd() == null) {
    			message = "데이터베이스 오류. 관리자에게 문의하세요.";
    		} else if (mdto.getPwd().equals(pw)) {
    			url = "board/main";
    			HttpSession session = request.getSession();
    			session.setAttribute("loginUser", mdto);
    			
    		} else if (!mdto.getPwd().equals(pw)) {
    			message = "비밀번호가 일치하지 않습니다.";
    		} else {
    			message = "로그인 오류. 관리자에게 문의하세요.";
    		}
    		
    		model.addAttribute("message", message);
    		return url;
    	}
    }

     

    로그인 정보와 유저 정보를 대조하여 message를 전달하는 코드 추가 

     

     

    -> 정상 로그인 완료 

     

     

     

    -> id가 DB에 없는 경우 

     

     

    -> 비밀번호가 일치하지 않는 경우 

     

     

     

    -> 로그인한 상태로 "/" request를 보낸 경우 

     

     


     

    *BoardList와 함께 main 출력하기 

     

    **MemberController에서 "board/main"으로 설정되어있던 url 을 "redirect:/boardList" 로 변경 한다 

    -> boardList.jsp로 가는 것이 아니라 boardList 로 RequestMapping 된 메소드 내용을 실행

     

    BoardDao 

     

    @Repository
    public class BoardDao {
    	
    	Connection con = null;
    	PreparedStatement pstmt = null;
    	ResultSet rs = null;
    	
    	@Autowired
    	DataBaseManager dbm;
    
    	public ArrayList<BoardDto> getBoardsMain() {
    		ArrayList<BoardDto> list = new ArrayList<>();
    		String sql = "select * from board order by num desc";
    		con = dbm.getConnection();
    		try {
    			pstmt = con.prepareStatement(sql);
    			rs = pstmt.executeQuery();
    			while(rs.next()) {
    				BoardDto bdto = new BoardDto();
    				bdto.setContent(rs.getString("content"));
    				bdto.setEmail(rs.getString("email"));
    				bdto.setImagename(rs.getString("imgfilename"));
    				bdto.setNum(rs.getInt("num"));
    				bdto.setPass(rs.getString("pass"));
    				bdto.setReadcount(rs.getInt("readcount"));
    				bdto.setReplycnt(rs.getInt("replycnt"));
    				bdto.setTitle(rs.getString("title"));
    				bdto.setUserid(rs.getString("userid"));
    				bdto.setWritedate(rs.getTimestamp("writedate"));
    				list.add(bdto);
    			}
    		} catch (SQLException e) { e.printStackTrace();
    		} finally { dbm.close(con, pstmt, rs); }
    		return list;
    	}
    }

     

     

    BoardDto 

     

    package com.ezen.board.dto;
    
    import java.sql.Timestamp;
    
    public class BoardDto {
    	private int num;
    	private int replycnt;
    	private int readcount;
    	private String pass;
    	private String userid;
    	private String email;
    	private String title;
    	private String content;
    	private String imagename;
    	private Timestamp writedate;
    	
    	public int getNum() {
    		return num;
    	}
    	public void setNum(int num) {
    		this.num = num;
    	}
    	public int getReplycnt() {
    		return replycnt;
    	}
    	public void setReplycnt(int replycnt) {
    		this.replycnt = replycnt;
    	}
    	public int getReadcount() {
    		return readcount;
    	}
    	public void setReadcount(int readcount) {
    		this.readcount = readcount;
    	}
    	public String getPass() {
    		return pass;
    	}
    	public void setPass(String pass) {
    		this.pass = pass;
    	}
    	public String getUserid() {
    		return userid;
    	}
    	public void setUserid(String userid) {
    		this.userid = userid;
    	}
    	public String getEmail() {
    		return email;
    	}
    	public void setEmail(String email) {
    		this.email = email;
    	}
    	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 getImagename() {
    		return imagename;
    	}
    	public void setImagename(String imagename) {
    		this.imagename = imagename;
    	}
    	public Timestamp getWritedate() {
    		return writedate;
    	}
    	public void setWritedate(Timestamp writedate) {
    		this.writedate = writedate;
    	}
    }

     

     

    BoardService

     

    @Service
    public class BoardService {
    
    	@Autowired
    	BoardDao bdao;
    
    	public ArrayList<BoardDto> getBoardsMain() {
    		ArrayList<BoardDto> list = bdao.getBoardsMain();
    		
    		return list;
    	}
    }

     

     

    BoardController

     

    @Controller
    public class BoardController {
    	
    	@Autowired
    	BoardService bs;
    	
    	@RequestMapping("boardList")
    	public String main(HttpServletRequest request, Model model) {
    		HttpSession session = request.getSession();
    		if(session.getAttribute("loginUser")==null) return "Member/loginForm";
    		else {
    			ArrayList<BoardDto> list = bs.getBoardsMain();
    			model.addAttribute("boardList", list);
    			
    		}
    		
    		return "board/main";
    	}
    }

     

    -> BoardController에서 "board/main"을 열게 함

     

     

    board/main.jsp 수정

     

     

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>메인</title>
    <link rel="stylesheet" type="text/css" href="resources/css/board.css"/>
    </head>
    <body>
    <div id="wrap" align="center">
    	<h1> 게시글 리스트 </h1>
    	<table class="list ">
    		<tr>
    			<td colspan="5" style="border:white; text-align:right;">
    				<div style="float:left;"> 
    					${loginUser.name}(${loginUser.userid})님 로그인
    					<input type="button" value="회원정보수정"
    					onClick = "location.href='board.do?command=editMemberForm'">
    					<input type="button" value="로그아웃"
    					onClick = "location.href='board.do?command=logout'"/>
    				</div>
    				<div style="float:right;">
    					<a href='boardWriteForm'> 게시글 등록 </a>
    				</div>
    			</td>
    		</tr>
    		<tr>
    			<th>번호</th>
    			<th>제목</th>
    			<th>작성자</th>
    			<th>작성일</th>
    			<th>조회수</th>
    		</tr>
    		<c:forEach items="${boardList}" var="board"> 
    			<tr >
    				<td align="center">${board.num}</td>
    				<td>
    					<a href="boardView?num=${board.num}"> 
    					${board.title}
    					
    					</a>
    				</td>
    				<td align="center">${board.userid}</td>
    				<td align="center"><fmt:formatDate value="${board.writedate}"/></td>
    				<td align="center">${board.readcount}</td>
    			</tr>
    		</c:forEach>
    	</table>
    </div>
    </body>
    </html>

     

     

     

     

     

     

    로그인 하면 main 페이지에 모든 게시물이 표시된다. 

     

     

     

     

     

    댓글

Designed by Tistory.