index.jsp 만들기

- 프로젝트를 실행할 때 가장 먼저 실행 해줄 jsp파일을 만들어 준다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP 게시판 웹 사이트</title>
</head>
<body>
	<script>
		location.href = 'main.jsp';
	</script>
</body>
</html>

 

부트스트랩 적용 방법

부트스트랩에서 다운받은 아래 폴더를 WebContent 폴더 안에 넣어준다.

login.jsp 만들기(로그인 폼 만들기)

- 로그인 폼을 만들어 준다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<!-- 부트 캠프 참조 -->
<meta name="viewport" content="width=device-width", initial-scale="1">

<!--  css 폴더에 있는 것을 참조한다. -->
<link rel="stylesheet" href="css/bootstrap.css">

<title>JSP 게시판 웹 사이트</title>
</head>
<body>

	<!-- 네비게이션 구현 (바)-->
	<nav class="navbar navbar-default">
		<!-- 헤드 로고를 담는 것 -->
		<div class="navbar-header">
			<button type="button" class="navbar-toggle collapsed"
				data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"
				aria-expanded="false">
				<!-- 아이콘 바 하나의 작데기를 표현(3개)  -->
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
			</button>
			<a class="navbar-brand" href="main.jsp">JSP 게시판 웹 사이트</a>
		</div>
		<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
			<!--리스트를 나타내는 곳  -->
			<ul class="nav navbar-nav">
				<li><a href="main.jsp">메인</a></li>
				<li><a href="bbs.jsp">게시판</a></li>
			</ul>
			
			<ul  class="nav navbar-nav navbar-right">
				<li class="dropdown">
					<a href="#" class="dropdown-toggle"
						data-toggle="dropdown" role="button" aria-haspopup="true"
						aria-expended="false">접속하기<span class="caret"></span></a>
					<ul class="dropdown-menu">
						<li class="active"><a href="login.jsp">로그인</a></li>
						<li><a href="join.jsp">회원가입</a></li>
					</ul>
				</li>
			</ul>
		</div>
	</nav>
	
	<!-- 로그인 양식 부 -->
	<div class="container">
		<div class="col-lg-4"></div>
		<div class="col=lg-4">
			<div class="jumbotron" style="padding-top:20px;">
			<!-- loginAction에 정보를 보내주겠다 -->
				<form method ="post" action="loginAction.jsp">
				<h3 style="text-align: center;">로그인 화면</h3>
				<div class="form-group">
					<input type="text" class="form-control" placeholder="아이디" name="userID" maxlength="20">
				</div>
				<div class="form-group">
					<input type="password" class="form-control" placeholder="비밀번호" name="userPassword" maxlength="20">
				</div>
					<input type="submit" class="btn btn-primary form-control" value="로그인">
				</form>
			</div>
		</div>
		<div class="col-lg-4"></div>
	</div>
	
	<!-- 애니메이션을 담당할 J쿼리를 홈페이지 넣어준다. -->
	<script src = "https://code.jquery.com/jquery-3.1.1.min.js"></script>
	
	<!-- WebContent 폴더에 있는 JS폴더의 부트스트랩을 가져와준다. -->
	<script src = "js/bootstrap.js"></script>
	
</body>
</html>

 

mysql db 만들기(테이블 만들기)

- 데이터베이스 안에 테이블을 만들어 준다.

create database bbs;

use bbs;

create table user (
userID varchar(20),
userPassword vachar(20),
userName varchar(20),
userGender varchar(20),
userEmail varchar(50),
primary key (userID)
);

show tables;

desc user;

insert into user values('hyunji', '123','현지','여자','hello@naver.com');

select * from user;

commit;

desc user;

 

User.java만들기(자바빈즈 만들기)

- 로그인 회원정보 변수들을 만들어 준다. 

- 자바빈즈를 만들어준다.

- 한명의 변수를 만들어준다.

package user;

public class User {
	
	private String userID;
	private String userPassword;
	private String userName;
	private String userGender;
	private String userEmail;
    
	public String getUserID() {
		return userID;
	}
	public void setUserID(String userID) {
		this.userID = userID;
	}
	public String getUserPassword() {
		return userPassword;
	}
	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserGender() {
		return userGender;
	}
	public void setUserGender(String userGender) {
		this.userGender = userGender;
	}
	public String getUserEmail() {
		return userEmail;
	}
	public void setUserEmail(String userEmail) {
		this.userEmail = userEmail;
	}

}

 

UserDAO.java 만들기(로그인 기능 만들기)

- 데이터베이스 접근 객체

- 실제로 DB 에서 정보를 저장하거나 연결하는 것을 나타낸다.

package user;

//외부 라이브러리를 연결해준다.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class UserDAO {

   private Connection conn;
   private PreparedStatement pstmt;
   private ResultSet rs;

   public UserDAO() {
      try {
         String dbURL = "jdbc:mysql://localhost:3306/bbs?serverTimezone=UTC";
         String dbID = "root";
         String dbPassword = "920424";
         //mysql에 접속 할 수 있도록 매개체 역할을 해주 코딩 
         Class.forName("com.mysql.jdbc.Driver");
         conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
         System.out.println("db 접속 완료");
         
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   
   // 로그인을 시도하는 함
   public int login(String userID, String userPassword) {
		String SQL = "SELECT userPassword FROM USER WHERE userID = ?";
				try {
					//해킹 기법을 방어하기 위한 코딩 
					pstmt = conn.prepareStatement(SQL);
					//값을 가져온다.
					pstmt.setString(1, userID) ; 
					//실행한 결과를 rs에 넣어준다.
					rs = pstmt.executeQuery();
					//만약값이 있다면, 
					if (rs.next()) { 
						//아이디가 있다면, 결과(비번)을 받아서 같다면, 
						if(rs.getString(1).equals(userPassword)) {
							return 1;// 로그인 성공.
						}
						else
							return 0;//비밀번호가 불일치 한다. 
					}
					return -1; //아이디가 없다.
				} catch (Exception e) {
					e.printStackTrace();
				}
				return -2; //데이터베이스 오류 
   		}//login end
  }

 

loginAction.jsp 만들기

- login.jsp에서 받은 아이디와 비번을 받아서 이 페이지가 처리를 해준다.

- mysql 커넥터를 lib폴더 안에 넣어준다.

- 프로젝트폴더를 우클릭해서 java build path에서 라이브러리 클릭 후, add JARs를 해준 후, lib폴더에 추가한 jar 파일을 추가해준다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="user.UserDAO" %>
<%@ page import="java.io.PrintWriter" %>
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="user" class="user.User" scope="page" />
<jsp:setProperty name="user" property="userID" />
<jsp:setProperty name="user" property="userPassword" />
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP 게시판 웹 사이트</title>
</head>
<body>
	<%
		
		String userID = null;
		if(session.getAttribute("userID") != null) {
			// 자신에게 할당된 유저아이디를 유저 아이디에 저장한다.
			userID = (String) session.getAttribute("userID");
		}
		//만약 유저아이디가 널값이 아니라면
		if (userID != null){
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("이미 로그인이 되어있습니다.");
			script.println("location.href = 'main.jsp'");
			script.println("</script>");
		}
		
		UserDAO userDAO = new UserDAO();
		int result = userDAO.login(user.getUserID(), user.getUserPassword());
		System.out.println(result);

		if(result == 1){
			session.setAttribute("userID", user.getUserID());
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("location.href = 'main.jsp'");
			script.println("</script>");
		}
		else if(result == 0){
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('비밀번호가 틀립니다.')");
			script.println("</script>");
			script.println("<script>");
			script.println("history.back()");
			script.println("</script>");
		}
		else if(result == -1){
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('존재하지 않는 아이디입니다.')");
			script.println("</script>");
			script.println("<script>");
			script.println("history.back()");
			script.println("</script>");
		}
		else if(result == -2){
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('데이터베이스 오류가 발생했습니다.')");
			script.println("</script>");
			script.println("<script>");
			script.println("history.back()");
			script.println("</script>");
		}
	%>
</body>
</html>

node.js 가 있는지 확인하는 코드

https://nodejs.org/ko/

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

최신 버전이 아닌 검증된 LTS버전을 받아준다. 
설치 후 정상적으로 다운받아졌는지 확인한다.
documents 폴더로 이동해준 후 boiler-plater폴더를 만들어 준다.
boiler-plate 폴더로 이동해준 후 npm 패키지를 만들어 준다.
기본 설정으로 계속 엔터를 쳐준 후 author에는 이름을 넣어준다.

 

에디터 다운받기

https://code.visualstudio.com/

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

알집파일을 풀어준 후 실행!

 

 

오픈 폴더를 누르고 아까 만들어둔 폴더를 입력한다.
아까 만들어둔 npm 패키지 파일을 확인하고 폴더 열기
제이슨파일
index.js 파일을 만들어 준다.(시작점을 만들어준다.)
터미널창에서 윗 코드를 입력하여 인스톨 해준다. (express 라이브러리를 다운받아서 사용하는 것)

 

index.js 에서 기본적인 express.js 앱 만들기

https://expressjs.com/ko/starter/hello-world.html

 

Express "Hello World" 예제

Hello world 예제 기본적으로 이 앱은 여러분이 작성할 수 있는 가장 간단한 Express 앱일 것입니다. 이 앱은 하나의 파일로 된 앱이며 Express 생성기를 통해 얻게 되는 앱과는 같지 않습니다. (이 예제�

expressjs.com

//express 모듈을 가지고 온다.
const express = require('express')
//새로운 펑션을 만들어서 app에 저장한다.
const app = express()
//백서버
const port = 3000

//Hello World!를 출력되게 한다.
app.get('/', (req, res) => res.send('Hello World!'))

//app을 실행 하는 것
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))

index.js에 윗 예시를 넣어준다.

 

"start" : "node index.js",를 추가해준다.(시작점을 추가해준다)

 

 

콘솔창에서 실행 시켜준다. 
웹브라우저 창에서서 해당되는 포트로 들어가면 결과물이 실행된다.

number 태그 : 입력창을 넣었을 때 왼쪽과 같이 번호를 입력하기 좋은 창이 나온다.
날짜와 숫자, 메일 등의 기본적인 형식을 따르도록 해준다.

autocomplete : 자동 완성 기능

placeholder : 입력창에 기본으로 보여줄 메세지를 보여준다.

autofocus : 자동으로 커서가 해당 입력창으로 간다.

 

정규식표현

 

required pattern

[a-zA-Z] : 알파벳의 대소문자를 한 개 입력한다.

. : 어떤 문자도 상관 없이 입력 할 수 있다.

+ : 모든 문자가 하나 이상 온다.

[0-9] : 0부터 9까지 입력이 가능하다.

':: IT > HTML' 카테고리의 다른 글

[웹키워드#1] HTML, CSS, SASS, SCSS  (0) 2020.07.23
[HTML]form태그의 enctype 속성  (0) 2020.07.23
[HTML] 모바일 지원 메타태그  (0) 2020.06.01
[HTML] 의미론적인 태그  (0) 2020.06.01
[HTML] from: hidden / lable  (0) 2020.05.31
<head>
  <title>HTML - 수업소개</title>
  <meta charset="utf-8">
  <mata name="viewport" content = "width = device-width, initial-scale=1.0">
</head>

width = device-width

: 화면의 폭을 디바이스 크기로 지정하라.

 

initial-scale=1.0

: 화면을 축소하지도 확대하지도 않은 상태로 웹페이지를 시작하라.

<!DOCTYPE html>
<html>

<head>
  <title>HTML - 수업소개</title>
  <meta charset="utf-8">
</head>

<body>

  <!--의미론적인 태그 <head>
    웹사이트 내에 별다른 기능은 하지 않지만 개발자에게 head의 영역을 보여주는 태그-->
  <head>
	<h1><a href="index.html">HTML</a></h1>
  </head>

<!-- <nav> 컨텐츠에 네비게이션의 영역은 이것이다 라는 것을 보여주는 태그-->
<nav>
  <ol>
    <li><a href="1.html">기술소개</a></li>
    <li><a href="2.html">기본문법<a/></li>
    <li><a href="3.html">하이퍼텍스트와 속성</a></li>
    <li><a href="4.html">리스트와 태그의 중첩</a></li>
  </ol>
</nav>

<!-- <section> 여러가지의 본문을 하나로 묶어주는 태그 -->
<section>
   <!--<article> 본문의 영역을 나타내 주는 태그, 여러가지의 본문을 나타낼 수 있음 -->
   <article>
      <h2>기술소개</h2>
      HTML은 HyperText Markup Language의 약자로서 웹페이지를 만드는 언어입니다.
   </article>

   <article>
      <h2>기술소개2</h2>
      HTML은 HyperText Markup Language의 약자로서 웹페이지를 만드는 언어입니다.
   </article>
</section>

<footer>
  <ul>
  	<li><a href="#"></li>
  </ul>
</footer>

</body>
</html>

hidden 의 주소줄 결과 값

 

lavel의 결과값

 

':: IT > HTML' 카테고리의 다른 글

[HTML] 모바일 지원 메타태그  (0) 2020.06.01
[HTML] 의미론적인 태그  (0) 2020.06.01
[HTML] HTML의 웹 기본 태그, <head>와 <body> 태그 설명  (0) 2020.05.22
[HTML5] 태그  (0) 2020.03.25
[HTML] 기초문법과 태그  (0) 2020.03.24

git

- 형상 관리 시스템(Verson Control System) 의 한 종류

- 주로 개발자들이 프로그램과 관련된 파일들을 저장하는 데 사용

 

commit

-게임의 세이브에 해당하는 행동

-커밋을 하려면 저장을 원하는 파일들을 묶어서 커밋 명령을 수행

 

add

- 스테이지에 파일을 올린다.

 

push

- github에 업로드 한다.

 

clone

- 원격 저장소(github)을 내 컴퓨터에 복사해온다.

 

코드뭉치버리기

- 마지막 커밋으로 돌아가고 싶을 때 사용

 

브랜치 (branch)

- 기능 변경을 하고 싶을 때 생성 및 사용

- 특정 커밋으로 돌아가고 싶을 때

 

머지 (merge)

-한 브랜치의 내용을 다른 브랜치에 반영

- 하나의 브랜치를 현재 브랜치와 합치는 것

-현재 브랜치 = 헤드(HEAD) 브랜치

 

체크아웃 (checkout)

-저장소에서 특정 커밋이나 브랜치로 돌아가고 싶을 때 사용

 

스테시

- 임시 저장 공간에 현재 작업 내용을 저장합니다.

- git에 업로드 되지 않은 파일은 스테시가 되지 않는다.

- 필요하다면 이전 커밋을 덮어쓰기도 가능하다.

 

revert

- 대상 커밋은 사라지지 않는다,

- 대상 커밋의 내용을 되돌린 새로운 커밋이 생긴다.

- 단점: 충돌이 날 가능성이 매우 높고, 어렵다.

- SourceTree 에서는 커밋 선택 – 우클릭 – 커밋 되돌리기

 

revert로 여러 커밋을 되돌리려면 어떻게 하나요?

- 최신부터 순서대로 revert를 반복 적용하면 됩니다

 

새로운 브랜치를 만들어 체크아웃하기

- 되돌릴 커밋 대상으로 브랜치를 생성 후 체트아웃

- 변경 사항 수정 후 커밋

- 마스터에 병합

 

rebase

- 병합과 마찬가지로 두 브랜치의 내용을 하나로 합치고 싶을 때 사용

- 기본 머지(병합)과 달리 트리가 더 깔끔하게 유지 됩니다.

- but 이미 원격에 있는 브랜치를 리베이스 하면 안된다. 충돌 가능성이 높고 위험.

 

 

 

git 가입하기

ttps://github.com/join 

 

Build software better, together

GitHub is where people build software. More than 50 million people use GitHub to discover, fork, and contribute to over 100 million projects.

github.com

Source Tree 설치

https://www.sourcetreeapp.com/ 

 

Sourcetree | Free Git GUI for Mac and Windows

A Git GUI that offers a visual representation of your repositories. Sourcetree is a free Git client for Windows and Mac.

www.sourcetreeapp.com

git 연습하기

https://learngitbranching.js.org/

 

Learn Git Branching

An interactive Git visualization tool to educate and challenge!

learngitbranching.js.org

-- 추가(20200811)

새브랜치로 이동
git checkout [브랜치명] 

git merge bugFix(합치고자하는 상대 브랜치)

bugFix의 내용을 마스터와 합체
git rebase master

마스터(부모)를 bugFix와 합체
git rebase bugFix


HEAD : 현재 작업중인 커밋
git checkout c1

부모(헤드)
git checkout master^
조부모(헤드)
git checkout master^^


상대 참조(4칸위)
git checkout HEAD~4
브랜치 강제 옮기기(-f)
git branch -f master HEAD~3

리셋
git reset HEAD~1

revert(되돌리기)
git revert HEAD

-----------------------------------------
헤드 아래에 있는 일련의 커밋들에 대한 복사본 만들기
git cherry-pick c2 c4

UI 선택해서 복붙
git rebase -i HEAD~4
git rebase -i overHere 

 

git clone


o/ < 원격저장소 이름
git checkout origin/master; git commit

원격저장소에서 데이터를 가져오는 방법(동기화)
git fetch


fetch 후 merge 하는 작업
git pull


git clone
git fakeTeamwork 2
git pull

내보내기
git push

최신상태로 돌리기
git fetch; git rebase o/master; git qush
git fetch; git merge o/master; git push
git pull --rebase; git push
git pull; git push

HTML 구조 구성하기

 

 <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <!-- 상단의 네비게이션 바 부분 -->
    <div class="nav">
      <div class ="nav-item">메뉴1</div>
      <div class ="nav-item">메뉴2</div>
      <div class ="nav-item">메뉴3</div>
      <div class ="nav-item">메뉴4</div> 
    </div>

    <!-- 중간 테이블 -->
    <div class = "main">
      <div class ="title">
        타이틀 부분
      </div>
      <div class="subtitle">
      타이틀 아래의 내용을 기입 할 수 있습니다.
      </div>
    </div>
  <div class = "leftside">
    <div class="leftside-item">
      왼쪽입니다.
    </div>
    <div class="leftside-item">
      왼쪽2입니다.
    </div>
    <div class="leftside-item">
      왼쪽3입니다.
    </div>
  </div>

    <script src="script.js"></script>
  </body>
</html>

 

 

 


CSS (스타일링) 구현하기

 

.box{
	width : 100px;
    height : 100px;
    border : 1px solid black;
}

1. css는 HTML 엘레먼트의 스타일링을 하기 위해 사용
2. box는 class="box" 속성을 가진 엘레먼트를 스타일하고 싶다고 명시하는 것
3. width,height,border 같은 규칙을 써서 엘레먼트의 모양 및 위치를 바꿈

 <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />

    <!-- 네비게이션 바 부분 css 
    height : 높이를 지정
    border-bottom : 1px solid black : 선을 하나 그어준다.
    display : flex; :  한 줄로 정렬한다.
    align-items : center; : 글자를 중간으로 옮긴다.
    -->
    <style>
      .nav {
        height : 70px;
        border-bottom : 1px solid black; 
        display : flex;
        align-items : center;
      }
    </style>


  </head>
  <body>
    <!-- 상단의 네비게이션 바 부분 -->
    <div class="nav">
      <div class ="nav-item">메뉴1</div>
      <div class ="nav-item">메뉴2</div>
      <div class ="nav-item">메뉴3</div>
      <div class ="nav-item">메뉴4</div> 
    </div>

    <!-- 중간 테이블 -->
    <div class = "main">
      <div class ="title">
        타이틀 부분
      </div>
      <div class="subtitle">
      타이틀 아래의 내용을 기입 할 수 있습니다.
      </div>
    </div>
  <div class = "leftside">
    <div class="leftside-item">
      왼쪽입니다.
    </div>
    <div class="leftside-item">
      왼쪽2입니다.
    </div>
    <div class="leftside-item">
      왼쪽3입니다.
    </div>
  </div>

    <script src="script.js"></script>
  </body>
</html>

 

스타일링의 결과 값


 <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />

    <!-- 네비게이션 바 부분 css -->
    <style>
      .nav {
        height : 70px;
        border-bottom : 1px solid black; 
        display : flex;
        align-items : center;
      }
      .nav-right-items {
          display : flex;
          margin-left : auto;
      }
      .nav-item {
        margin-left : 10px;
      }
      .company-name {
        margin-left : 20px;
      }
      .title {
        font-size : 60px;
        font-weight : bold;
      }
      .subtitle { 
        font-size : 40px;
        font-weight : 300;
      }

    </style>


  </head>
  <body>
    <!-- 상단의 네비게이션 바 부분 -->
    <div class="nav">
      <div class="company-name">
        GO치삼의 개발일지
      </div>
      <!-- 감싼 부분을 nav-right-item로 정의한다. -->
      <div class="nav-right-items">
        <div class ="nav-item">메뉴1</div>
        <div class ="nav-item">메뉴2</div>
        <div class ="nav-item">메뉴3</div>
        <div class ="nav-item">메뉴4</div> 
      </div>
    </div>

    <!-- 중간 테이블 -->
    <div class = "main">
      <div class ="title">
        타이틀 부분
      </div>
      <div class="subtitle">
      타이틀 아래의 내용을 기입 할 수 있습니다.
      </div>
    </div>
  <div class = "leftside">
    <div class="leftside-item">
      왼쪽입니다.
    </div>
    <div class="leftside-item">
      왼쪽2입니다.
    </div>
    <div class="leftside-item">
      왼쪽3입니다.
    </div>
  </div>

    <script src="script.js"></script>
  </body>
</html>

스타일링의 결과값

 


 

 <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />

    <!-- 네비게이션 바 부분 css -->
    <style>
      .nav {
        height : 70px;
        border-bottom : 1px solid black; 
        display : flex;
        align-items : center;
      }
      .nav-right-items {
          display : flex;
          margin-left : auto;
      }
      .nav-item {
        margin-left : 10px;
      }
      .company-name {
        margin-left : 20px;
      }
      .title {
        text-align : center;
        font-size : 60px;
        font-weight : bold;
      }
      .subtitle { 
        text-align : center;
        font-size : 40px;
        font-weight : 300;
      }

    </style>


  </head>
  <body>
    <!-- 상단의 네비게이션 바 부분 -->
    <div class="nav">
      <div class="company-name">
        GO치삼의 개발일지
      </div>
      <!-- 감싼 부분을 nav-right-item로 정의한다. -->
      <div class="nav-right-items">
        <div class ="nav-item">메뉴1</div>
        <div class ="nav-item">메뉴2</div>
        <div class ="nav-item">메뉴3</div>
        <div class ="nav-item">메뉴4</div> 
      </div>
    </div>

    <!-- 중간 테이블 -->
    <div class = "main">
      <div class ="title">
        타이틀 부분
      </div>
      <div class="subtitle">
      타이틀 아래의 내용을 기입 할 수 있습니다.
      </div>
    </div>
  <div class = "leftside">
    <div class="leftside-item">
      왼쪽입니다.
    </div>
    <div class="leftside-item">
      왼쪽2입니다.
    </div>
    <div class="leftside-item">
      왼쪽3입니다.
    </div>
  </div>

    <script src="script.js"></script>
  </body>
</html>

글의 내용을 중앙으로 정렬한다.

 

정렬의 결과값

 


 <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />

    <!-- 네비게이션 바 부분 css -->
    <style>
      .nav {
        height : 70px;
        border-bottom : 1px solid black; 
        display : flex;
        align-items : center;
      }
      .nav-right-items {
          display : flex;
          margin-left : auto;
      }
      .nav-item {
        margin-left : 10px;
      }
      .company-name {
        margin-left : 20px;
      }
      .title {
        text-align : center;
        font-size : 3.5rem;
        font-weight : bold;
      }
      .subtitle { 
        text-align : center;
        font-size : 1.25rem;
        font-weight : 300;
      }
      .main {
        width : 800px;
        margin : 0 auto;
        margin-top : 60px;
      }

    </style>


  </head>
  <body>
    <!-- 상단의 네비게이션 바 부분 -->
    <div class="nav">
      <div class="company-name">
        GO치삼의 개발일지
      </div>
      <!-- 감싼 부분을 nav-right-item로 정의한다. -->
      <div class="nav-right-items">
        <div class ="nav-item">메뉴1</div>
        <div class ="nav-item">메뉴2</div>
        <div class ="nav-item">메뉴3</div>
        <div class ="nav-item">메뉴4</div> 
      </div>
    </div>

    <!-- 중간 테이블 -->
    <div class = "main">
      <div class ="title">
        타이틀 부분
      </div>
      <div class="subtitle">
      타이틀 아래의 내용을 기입 할 수 있습니다.
      </div>
    </div>
  <div class = "leftside">
    <div class="leftside-item">
      왼쪽입니다.
    </div>
    <div class="leftside-item">
      왼쪽2입니다.
    </div>
    <div class="leftside-item">
      왼쪽3입니다.
    </div>
  </div>

    <script src="script.js"></script>
  </body>
</html>

 

margin-top으로 윗 부붙에 여백을 지정해줍니다.


 

 <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />

    <!-- 네비게이션 바 부분 css -->
    <style>
      .nav {
        height : 70px;
        border-bottom : 1px solid black; 
        display : flex;
        align-items : center;
      }
      .nav-right-items {
          display : flex;
          margin-left : auto;
      }
      .nav-item {
        margin-left : 10px;
      }
      .company-name {
        margin-left : 20px;
      }
      .title {
        text-align : center;
        font-size : 3.5rem;
        font-weight : bold;
      }
      .subtitle { 
        text-align : center;
        font-size : 1.25rem;
        font-weight : 300;
      }
      .main {
        width : 1000px;
        margin : 0 auto;
        margin-top : 60px;
      }
      .leftside-item {
        width : 300px;
        height : 350px;
        border : 1px solid black;
        margin : 20px;
        border-radius : 4px;
      }
      .leftside {
        display : flex;
      }
      .leftside-item-title {
        font-size: 1.5rem;
        background : rgba(0,0,0,.03);
        text-align : center;
        height : 53px;
        line-height : 53px;
        border-bottom: 1px solid black;
      }
      .leftside-item-price {
        font-size: 1.5rem;
        font-weight : bold;
        padding : 20px;
        text-align : center;
      }
      .leftside-item-detail {
        font-size: 1.0rem;
        font-weight : bold;
        padding : 20px;
        text-align : center;

      }
      .leftside-item-button {
        padding: .5rem 1rem;
        font-size: 1.25rem;
        line-height : 1.5;
        border-radius : .3rem;
        color : #007bff;
        background-color : transparent;
        background-image : none;
        border-color: #007bff;
        margin-top : 20px;
        margin-left : 85px;
      }
      .leftside-item-button-active { 
        background-color : #007bff;
        color : white;
      }

    </style>


  </head>
  <body>
    <!-- 상단의 네비게이션 바 부분 -->
    <div class="nav">
      <div class="company-name">
        GO치삼의 개발일지
      </div>
      <!-- 감싼 부분을 nav-right-item로 정의한다. -->
      <div class="nav-right-items">
        <div class ="nav-item">메뉴1</div>
        <div class ="nav-item">메뉴2</div>
        <div class ="nav-item">메뉴3</div>
        <div class ="nav-item">메뉴4</div> 
      </div>
    </div>

    <!-- 중간 테이블 -->
    <div class = "main">
      <div class ="title">
        타이틀 부분
      </div>
      <div class="subtitle">
      타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.타이틀 아래의 내용을 기입 할 수 있습니다.
      </div>
      <div class = "leftside">
        <div class="leftside-item">
          <div class = "leftside-item-title">
            왼쪽의 윗칸
          </div>

          <div class = "leftside-item-price">
            왼쪽의 중간칸(가격)
          </div>

          <div class = "leftside-item-detail">
            왼쪽의 아랫칸
          </div>

          <button class = "leftside-item-button">
            클릭하세요
          </button>

        </div>

        <div class="leftside-item">

          <div class = "leftside-item-title">
            왼쪽1의 윗칸
          </div>

          <div class = "leftside-item-price">
            왼쪽1의 중간칸
          </div>

          <div class = "leftside-item-detail">
            왼쪽1의 아랫칸
          </div>

          <button class = "leftside-item-button leftside-item-button-active">
            클릭하세요
          </button>

        </div>

        <div class="leftside-item">

          <div class = "leftside-item-title">
            왼쪽2의 윗칸
          </div>

          <div class = "leftside-item-price">
            왼쪽2의 중간칸
          </div>

          <div class = "leftside-item-detail">
            왼쪽2의 아랫칸
          </div>

          <button class = "leftside-item-button leftside-item-button-active" >
            클릭하세요
          </button>

        </div>
      </div>
  </div>

    <script src="script.js"></script>
  </body>
</html>

 

에디터 프로그램

https://repl.it/

 

The collaborative browser based IDE

Repl.it is a simple yet powerful online IDE, Editor, Compiler, Interpreter, and REPL. Code, compile, run, and host in 50+ programming languages: Clojure, Haskell, Kotlin (beta), QBasic, Forth, LOLCODE, BrainF, Emoticon, Bloop, Unlambda, JavaScript, CoffeeS

repl.it


HTML 태그의 기본

기본 태그 설명


<head> 태그 안의 태그들

 

style.css 안에서 태그를 해주면 html 태그 안에 <style>를 해주지 않아도 <link> 태그에서 css 파일을 불러와 반영해줄 수 있다.


<div class="box">박스</div>
<a href = "naver.com">네이버</a>

1. <div></div>는 태그라고 하고 항상 열림/닫힘 한 쌍이 있다.
2. class="box"은 속성이라고 함. 이 class 속성을 이용해서 나중에 css로 스타일링을 할 수 있음.
3. 합쳐서 "엘레먼트"라고 부름

<body>태그 관련텍스트 관련 태그들

텍스트 관련 태그


미디어 관련 태그들

<!-- html 라는 것을 표현한다.-->
<html>
  <!-- html 안에는 <head>,<body> 두 가지 태그가 있음 -->
  <head>
    <!-- 어떤 문서가 들어가는지 명시한다.-->
    <title>타이틀을 적어주면 탭 창의 제목이 바뀝니다.</title>
    <!--link 태그는 다른 곳에 저장되어있는 파일들을 불러와라라는 뜻이다.-->
    <link href="style.css" rel="stylesheet" type="text/css"/>
    <!-- mata 태그는 이 파일이 어떤 정보를 갖고 있는지를 나타내는 태그 이다. 스크랩할 때 간단하게 소개하는 멘트가 보여진다.-->
    <meta name="description" content="HTML을 공부하는 문서">
    <!--style태그는 css를 적어 줄 수 있다.-->
  </head>

  <body>
  
    <!-- 미디어 관련 태그들 -->

    <!-- 사진을 불러 올 때 쓰는 태그 
    src 는 소스의 줄임말이다. -->
    <img src="이미지주소"/>
    <!-- 비디오를 불러 올 때 쓰는 태그 -->
    <video src="비디오주소" controls />

    <!-- 링크 태그 -->
    <a href="naver.com">네이버</a>
    <!-- 새 창을 열어서 랑크 주소로 이동 -->
    <a href="google.com" target="_blank">구글</a>

  </body>

</html>

테이블 태그 

<!-- html 라는 것을 표현한다.-->
<html>
  <!-- html 안에는 <head>,<body> 두 가지 태그가 있음 -->
  <head>
    <!-- 어떤 문서가 들어가는지 명시한다.-->
    <title>타이틀을 적어주면 탭 창의 제목이 바뀝니다.</title>
    <!--link 태그는 다른 곳에 저장되어있는 파일들을 불러와라라는 뜻이다.-->
    <link href="style.css" rel="stylesheet" type="text/css"/>
    <!-- mata 태그는 이 파일이 어떤 정보를 갖고 있는지를 나타내는 태그 이다. 스크랩할 때 간단하게 소개하는 멘트가 보여진다.-->
    <meta name="description" content="HTML을 공부하는 문서">
    <!--style태그는 css를 적어 줄 수 있다.-->
  </head>

  <body>

    <!-- 테이블 태그 -->
    
    <table border="1">
      <!-- 테이블의 칼럼 개수, 칼럼 이름 -->
      <thead>
        <!-- 칼럼 2개 생성 -->
        <tr>
          <th>이름</th>
          <th>나이</th>
        </tr>
      </thead>

      <!-- 표의 내용이 들어감 -->
      <tbody>
        <!-- 첫 줄 -->
        <tr>
          <td>고양이</td>
          <td>6살</td>
        </tr>

        <!-- 두번째 줄 -->
        <tr>
          <td>물고기</td>
          <td>1살</td>
        </tr>

      </tbody>
    </table>
    
  </body>

</html>

 

테이블 태그의 결과값

 


목록 태그들

<!-- html 라는 것을 표현한다.-->
<html>
  <!-- html 안에는 <head>,<body> 두 가지 태그가 있음 -->
  <head>
    <!-- 어떤 문서가 들어가는지 명시한다.-->
    <title>타이틀을 적어주면 탭 창의 제목이 바뀝니다.</title>
    <!--link 태그는 다른 곳에 저장되어있는 파일들을 불러와라라는 뜻이다.-->
    <link href="style.css" rel="stylesheet" type="text/css"/>
    <!-- mata 태그는 이 파일이 어떤 정보를 갖고 있는지를 나타내는 태그 이다. 스크랩할 때 간단하게 소개하는 멘트가 보여진다.-->
    <meta name="description" content="HTML을 공부하는 문서">
    <!--style태그는 css를 적어 줄 수 있다.-->
  </head>

  <body>
    <!-- 목록 태그들 -->
    
    <!-- <ol>은 ordered list (순번을 붙여줌) -->
    <ol>
      <li>보비</li>
      <li>쵸비</li>
      <li>예쁘니</li>
    </ol>

    <!-- <ul> : unordered list / 앞에 점을 찍어주는 태그 -->
    <ul>
      <li>보비</li>
      <li>쵸비</li>
      <li>예쁘니</li>
    </ul>
    
  </body>

</html>

 

목록 태그의 결과 값


구역을 나누는 태그들

<!-- html 라는 것을 표현한다.-->
<html>
  <!-- html 안에는 <head>,<body> 두 가지 태그가 있음 -->
  <head>
    <!-- 어떤 문서가 들어가는지 명시한다.-->
    <title>타이틀을 적어주면 탭 창의 제목이 바뀝니다.</title>
    <!--link 태그는 다른 곳에 저장되어있는 파일들을 불러와라라는 뜻이다.-->
    <link href="style.css" rel="stylesheet" type="text/css"/>
    <!-- mata 태그는 이 파일이 어떤 정보를 갖고 있는지를 나타내는 태그 이다. 스크랩할 때 간단하게 소개하는 멘트가 보여진다.-->
    <meta name="description" content="HTML을 공부하는 문서">
    <!--style태그는 css를 적어 줄 수 있다.-->
    <style>
      .top{
        background: red;
        height : 100px;
      }
      .mid{
        background: blue;
        height : 100px;
      }
      .bot{
        background: green;
        height : 100px;
      }
    </style>
  </head>

  <body>
    <!-- 구역을 나누는 태그들 -->
    <!-- <div> vs <span> -->
      <div class ="top">상단</div>
      <div class="mid">중단</div>
      <div class="bot">하단</div>
  </body>

</html>

 

구역을 나누는 태그의 결과값

<!-- html 라는 것을 표현한다.-->
<html>
  <!-- html 안에는 <head>,<body> 두 가지 태그가 있음 -->
  <head>
    <!-- 어떤 문서가 들어가는지 명시한다.-->
    <title>타이틀을 적어주면 탭 창의 제목이 바뀝니다.</title>
    <!--link 태그는 다른 곳에 저장되어있는 파일들을 불러와라라는 뜻이다.-->
    <link href="style.css" rel="stylesheet" type="text/css"/>
    <!-- mata 태그는 이 파일이 어떤 정보를 갖고 있는지를 나타내는 태그 이다. 스크랩할 때 간단하게 소개하는 멘트가 보여진다.-->
    <meta name="description" content="HTML을 공부하는 문서">
    <!--style태그는 css를 적어 줄 수 있다.-->
    <style>
      .top{
        background: green;
        height : 100px;
      }
      .mid{
        background: yellow;
        height : 100px;
      }
      .bot{
        background: red;
        height : 100px;
      }

      .like{
        background: green;
        height : 100px;
      }
      .sub{
        background: yellow;
        height : 100px;
      }
      .comment{
        background: red;
        height : 100px;
      }
    </style>
  </head>

  <body>
    <!-- 구역을 나누는 태그들 -->
    <!-- <div> vs <span> -->

      <!-- <div> -->
      <div class ="top">상단</div>
      <div class="mid">중단</div>
      <div class="bot">하단</div>
      <!-- <span> -->
      <span class ="like">좋아요</div>
      <span class="sub">구독</div>
      <span class="comment">댓글</div>

  <!-- <div>(block element)는 한 줄 전체 공간을 차지
      <span>(inline element)은 자기 내용물 만큼의 공간만 차지 -->

  </body>

</html>

<div> vs <span>의 결과값

 


인풋 태그

<!-- html 라는 것을 표현한다.-->
<html>
  <!-- html 안에는 <head>,<body> 두 가지 태그가 있음 -->
  <head>
    <!-- 어떤 문서가 들어가는지 명시한다.-->
    <title>타이틀을 적어주면 탭 창의 제목이 바뀝니다.</title>
    <!--link 태그는 다른 곳에 저장되어있는 파일들을 불러와라라는 뜻이다.-->
    <link href="style.css" rel="stylesheet" type="text/css"/>
    <!-- mata 태그는 이 파일이 어떤 정보를 갖고 있는지를 나타내는 태그 이다. 스크랩할 때 간단하게 소개하는 멘트가 보여진다.-->
    <meta name="description" content="HTML을 공부하는 문서">
  </head>

  <body>
    <!-- 인풋 태그들 -->
    텍스트 : <input type="text" />
    체크박스 : <input type="checkbox" />
    라디오 : <input type="radio" />
    색깔 : <input type="color" />
    여러문장 : <textarea></textarea>
    드랍다운 : <select name="name">
      <option value="보비">보비</option>
      <option value="보비">쵸비</option>
    </select>

    <br>
    
    로그인 :
    <form>
      <input type="email" placeholder="이메일" />
      <input type="password" placeholder="비밀번호" />
      <button type="submit">로그인</button>
    </form>
    
  </body>

</html>

 

인풋 태그의 결과 값

 

 

':: IT > HTML' 카테고리의 다른 글

[HTML] 모바일 지원 메타태그  (0) 2020.06.01
[HTML] 의미론적인 태그  (0) 2020.06.01
[HTML] from: hidden / lable  (0) 2020.05.31
[HTML5] 태그  (0) 2020.03.25
[HTML] 기초문법과 태그  (0) 2020.03.24

 

부트스트랩 :  웹 개발 라이브러리.(대부분이 오픈소스이다.)

반응형  웹 :  디바이스, 모바일, 태블릿에 상관없이 같은 페이지를 보여주는 것

 

 

MIT :  상업적으로 이용할 수 있는 라이센스


부트스트랩 다운받기

 

1. 부트스트랩 무료 사이트에서 파일을 다운 받는다.

 

https://startbootstrap.com/themes/freelancer/

 

Freelancer - One Page Theme

A free one page Bootstrap portfolio theme for freelancers. All Start Bootstrap templates are free to download and open source.

startbootstrap.com

 


Sublime Text 3 설치

2. 부트스트랩 HTML을 편집해줄 에디터를 다운 받아줍니다.

 

http://www.sublimetext.com/3

 

Download - Sublime Text

Sublime Text 3 is the current version of Sublime Text. For bleeding-edge releases, see the dev builds. Sublime Text may be downloaded and evaluated for free, however a license must be purchased for continued use. There is currently no enforced time limit f

www.sublimetext.com

 

https://hongku.tistory.com/285

 

Sublime Text :: 맥북(Mac os)에 서브라임 텍스트 설치하기

Sublime Text 3 설치 많은 개발자분들이 사용하는 개발 도구 중 '서브라임텍스트'가 있습니다. 서브라임텍스트는 코드에 색상을 입혀서 가독성을 높여주고, 개발의 효율을 높여줍니다. 서브라임텍��

hongku.tistory.com

 

index.html
0.03MB

 

수정 된 HTML 파일


 

개인 웹 서버 구축 및 업로드

3. 많은 사람이 볼 수 있도록 웹서버 구축을 해줍니다.

 

https://www.dothome.co.kr/

 

닷홈 - 호스팅은 닷홈

닷홈은 무제한 웹호스팅, 무료호스팅, 도메인, 홈페이지빌더, 무제한메일, SSL보안인증서, 서버호스팅, 코로케이션 서비스를 제공하고 있습니다.

www.dothome.co.kr

 

웹호스팅 탭에서 무료 호스팅을 신청합니다.
신청을 눌러줍니다.
승인하고 신청을 시작합니다.
FTP와 DB 정보를 입력해 준 후 메일 인증을 합니다.

 

완료 된 것을 확인합니다.

 

구축 완료는 30분에서 1시간 이후 호스팅 세팅이 완료 됩니다.(바로 되기도 하는 것 같다)
시간이 지난 후 도메인주소로 들어가보면 세팅이 완료되었음을 알 수 있습니다.

 


https://filezilla-project.org/

 

FileZilla - The free FTP solution

Overview Welcome to the homepage of FileZilla®, the free FTP solution. The FileZilla Client not only supports FTP, but also FTP over TLS (FTPS) and SFTP. It is open source software distributed free of charge under the terms of the GNU General Public Licen

filezilla-project.org

FTP에 접속하기 위해 파일질라를 다운받아줍니다.(알드라이브도 업로드가 가능하다.)

 

FileZilla - The free FTP solution

Overview Welcome to the homepage of FileZilla®, the free FTP solution. The FileZilla Client not only supports FTP, but also FTP over TLS (FTPS) and SFTP. It is open source software distributed free of charge under the terms of the GNU General Public Licen

filezilla-project.org

 

https://filezilla-project.org/download.php?platform=osx

 

Download FileZilla Client for Mac OS X

Download FileZilla Client for Mac OS X The latest stable version of FileZilla Client is 3.48.1 Please select the file appropriate for your platform below. Mac OS X Size: 10376719 bytes SHA-512 hash: 526a4ade31e663f5998351a6714da1d32e39e1c5016d06cb6f9f24cb4

filezilla-project.org

맥에서 파일질라 다운 및 전송하기

 

https://hongku.tistory.com/188

 

맥북에서 파일질라(FileZilla)를 이용하여 파일 전송

파일질라 FileZila 다운받기 https://filezilla-project.org/download.php?platform=osx 다운로드를 눌러서 다운을 받아주세요. 파일질라 설치하기 'Continue'를 눌러서 설치를 진행해주시면 됩니다. 설치 중....

hongku.tistory.com

 

실행 후 FTP 아이디와 비번을 입력 해줍니다.

 

set-finish.html은 기본으로 보여줬던 닷홈호스팅 세팅 완료 페이지와 일치한다.

 

새로운 디렉토리를 만들어줍니다.
다운받아서 수정했던 부트스트랩 폴더 내용을 업로드 해줍니다.

 

업로트 후 http://도메인주소/업로트폴더명 을 입력해주면,

아래와 같이 수정했던 부트스트랩을 볼 수 있습니다.

http://helloqu.dothome.co.kr/bootstrap/

 

고치삼 개발자 라이프

Circus Tent Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam. Close Wi

helloqu.dothome.co.kr


메일 전송 기능 구현하기

4. 

부트스트랩은 기본적으로 PHP 메일 전송 시스템을 지원하고 있다.

*반드시 웹호스팅에서 PHP를 지원하고 메일전송시스템을 허용하고 있는지 확인 후 구현을 시작 할 수 있다.

*닷홈의 무료호스팅에는 메일전송을 허용하고 있지 않다.(보통 유료에서는 지원이 가능하다.)

 

https://www.cafe24.com/

 

카페24

No.1 글로벌 전자상거래 플랫폼 '카페24'

www.cafe24.com

유료 호스팅을 이용할 수 있는 카페 24 사이트 이다.

10G광 호스팅에 들어간다.

 

같은 방식으로 신청 해준 후 , 파일질러로 닷홈 접속과 같이 들어간 후 같이 작업한 파일을 업로드 해준다.

컨트롤+F키로 email 주소를 찾아 준 뒤 수정 해주도록 한다.
보여지는 결과값들
jqBootstrapValidation.js를 열어주어 메일 기능 오류시 나오는 오류를 한글로 수정해준다.

 

if (settings.options.sniffHtml) {
            var message = "";
            // ---------------------------------------------------------
            //                                                   PATTERN
            // ---------------------------------------------------------
            if ($this.attr("pattern") !== undefined) {
              message = "예상치 못한 형식입니다.<!-- data-validation-pattern-message to override -->";
              if ($this.data("validationPatternMessage")) {
                message = $this.data("validationPatternMessage");
              }
              $this.data("validationPatternMessage", message);
              $this.data("validationPatternRegex", $this.attr("pattern"));
            }
            // ---------------------------------------------------------
            //                                                       MAX
            // ---------------------------------------------------------
            if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) {
              var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax"));
              message = "값이 너무 높습니다. 최댓값 :  '" + max + "'<!-- data-validation-max-message to override -->";
              if ($this.data("validationMaxMessage")) {
                message = $this.data("validationMaxMessage");
              }
              $this.data("validationMaxMessage", message);
              $this.data("validationMaxMax", max);
            }
            // ---------------------------------------------------------
            //                                                       MIN
            // ---------------------------------------------------------
            if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) {
              var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin"));
              message = "값이 너무 낮습니다. 최솟값 :'" + min + "'<!-- data-validation-min-message to override -->";
              if ($this.data("validationMinMessage")) {
                message = $this.data("validationMinMessage");
              }
              $this.data("validationMinMessage", message);
              $this.data("validationMinMin", min);
            }
            // ---------------------------------------------------------
            //                                                 MAXLENGTH
            // ---------------------------------------------------------
            if ($this.attr("maxlength") !== undefined) {
              message = "값이 너무 깁니다. 최댓값 : '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->";
              if ($this.data("validationMaxlengthMessage")) {
                message = $this.data("validationMaxlengthMessage");
              }
              $this.data("validationMaxlengthMessage", message);
              $this.data("validationMaxlengthMaxlength", $this.attr("maxlength"));
            }
            // ---------------------------------------------------------
            //                                                 MINLENGTH
            // ---------------------------------------------------------
            if ($this.attr("minlength") !== undefined) {
              message = "값이 너무 짧습니다. 최소값 : '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->";
              if ($this.data("validationMinlengthMessage")) {
                message = $this.data("validationMinlengthMessage");
              }
              $this.data("validationMinlengthMessage", message);
              $this.data("validationMinlengthMinlength", $this.attr("minlength"));
            }
            // ---------------------------------------------------------
            //                                                  REQUIRED
            // ---------------------------------------------------------
            if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) {
              message = settings.builtInValidators.required.message;
              if ($this.data("validationRequiredMessage")) {
                message = $this.data("validationRequiredMessage");
              }
              $this.data("validationRequiredMessage", message);
            }
            // ---------------------------------------------------------
            //                                                    NUMBER
            // ---------------------------------------------------------
            if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") {
              message = settings.builtInValidators.number.message;
              if ($this.data("validationNumberMessage")) {
                message = $this.data("validationNumberMessage");
              }
              $this.data("validationNumberMessage", message);
            }
            // ---------------------------------------------------------
            //                                                     EMAIL
            // ---------------------------------------------------------
            if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") {
              message = "이메일 형식이 잘못 입력 되었습니다. <!-- data-validator-validemail-message to override -->";
              if ($this.data("validationValidemailMessage")) {
                message = $this.data("validationValidemailMessage");
              } else if ($this.data("validationEmailMessage")) {
                message = $this.data("validationEmailMessage");
              }
              $this.data("validationValidemailMessage", message);
            }

 

컨텍트미 파일 수정

$(function () {
    $(
        "#contactForm input,#contactForm textarea,#contactForm button"
    ).jqBootstrapValidation({
        preventSubmit: true,
        submitError: function ($form, event, errors) {
            // additional error messages or events
        },
        submitSuccess: function ($form, event) {
            event.preventDefault(); // prevent default submit behaviour
            // get values from FORM
            var name = $("input#name").val();
            var email = $("input#email").val();
            var phone = $("input#phone").val();
            var message = $("textarea#message").val();
            var firstName = name; // For Success/Failure Message
            // Check for white space in name for Success/Fail message
            if (firstName.indexOf(" ") >= 0) {
                firstName = name.split(" ").slice(0, -1).join(" ");
            }
            $this = $("#sendMessageButton");
            $this.prop("disabled", true); // Disable submit button until AJAX call is complete to prevent duplicate messages
            $.ajax({
                url: "/assets/mail/contact_me.php",
                type: "POST",
                data: {
                    name: name,
                    phone: phone,
                    email: email,
                    message: message,
                },
                cache: false,
                success: function () {
                    // Success message
                    $("#success").html("<div class='alert alert-success'>");
                    $("#success > .alert-success")
                        .html(
                            "<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;"
                        )
                        .append("</button>");
                    $("#success > .alert-success").append(
                        "<strong>메일이 성공적으로 보내졌습니다. </strong>"
                    );
                    $("#success > .alert-success").append("</div>");
                    //clear all fields
                    $("#contactForm").trigger("reset");
                },
                error: function () {
                    // Fail message
                    $("#success").html("<div class='alert alert-danger'>");
                    $("#success > .alert-danger")
                        .html(
                            "<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;"
                        )
                        .append("</button>");
                    $("#success > .alert-danger").append(
                        $("<strong>").text(
                            "죄송합니다. " +
                                firstName +
                                "님, 현재 메일 서버가 응답하지 않습니다. 나중에 다시 시도해주세요. "
                        )
                    );
                    $("#success > .alert-danger").append("</div>");
                    //clear all fields
                    $("#contactForm").trigger("reset");
                },
                complete: function () {
                    setTimeout(function () {
                        $this.prop("disabled", false); // Re-enable submit button when AJAX call is complete
                    }, 1000);
                },
            });
        },
        filter: function () {
            return $(this).is(":visible");
        },
    });

    $('a[data-toggle="tab"]').click(function (e) {
        e.preventDefault();
        $(this).tab("show");
    });
});

/*When clicking on Full hide fail/success boxes */
$("#name").focus(function () {
    $("#success").html("");
});

 

contact_me.php 파일을 열어 준 후, 수정한다.

<?php
// Check for empty fields
if(empty($_POST['name']) || empty($_POST['email']) || empty($_POST['phone']) || empty($_POST['message']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
  http_response_code(500);
  exit();
}

$name = strip_tags(htmlspecialchars($_POST['name']));
$email = strip_tags(htmlspecialchars($_POST['email']));
$phone = strip_tags(htmlspecialchars($_POST['phone']));
$message = strip_tags(htmlspecialchars($_POST['message']));

// Create the email and send the message
$to = "helloqu@naver.com"; // Add your email address in between the "" replacing yourname@yourdomain.com - This is where the form will send a message to.
$subject = "메일이 도착하였습니다.:  $name";
$body = "당신의 개인 홈페이지에서 메일이 도착하였습니다.\n\n"."이곳의 자세한 내용을 확인 하세요.:\n\nName: $name\n\nEmail: $email\n\nPhone: $phone\n\nMessage:\n$message";
$header = "From: http://helloqu.dothome.co.kr/\n"; // This is the email address the generated message will be from. We recommend using something like noreply@yourdomain.com.
$header .= "Reply-To: $email";	

if(!mail($to, $subject, $body, $header))
  http_response_code(500);
?>

 

파일질러를 이용하여 수정한 파일 들을 업로드 해준다.

 

https://engkimbs.tistory.com/746

 

[Spring] 스프링 AOP (Spring AOP) 총정리 : 개념, 프록시 기반 AOP, @AOP

| 스프링 AOP ( Aspect Oriented Programming ) AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불린다. 관점 지향은 쉽게 말해 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으..

engkimbs.tistory.com

 

OOP(자바의 기본방식 :  각체지향 ) 에서 Aspect 만 바뀌였다.

특정 한 타이밍에 어느 위치에 어떤 메소드를 실행 시킬 것인지에 대한 프로그래밍 기법

 

 Aspect: 기존 객체 지향 프로그램에서 모듈화 기법으로

추가된 중복 코드(공통 처리 부분)을 별도의 독립된 클래스(Aspect)로 만들어 놓은 것

 

AOP : 공통(공용), 공유 할 내용, 일종의 기법

 

핵심모듈 : 반드시 구현할 기능

예) 로그인 여부 확인(회원 수정, 삭제 등에 필요함)

 

위와 같은 기능을 할 코드들을 따로 클래스로 만들어준다.

이것을 공통 관심사 모듈(Aspect)이라고 한다.

 

공통 관심사 모듈

예) 로그인 처리부분, 보안, 공통으로 사용할 수 없는 코딩

-> 스프링에서는 Aspect는 Advice라고 한다. Angular에서는 서비스라고 한다.

 

AOP는 언제 불러다 사용할 것이고, 언제 실행 할 것인지가 중요하다.

이렇게 실행 위치를 지정해주는 것은 joinPoint, PointCut라고 한다.

 

JoinPoint :  실행 위치를 지정(실행 위치만 지정한다.)

예) before, after

 

PointCut : 어떤 메소드 앞, 뒤에서 실행을 지정

어느 메소드를 사용할 것인지도 같이 설정해준다.

ex) before에 startMethod 실행지정.

 

이러한 지정 법은 Weaving이라고 한다.

핵심클래스의 특정위치에 넣어주는 것

 

이러한 모든 것을 통틀어 Aspect라고 한다.

 

또한 Aspect와 Advice를 합쳐진 것을 보고 Advisior라고도 한다.


AOP를 실행 시키는 방법

 

1. 프록시 기반의 AOP지원(AOP객체를 생성해주는 클래스)

default(메소드 중심)->빈즈 클래스로 구성.

2. <aop:config>태그를 사용

3. AspectJ이용 (@Aspect Annotation을 이용하는 방법)

 

프로젝트 생성하기

맨 밑에 있는 mvc를 선택해도 되지만(Spring MVC Project),

자동으로 만들어주는 프로젝트이기 때문에 수정하기가 쉽지않다.

따라서, 수동으로 프로젝트를 설계하기 위해 위와 같은 프로젝트로 설정한다.

 

프로젝트 생성시 체크해볼 것

 


POM.xml 수정하기

 

AOP -> springFrame(스프링 프레임워크이 필요하고, 스프링-익스프레션, 스프링-빈즈 라는 라이브러리가 필요하다.)

AOP연습에서는 위와 같은 lib가 필요하다.

 

변경 전

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.dod</groupId>
	<artifactId>dko</artifactId>
	<name>fvdsafds</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>1.6</java-version>
		<org.springframework-version>3.1.1.RELEASE</org.springframework-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				 </exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
				
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>	
		
		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
				
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	
		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>        
	</dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 

변경 후

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.hjs</groupId>
   <artifactId>springAop</artifactId>
   <name>SpringAop</name>
   <packaging>war</packaging>
   <version>1.0.0-BUILD-SNAPSHOT</version>
   <properties>
      <!-- Generic properties -->
      <java-version>1.6</java-version>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      
      <!-- Spring -->
      <org.springframework-version>4.2.5.RELEASE</org.springframework-version>
      
      
      
      <!-- Hibernate / JPA -->
      <hibernate.version>4.2.1.Final</hibernate.version>
      
      <!-- Logging -->
      <logback.version>1.0.13</logback.version>
      <slf4j.version>1.7.5</slf4j.version>
      
      <!-- Test -->
      <junit.version>4.11</junit.version>
      
      <org.aspectj-version>1.6.10</org.aspectj-version>
      <org.slf4j-version>1.6.6</org.slf4j-version>
   </properties>
   <dependencies>
      
      <!-- Spring -->
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>${org.springframework-version}</version>
         <exclusions>
            <!-- Exclude Commons Logging in favor of SLF4j -->
            <exclusion>
               <groupId>commons-logging</groupId>
               <artifactId>commons-logging</artifactId>
             </exclusion>
         </exclusions>
      </dependency>
      
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-webmvc</artifactId>
         <version>${org.springframework-version}</version>
      </dependency>
      
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-expression</artifactId>
         <version>${org.springframework-version}</version>
      </dependency>
      
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-beans</artifactId>
         <version>${org.springframework-version}</version>
      </dependency>
   </dependencies>
</project>

샘플 스프링 메이븐으로 만들어보기

 

샘플 스프링 메이븐으로 만들게 되면 pom.xml의 내용이 필요한 내용만 들어가게 된다.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.samples</groupId>
  <artifactId>AOPSpring</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <properties>

		<!-- Generic properties -->
		<java.version>1.6</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

		<!-- Spring -->
		<spring-framework.version>3.2.3.RELEASE</spring-framework.version>

		<!-- Hibernate / JPA -->
		<hibernate.version>4.2.1.Final</hibernate.version>

		<!-- Logging -->
		<logback.version>1.0.13</logback.version>
		<slf4j.version>1.7.5</slf4j.version>

		<!-- Test -->
		<junit.version>4.11</junit.version>

	</properties>
	
	<dependencies>
		<!-- Spring and Transactions -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<!-- Logging with SLF4J & LogBack -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${logback.version}</version>
			<scope>runtime</scope>
		</dependency>

		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>

		
		<!-- Test Artifacts -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring-framework.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

	</dependencies>	
</project>

https://blog.naver.com/hojysoo/221971341519

 

20200520 - 스프링 프로젝트 관점지향 프로그래밍 (AOP - Aspect Oriented Programming)

OOP에서 Aspect만 바뀌었다.​특정 한 타이밍에 어느 위치에 어떤 메서드를 실행시킬 것인지에 대한 프...

blog.naver.com

버전 정보를 수정해준다.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.samples</groupId>
  <artifactId>AOPSpring</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <properties>

		<!-- Generic properties -->
		<java.version>1.6</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

		<!-- Spring -->
		<spring-framework.version>4.2.5.RELEASE</spring-framework.version>

		<!-- Hibernate / JPA -->
		<hibernate.version>4.2.1.Final</hibernate.version>

		<!-- Logging -->
		<logback.version>1.0.13</logback.version>
		<slf4j.version>1.7.5</slf4j.version>

		<!-- Test -->
		<junit.version>4.11</junit.version>

	</properties>
	
	<dependencies>
		<!-- Spring and Transactions -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<!-- Logging with SLF4J & LogBack -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${logback.version}</version>
			<scope>runtime</scope>
		</dependency>

		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>

		
		<!-- Test Artifacts -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring-framework.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

	
	<!-- 1. 핵심 Class 빈즈 등록 -->
<bean id="testServiceImpl" class="sp.aop.TestServiceImpl" />

<!-- 2. Advice Class 빈즈 등록 -->
<bean id="beforeLog" class="sp.aop.BeforeLogAdvice" />

<!-- 3.PointCut 생성 -->
<bean id="" class="org.springframework.aop.support.JdkRegexpMethodPointcut" />

	</dependencies>	
</project>

 

package sp.aop;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice; // 이후라고하면 MethodAfterAdvice 구현받으면 된다.

//추가
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

//Advice : 모든 Class에 공통으로 사용할 기능( 소스코드 -> method 중심 )
//interface 대신(OOP 방식) 에 Advice Class 를 작성해서 구현(AOP 방식) -> Aspect

//실행 위치를 특정 Method 의 앞에서 실행 -> MethodBeforeAdvice 를 구현
public class BeforeLogAdvice implements MethodBeforeAdvice { //공통관심 모듈 클래스를 만든다.
	private Log log = LogFactory.getLog(getClass()); //Log 객체를 얻어오는 문장
	
	//1) Spring의 AOP(method 중심) -> 핵심 CLass의 Method
	//2) 생성된 객체를 배열로 받아온다.
	//3) target Class(핵심 Class의 객체를 얻어온다.)
	
	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		//TODO auto-generated method stub
		log.info(method.toString()+" Method : "+target+"에서 호출 전!");
	}//before() END

}//BeforeLogAdvice CLASS END

 

package sp.aop;
//모든 핵심 class 에서 공통으로 사용할 목적으로의 Method 작성, 인터페이스는 메소드 옆에 {} 지정하면 안된다.
public interface TestService {
    // 해당 메소드들은 public abstract void 와 같이 추상메소드로 작성된다.
	public void save(String msg);// 입력
	public void write(); //출력
}//TestService INTERFACE END

 

 

app.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"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">


<!-- 1. 핵심 Class 빈즈 등록 -->
<bean id="testServiceImpl" class="sp.aop.TestServiceImpl" />

<!-- 2. Advice Class 빈즈 등록 -->
<bean id="beforeLog" class="sp.aop.BeforeLogAdvice" />


<!-- 3.PointCut 생성 -> 어느 위치에서 AOP Method 를 지정해서 실행
	value="접근 지정 반환명 package 명... Class 명 하위  package 명(..) 특정 Method명 0개 이상"
	        (*) 매개변수 한 개 표시, (*,*) 매개변수 2개 표시 -->
	        
<bean id="writePointcut"
 class="org.springframework.aop.support.JdkRegexpMethodPointcut">
	<property name="pattern" value=".*write.*" />
</bean>


<!-- 4. Advice + PointCut(Advisor) 설정 -->
<bean id="testAdvisor" 
class="org.springframework.aop.support.DefaultPointcutAdvisor">
	<property name="advice" ref="beforeLog" /> 
	<property name="pointcut" ref="writePointcut" />
</bean>


</beans>

package sp.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; // xml문서를 찾을 수 있게 하는 lib

public class ResultMain {

	public static void main(String[] args) {
		String path="sp/aop/app.xml";
		ApplicationContext context = new ClassPathXmlApplicationContext(path);
		
		//TestService service= (TestService)context.getBean("testServiceImpl");
		//원래는 위의 것이 일반적이지만, AOP 객체를 얻어오기 위해서는, 밑에처럼 AOP객체를 얻는다.
		
		//AOP객체를 생성 -> Advisor 작동 -> Advice + pointcut 실행
		TestService service = (TestService)context.getBean("testService");
		service.save("AOP 적용 연습");
		//before advice(before() 작동 실행) -> 실행상태에서 처리
		service.write();
		
	}//main()END

}//CLASS END

 

 

 

package sp.aop;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class AfterLogAdvice implements AfterReturningAdvice {

	public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
		// TODO Auto-generated method stub
		 System.out.println(method.toString()+"method:"+target+"에서 호출 후!");
	}

  /* @Override
   public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
      
       * 1. 추가된 객체
       * 2.핵심클래스의 method명
       * 3.생성된 객체들
       * 4.targetClass의 객체
       
      System.out.println(method.toString()+"method:"+target+"에서 호출 후!");
   }*/

}

app.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"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">


<!-- 1. 핵심 Class 빈즈 등록 -->
<bean id="testServiceImpl" class="sp.aop.TestServiceImpl" />

<!-- 2. Advice Class 빈즈 등록 -->
<bean id="beforeLog" class="sp.aop.BeforeLogAdvice" />
<bean id="AfterLog" class="sp.aop.AfterLogAdvice" />


<!-- 3.PointCut 생성 -> 어느 위치에서 AOP Method 를 지정해서 실행
	value="접근 지정 반환명 package 명... Class 명 하위  package 명(..) 특정 Method명 0개 이상"
	        (*) 매개변수 한 개 표시, (*,*) 매개변수 2개 표시 -->
	        
<bean id="writePointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
	<property name="pattern" value=".*write.*" />
</bean>

<bean id="savePointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
	<property name="pattern" value=".*save.*" />
</bean>


<!-- 4. Advice + PointCut(Advisor) 설정 -->
<bean id="testAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
	<property name="advice" ref="beforeLog" />
	<property name="pointcut" ref="writePointcut" />
</bean>

<!-- 4-1. Advice + PointCut(Advisor) 설정 -->
<bean id="testAfterAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
	<property name="advice" ref="AfterLog" />
	<property name="pointcut" ref="savePointcut" />
</bean>

<!-- 5. AOP를 적용(ProxyFactoryBean 객체를 생성) target(핵심 Class) -->
<bean id="testService" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="target" ref="testServiceImpl" />
	<property name="interceptorNames">
		<list>
			<value>testAdvisor</value>
			<value>testAfterAdvisor</value>
		</list>
	</property>
</bean>
<!-- ///////END AOP 환경설정 부분 -->

</beans>

BoardController

 

package com.ohj.controller;

import java.util.List;

import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; // 스프링은 모델이다.(모델 앤 뷰 객체)
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.ohj.domain.BoardVO;
import com.ohj.service.BoardService;

import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;

@Controller
@Log4j
@RequestMapping("/board/*")
@AllArgsConstructor
public class BoardController {
   private BoardService service; 
   
   @GetMapping("/list")
   public void list(Model model) {
      log.info("list");
      model.addAttribute("list", service.getList()); // 반환타입 List<BoardVO> --> list.jsp
   }// list() END
   // 이 리스트 메소드가 호출되려면 /board/list 로 되어야 한다.
    // ModelAndView 에 값 실어주려면 setAttribute 인데 여기선 addAttribute 라는 메소드로 리스트란 명칭을 실어주는 것이다.
   
   @GetMapping("/register")
   public void register() {
      
   }//register() END 
   
   @PostMapping("/register")
   public String register(BoardVO board, RedirectAttributes rttr) {
      
      log.info("register:" + board);
      service.register(board);
      rttr.addFlashAttribute("result", board.getBno()); // 딱 1회만 전송할 수 있도록 만들어주는 메서드(addFlashAttribute)
      
      return "redirect:/board/list";
   }//register() END
   
   @GetMapping({"/get","/modify"}) //매개변수에서 url패턴명이 바로 model객체 내부로 들어가서 return 되는 것(모델 객체가 리턴)
   public void get(@RequestParam("bno") Long bno, Model model) { // @RequestParam("bno") 이 부분은 board/get?bno=n 과 같이 데이터 전달을 알려준다.(자동주입)
      //request.getParameter("bno")를 대신해주는 것이 @RequestParam("bno")
      
      log.info("/get or modify");
      model.addAttribute("board",service.get(bno));  //BoardVO 반환타입
   }//get() END
   
   @PostMapping("/modify")
   public String modify(BoardVO board, RedirectAttributes rttr) {
      log.info("modify : " + board);
      
      if (service.modify(board)) {
         rttr.addFlashAttribute("result", "success");
      }
      return "redirect:/board/list";
   }// modify() END
   
   //★삭제는 반드시 POST 방식으로 처리
   @PostMapping("/remove")
   public String remove(@RequestParam("bno") Long bno, RedirectAttributes rttr) {
      log.info("remove...." + bno);
      if(service.remove(bno)) {
         rttr.addFlashAttribute("result","success");
         
      }
      return "redirect:/board/list";
   }//remove() END
   
}//BoardController CLASS END

 

get.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@include file="../includes/header.jsp" %>

<div class="row">
	<div class="col-lg-12">
		<h1 class="page-header">Board Read</h1>
	</div>
	<!-- /.col-lg-12 -->
</div>

<div class="row">
	<div class="col-lg-12">
		<div class="panel panel-default">
			<div class="panel-heading">Board Read Page</div>
			<!-- /.panel-heading -->
			<div class="panel-body">
				
				
					<div class="form-group">
						<label>Bno</label> <input class="form-control" name="bno" value='<c:out value="${board.bno}" />' readonly="readonly">
					</div>
					
					<div class="form-group">
						<label>Title</label> <input class="form-control" name="title" value='<c:out value="${board.title}" />' readonly="readonly">
					</div>
					
					<div class="form-group">
						<label>Text Area</label>
						<textarea class="form-control" rows="3" name="content" readonly="readonly"><c:out value="${board.content }" /></textarea>
					</div>
					
					<div class="form-group">
           				<label>Writer</label><input class = "form-control" name = "writer" value='<c:out value="${board.writer}" />' readonly="readonly"> 
           			</div>
           			
					<button data-oper="modify" class="btn btn-default" onclick="location.href='/board/modify?bno=<c:out value="${board.bno }"/>'">Modify</button>		
					<button data-oper="list" class="btn btn-info" onclick="location.href='/board/list'">List</button>

				
			</div>
			<!-- end panel body -->		
		</div>
		<!-- end panel body -->
	</div>
	<!-- end panel -->
</div>
<!-- /.row -->
<%@include file="../includes/footer.jsp"%>

 

 

modify.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@include file="../includes/header.jsp" %>

<div class="row">
   <div class="col-lg-12">
      <h1 class="page-header">Board Register</h1>
   </div>
   <!-- /.col-lg-12 -->
</div>

<div class="row">
   <div class="col-lg-12">
      <div class="panel panel-default">
         <div class="panel-heading">Board Register</div>
         <!-- /.panel-heading -->
         <div class="panel-body">
            <form role="form" action="/board/modify" method="post">
            
               <div class="form-group">
                  <label>Bno</label> <input class="form-control" name="bno" value='<c:out value="${board.bno}" />' readonly="readonly">
               </div>
               
               <div class="form-group">
                  <label>Title</label> <input class="form-control" name="title" value='<c:out value="${board.title}" />' >
               </div>
               
               <div class="form-group">
                  <label>Text Area</label>
                  <textarea class="form-control" rows="3" name="content" ><c:out value="${board.content }" /></textarea>
               </div>
               
               <div class="form-group">
                       <label>Writer</label><input class = "form-control" name = "writer" value='<c:out value="${board.writer}" />'> 
                    </div>
                    
                    <div class="form-group">
                       <label>RegDate</label>
                       <input class="form-control" name = "regDate" 
                          value='<fmt:formatDate pattern ="yyyy/MM/dd" 
                          value ="${board.regdate}" />' readonly="readonly"> 
                    </div>
                    
                    <div class="form-group">
                       <label>Update Date</label>
                       <input class="form-control" name = "updateDate" 
                          value='<fmt:formatDate pattern ="yyyy/MM/dd" 
                          value ="${board.updateDate}" />' readonly="readonly"> 
                    </div>
                    
                    
               <button type="submit" data-oper="modify" class="btn btn-default">Modify</button>
               <button type="submit" data-oper="remove" class="btn btn-danger">Remove</button>
               <button type="submit" data-oper="list" class="btn btn-info">List</button>
               
            </form>
         </div>
         <!-- end panel body -->      
      </div>
      <!-- end panel body -->
   </div>
   <!-- end panel -->
</div>
<!-- /.row -->
<%@include file="../includes/footer.jsp"%>

<!-- remove JSP code -->
<script type="text/javascript">
$(document).ready(function(){
   var formObj=$("form");
   $('button').on("click",function(e){
      e.preventDefault();
      var operation = $(this).data("oper");
      console.log(operation);
      if(operation==='remove'){
         formObj.attr("action","/board/remove");
         
      }else if(operation==='list'){
         self.location="/board/list";
         return;
      }
      formObj.submit();
         
   });
});
</script>

+ Recent posts