[새싹] 현대IT&E 231127 기록 - Spring

최정윤·2023년 11월 28일
0

새싹

목록 보기
30/67
post-thumbnail
post-custom-banner

1차 프로젝트

스프링 웹 프로젝트

팀 구성

  • 3명, 총 9개 팀. 랜덤.

주제

  • 커뮤니티 게시판(커뮤니티 주제는 자유)

제출물 : 17일 밤12시까지 메일로 전송

  • 소스(팀별)
  • ppt 또는 pdf(팀별)
  • 영상 1~10분(개인별 자신의 역할을 영상으로)
  • 팀별 영상(발표시 녹화? or 개별 녹화?)

  • 기간: 2023-12-11 09:00~ 2023-12-15 오전 (4.5 day)
  • 테이블 구조 및 컬럼 : 원하는대로
  • 기본적인 CRUD 필요.
    • 제목
    • 작성자
    • 날짜/시간
      • 오늘 게시물이면 시간만 출력 ex) 14:08:05
      • 오늘 게시물이 아닐 경우 날짜만 출력 ex) 2022-04-05
    • 조회수
    • 페이징
  • 그외 기능 (3가지 이상 기능 추가. 또 다른 아이디어 환영.)
    • 회원제
    • 추천/비추천
    • 팔로워, 게시물 모아보기
    • 파일업로드, 다운로드
    • 무한로딩
    • 새로운 게시판 자동 생성 기능
    • 검색 : 제목 또는 작성자 또는 내용 또는 댓글
    • 댓글
    • 답변형
    • 에디터...
    • 게시판 그룹관리

      🍃 01. 스프링 개발 환경 구축

      스프링 설치하기

      STS3 설치



오류 발생1

오류발생2

오류발생3

오류발생4

  • [zulu로 다시하기](-vm /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home/bin)
    STS.ini
-vm
/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home/bin
-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.6.300.v20210813-1054.jar
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.2.300.v20210828-0802
-product
org.springsource.sts.ide
--launcher.defaultAction
openFile
-vmargs
-Dosgi.requiredJavaVersion=11
-Dosgi.dataAreaRequiresExplicitInit=true
-Xms256m
-Xmx2048m
--add-modules=ALL-SYSTEM
-Dosgi.module.lock.timeout=10
-XstartOnFirstThread
-Dorg.eclipse.swt.internal.carbon.smallFonts
-Xdock:icon=../Resources/sts.icns

[참고링크]

STS4 설치

오류 발생

[참고링크]


스프링 환경설정


1.2. 스프링의 특징과 의존성 주입

  • 프레임워크를 이용한다는 것은 기본 흐름이나 구조를 정하고, 모든 팀원이 이 구조에 자신의 코드를 추가하는 방식으로 개발하게 됨을 의미한다.
  • 스프링은 비교적 시작이 늦은 프로젝트였지만, 가장 성공적인 경량 프레임워크이다.

1.2.1.1 스프링의 주요 특징

  • POJO 기반의 구성
  • 의존성 주입을 통한 객체 간의 관계 구성
  • AOP 지원
  • 편리한 MVC 구조
  • WAS의 종속적이지 않은 개발 환경

스프링 실습

STS 코드

전체 폴더 구조

파일별 코드

ArticleInsert.java

package net.developia.article.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class ArticleInsert extends AbstractController {

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// TODO Auto-generated method stub
		return new ModelAndView("/WEB-INF/views/article/insert.jsp");
	}

}

ArticleInsertAction.java

package net.developia.article.controller;

import lombok.extern.slf4j.Slf4j;
import net.developia.spring01.article.dto.ArticleDTO;
import net.developia.spring01.article.service.ArticleService;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class ArticleInsertAction extends AbstractController {
    ArticleService service = ArticleService.getInstance();

    @Override
    public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
        String name = request.getParameter("name");
        String title = request.getParameter("title");
        String content = request.getParameter("content");
        String password = request.getParameter("password");

        ArticleDTO articleDTO = new ArticleDTO();
        articleDTO.setName(name);
        articleDTO.setTitle(title);
        articleDTO.setPassword(password);
        articleDTO.setContent(content);

//        log.info(String.valueOf(articleDTO));

        try {
            service.insertArticle(articleDTO);
            return new ModelAndView("redirect:list");
        } catch (Exception e) {
            ModelAndView mav = new ModelAndView("/WEB-INF/views/article/result.jsp");
            mav.addObject("msg", "게시물 입력 실패 \n입력 폼으로 되돌아갑니다.");
            mav.addObject("url", "javascript:history.back();");
            return mav;
        }
    }


}

HomeController.java

package net.developia.spring01;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@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 );
		
		return "home";
	}
	
}

Spring.MVC

package net.developia.spring01;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class SpringMVC extends AbstractController {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// TODO Auto-generated method stub
		return new ModelAndView("/WEB-INF/views/hello.jsp", "msg", "Hello Spring MVC");
	}

}

ArticleInsert.java

package net.developia.spring01.article.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class ArticleInsert extends AbstractController {
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// TODO Auto-generated method stub
		return new ModelAndView("/WEB-INF/article/insert.jsp");
	}

}

ArticleInsertAction.java

package net.developia.spring01.article.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import lombok.extern.log4j.Log4j;
import net.developia.spring01.article.dto.ArticleDTO;
import net.developia.spring01.article.service.ArticleService;


//@Log4j
public class ArticleInsertAction extends AbstractController {
	//private static final Logger log = LoggerFactory.getLogger(ArticleInsertAction.class);

	ArticleService service = ArticleService.getInstance();
	
	@Override
	public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
		String name      = request.getParameter("name");
		String title     = request.getParameter("title");
		String password  = request.getParameter("password");
		String content   = request.getParameter("content");
		
		ArticleDTO articleDTO = new ArticleDTO();
		articleDTO.setName(name);
		articleDTO.setTitle(title);
		articleDTO.setPassword(password);
		articleDTO.setContent(content);
		
//		log.info(articleDTO);
		try {
			service.insertArticle(articleDTO);
			return new ModelAndView("redirect:list");
		} catch (Exception e) {
			ModelAndView mav = new ModelAndView("/WEB-INF/article/result.jsp");
			mav.addObject("msg", "게시물 입력 실패\\n입력 폼으로 되돌아갑니다.");
			mav.addObject("url", "javascript:history.back();");
			return mav;
		}
	}
}

ArticleList.java

package net.developia.spring01.article.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import net.developia.spring01.article.dto.ArticleDTO;
import net.developia.spring01.article.service.ArticleService;


@Slf4j
public class ArticleList extends AbstractController {
	
	ArticleService service = ArticleService.getInstance();
	
	@Override
	public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
		
		try {
			List<ArticleDTO> list = service.getArticleList();
			return new ModelAndView("/WEB-INF/views/article/list.jsp", "list", list);
			
		} catch (Exception e) {
			ModelAndView mav = new ModelAndView("/WEB-INF/views/article/result.jsp");
			mav.addObject("msg", "게시물 리스트 출력 실패");
			mav.addObject("url", "../");
			return mav;
		}
	}
}

ArticleDAO.java

package net.developia.spring01.article.dao;
import lombok.extern.slf4j.Slf4j;
import net.developia.spring01.article.dto.ArticleDTO;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ArticleDAO {
    private static final ArticleDAO dao = new ArticleDAO();
    private ArticleDAO() {
        try{
            Class.forName("net.sf.log4jdbc.DriverSpy");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static ArticleDAO getInstance() {
        return dao;
    }

    public void insertArticle(ArticleDTO articleDTO) throws SQLException {
        String sql =
                "insert into article(no, title, name, content, password)" + "values(seq_article.nextval, ?,  ?, ?, ?)";

        try(Connection conn = DriverManager.getConnection( // 연결
        		"jdbc:log4jdbc:oracle:thin:@localhost:1521/xepdb1", "ace","ace");
            PreparedStatement pstmt = conn.prepareStatement(sql)) { // 오라클 서버에 전달
            pstmt.setString(1, articleDTO.getTitle());
            pstmt.setString(2, articleDTO.getTitle());
            pstmt.setString(3, articleDTO.getContent());
            pstmt.setString(4, articleDTO.getPassword());
            pstmt.executeQuery();
        } catch (SQLException e) {
//            log.info(e.getMessage());
            throw e;
        }
    }

    public List<ArticleDTO> getArticleList() throws SQLException  {
        String sql =
                " SELECT no, title, name, regdate, readcount, password  FROM article ORDER BY no DESC";

        List<ArticleDTO> list = new ArrayList<>();
        try(Connection conn = DriverManager.getConnection(
        		"jdbc:log4jdbc:oracle:thin:@localhost:1521/xepdb1", "ace","ace");
            PreparedStatement pstmt = conn.prepareStatement(sql)) {
            ResultSet rs = pstmt.executeQuery();
            while(rs.next()) {
                ArticleDTO dto = new ArticleDTO();
                dto.setNo(rs.getLong("no"));
                dto.setTitle(rs.getString("title"));
                dto.setName(rs.getString("name"));
                dto.setRegdate(rs.getDate("regdate"));
                dto.setReadcount(rs.getInt("readcount"));
                list.add(dto);
            }
            return list;
        } catch (SQLException e) {
//            log.info(e.getMessage());
            throw e;
        }
    }
}

ArticleDTO.java

package net.developia.spring01.article.dto;

import java.io.Serializable;
import java.util.Date;

import org.apache.commons.codec.digest.DigestUtils;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class ArticleDTO implements Serializable {
	private long no;
	private String title;
	private String name;
	private String password;
	private String content;
	private Date regdate;
	private int readcount;
	
	public void setPassword(String password) {
		this.password = DigestUtils.sha512Hex(password);
	}
}

ArticleService.java

package net.developia.spring01.article.dto;

import java.io.Serializable;
import java.util.Date;

import org.apache.commons.codec.digest.DigestUtils;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class ArticleDTO implements Serializable {
	private long no;
	private String title;
	private String name;
	private String password;
	private String content;
	private Date regdate;
	private int readcount;
	
	public void setPassword(String password) {
		this.password = DigestUtils.sha512Hex(password);
	}
}

ReadyController.java

package net.developia.spring01.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class ReadyController extends AbstractController {

	@Override
	public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		return new ModelAndView("/WEB-INF/game/ready.jsp");
	}
	
}

ResultController.java

package net.developia.spring01.mvc;

import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;


public class ResultController extends AbstractController {

	@Override
	public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
        // Get user's choice
        int you = Integer.parseInt(request.getParameter("you"));

        // Generate a random choice for the computer
        int com = new Random().nextInt(3) + 1;

        // Determine the winner
        String result = determineWinner(you, com);

        // Set the result and choices as attributes
        ModelAndView mav = new ModelAndView();
        mav.setViewName("/WEB-INF/game/result.jsp");
        mav.addObject("you", getChoiceString(you));
        mav.addObject("com", getChoiceString(com));
        mav.addObject("result", result);

        return mav;
	}
	
    private String determineWinner(int you, int com) {
        if (you == com) {
            return "비겼습니다!";
        } else if ((you == 1 && com == 3) || (you == 2 && com == 1) || (you == 3 && com == 2)) {
            return "당신이 이겼습니다!";
        } else {
            return "컴퓨터가 이겼습니다!";
        }
    }
	
    private String getChoiceString(int choice) {
        switch (choice) {
            case 1:
                return "가위";
            case 2:
                return "바위";
            case 3:
                return "보";
            default:
                return "";
        }
    }

}

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<!-- 	<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> -->
	
	<context:component-scan base-package="net.developia.spring01" />
	
	<beans:bean name="/game/ready" class="net.developia.spring01.mvc.ReadyController"/>
	<beans:bean name="/game/result" class="net.developia.spring01.mvc.ResultController"/>
	
	<beans:bean name="/hello" class="net.developia.spring01.SpringMVC"/>
	<beans:bean name="/article/insert" class="net.developia.article.controller.ArticleInsert" />
	<beans:bean name="/article/insertAction" class="net.developia.article.controller.ArticleInsertAction" />
	<beans:bean name="/article/list" class="net.developia.spring01.article.controller.ArticleList"/>
</beans:beans>

root-context.xml

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
		
</beans>

insert.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/png" sizes="16x16" href="/webdev/kitty.png">
<title>Insert title here</title>
</head>
<body>
<form name="myform" method="post" action="insertAction">
<table>
   <caption>게시물 글쓰기</caption>
<tr>
   <th>제목</th>
   <td><input type="text" name="title" autofocus required /></td>
</tr>
<tr>
   <th>이름</th>
   <td><input type="text" name="name" required /></td>
</tr>
<tr>
   <th>비밀번호</th>
   <td><input type="password" name="password" required /></td>
</tr>
<tr>
   <th>내용</th>
   <td><textarea name="content" rows="5" cols="40"></textarea></td>
</tr>
<tr>
   <td colspan="2" align="center">
      <input type="submit" value="완료" />
   </td>
</tr>
</table>
</form>
</body>
</html>

list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- 구글 폰트 -->
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+KR" rel="stylesheet">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="../css/site.css">

<link rel="icon" type="image/png" sizes="16x16" href="/webdev/kitty.png">
<title>Insert title here</title>
</head>
<body>
<br/>
<div class="container">
   <div class="jumbotron"><h1>게시물 리스트</h1></div>
   
   <div style="text-align: right">1/1000</div>
   <table border="1" class="table">
   <thead class="thead-dark">
   <tr>
      <th scope="col">번호</th>
      <th scope="col">제목</th>
      <th scope="col">작성자</th>
      <th scope="col">작성일</th>
      <th scope="col">조회수</th>
   </tr>
   </thead>
   <c:forEach items="${list}" var="article">
   <tr>
      <th scope="row">${article.no}</th>
      <td>${article.title}</td>
      <td>${article.name}</td>
      <td>${article.regdate}</td>
      <td>${article.readcount}</td>
   </tr>
   </c:forEach>
   </table>
   <br/>
   <button type="button" class="btn btn-primary" onclick="javascript:location.href='insert'">글쓰기</button>
   
</div>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

</body>
</html>

result.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>
<script type="text/javascript">
alert('${msg}');
location.href='${url}';
</script>
</body>
</html>

실행 화면

http://localhost:8080/spring01/article/insert

http://localhost:8080/spring01/article/list

Oracle 코드

select * from article;

profile
개발 기록장
post-custom-banner

0개의 댓글