728x90
300x250
[PC활용] Oracle(오라클) - Cmd 명령어로 sqlplus가 동작하지 않을 때 해결 방법


Oracle을 PC에서 설치하여 sqlplus로 작업을 하고자 했을 때 초기 순정 설치했을 때는 sqlplus 명령어가 잘 되지만, 
살다보면 셋팅값을 변경해서 안 켜지는 경우가 있을 수도 있다.


이럴 때 해결하는 방법에 대해서 소개하려고 한다.


[작성환경]

- MS 윈도우 10

- Oracle Databases 설치된 상태


[적용대상]

- Oracle Databases



1. 제어판 - 시스템 속성


몇 가지 간단한 설정으로 다시 사용할 수 있다.


그림 1. 시스템 속성


컴퓨터 -> 속성을 클릭한다. (마우스 오른쪽 버튼)

고급 시스템 설정을 클릭한다.

고급 탭을 클릭한다.

환경 변수(N)을 클릭한다.





그림 2. 시스템 속성


시스템 변수의 "PATH"를 편집한다.

예) C:\oraclexe\app\oracle\product\11.2.0\server\bin

오라클 설치한 경로를 찾아가보면 아래의 그림처럼 sqlplus의 위치를 찾을 수 있다.



[추가 방법]

-> 1. (컴퓨터 -> 속성 -> 환경변수 -> 시스템 변수 -> 새로만들기 

      "ORACLE_HOME" -> C:\oraclexe\app\oracle\product\11.2.0\server

   2. 시스템 변수 (Path 편집) -> %ORACLE_HOME%\bin





그림 3. 오라클 서버 프로그램 폴더

해당 경로에 있는 sqlplus의 모습이다.

반응형
728x90
300x250
[Oracle Databases] 번외글 - 게시판 페이징 관련 로직 쿼리


게시글 중 페이징네이션과 관련한 글을 실습하다보면, 쿼리 문제에 당면하는 일들이 벌어질 수 있다.

그래서 따로 몇 가지 중요 포인트를 정리해보았다.


1. [JSP] 17. JSP/Servlet MVC2 - 페이징네이션과 검색 그리고 오라클 프로젝트 (1), 2020-09-30
- https://yyman.tistory.com/1428


2. [JSP] 18. JSP/Servlet MVC2 - 페이징네이션과 검색 그리고 오라클 프로젝트 (2), 2020-09-30
https://yyman.tistory.com/1429


- 사용 프로그램: SQL Developer (Oracle)

- DB: Oracle Databases [11, 19g]


이 글이 어렵게 이해되는 경우를 위해서 아주 친절하게 SQL Developer에서 어떤 작업을 했는지 소개하도록 하겠다.



그림 1. Oracle SQL Developer에서의 작업 모습의 예

그림 1은 쿼리 넣고 태스트를 하는 모습이다. 예를 들면, Java, C#, C++, PHP, .NET 등의 코드를 삽입하기 전에 미리 확인을 해볼 수 있다.

이런 작업을 수 차례 반복해서 해보고 프로그래밍 코드에 적용하면 된다.


더 좋은 전문적인 프로그램이 있으면, 또는 편리한 프로그램이 있으면 다른 프로그램을 사용해도 무방하다.



1. 게시판 페이징 로직


게시글 "[JSP] 18. JSP/Servlet MVC2 - 페이징네이션과 검색 그리고 오라클 프로젝트 (2), 2020-09-30"에 적혀져 있는 SQL 쿼리문이다.

물론 이 쿼리는 오라클 형태로 작성된 쿼리이다.


-- Oracle 11 - 자동번호 생성 테이블 정의
-- Table 생성 (BOARD)
-- NEW.ID (Table의 id를 가리킴)
CREATE TABLE board
(
    id NUMBER PRIMARY KEY,
    name VARCHAR2(30),
    subject VARCHAR2(30),
    memo NCLOB,
    count NUMBER,
    regidate DATE
);


-- Sequence 정의
CREATE SEQUENCE board_sequence
START WITH 1
INCREMENT BY 1;


-- Trigger 생성
-- BEFORE INSERT on '테이블명'
CREATE OR REPLACE TRIGGER board_trigger
BEFORE INSERT
    ON board
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT board_sequence.nextval INTO :NEW.ID FROM dual;
END;


/* 데이터 추가 */
INSERT INTO board (name, subject, memo, count, regidate) VALUES ('홍길동', '안녕하세요.', '메모메모', '0', '2020-09-29 11:11:00');

/* 데이터 등록 후 커밋할 것(대량 정보 처리 후) */
COMMIT;

-- 싱글 쿼리 (페이징)
SELECT * FROM (
SELECT /*+ INDEX_DESC(Z OP_SAMPLE_PK) */ ROWNUM AS RNUM, Z.* FROM (
SELECT * from board order by id desc
) Z WHERE ROWNUM <= 10
) WHERE RNUM >= 1

-- 특정 싱글 쿼리 SQL
SELECT * FROM (
SELECT /*+ INDEX_DESC(Z OP_SAMPLE_PK) */ ROWNUM AS RNUM, Z.* FROM (
SELECT * from board where subject like '%야해해%' order by id desc
) Z WHERE ROWNUM <= 10
) WHERE RNUM >= 1


[파일명: board-tbl-oracle_개선후.sql]


[첨부(Attachments)]

board-tbl-oracle_개선후.zip


이 쿼리처럼 세상에 있는 문제가 단일로 처리되면 간단하게 구성해도 된다.

하지만, 그렇지 않다는 점이다.




2. 다중 테이블 문제


두 개의 테이블을 두었다.


하나는 메뉴와 가격에 대한 테이블이다.

하나는 가게 정보에 대한 테이블이다.


CREATE TABLE foodmenu_tbl
(
    id NUMBER PRIMARY KEY,
    name VARCHAR2(30),
    price NUMBER,
    store_id NUMBER,
    cnt NUMBER,
    regidate DATE
);

-- Table 생성 (FOODSTORE_TBL)
CREATE TABLE foodstore_tbl
(
    id NUMBER PRIMARY KEY,
    name VARCHAR2(30),
    address VARCHAR2(30),
    regidate DATE
);


두 개 테이블을 하나로 합치면, foomenu_tbl의 stord_id와 foodstore_tbl의 id가 참조 관계를 형성하는 것을 알 수 있다.

모델링 프로그램으로 살펴볼 때는 외래키 지정해도 무방하다.


아무튼, 두 가지 이상 테이블을 조인하여 사용했을 때 쿼리에 대한 것이다.

100만 건 이상 넘어갔을 때는 느려지긴 하지만, 성능이 우수한 쿼리이다. 
(다른 방법을 찾아봐야 할듯. 이 주제에서는 생략함)


-- 2020-10-07 SQL Paging Upgrade

-- 조회 관련 태스트
select f1.id, f1.name, f1.price, f2.name as storename from foodmenu_tbl f1, foodstore_tbl f2 where f1.store_id = f2.id
select count(*) from foodmenu_tbl f1, foodstore_tbl f2 where f1.store_id = f2.id


-- Oracle 11 - 자동번호 생성 테이블 정의

-- Table 생성 (FOODMENU_TBL)
-- NEW.ID (Table의 id를 가리킴)
CREATE TABLE foodmenu_tbl
(
    id NUMBER PRIMARY KEY,
    name VARCHAR2(30),
    price NUMBER,
    store_id NUMBER,
    cnt NUMBER,
    regidate DATE
);

-- Sequence 정의
CREATE SEQUENCE foodmenu_sequence
START WITH 1
INCREMENT BY 1;


-- Trigger 생성

-- BEFORE INSERT on '테이블명'
CREATE OR REPLACE TRIGGER foodmenu_trigger
BEFORE INSERT
    ON foodmenu_tbl
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT foodmenu_sequence.nextval INTO :NEW.ID FROM dual;
END;



----------------------------------------------------------------------


-- Table 생성 (FOODSTORE_TBL)
CREATE TABLE foodstore_tbl
(
    id NUMBER PRIMARY KEY,
    name VARCHAR2(30),
    address VARCHAR2(30),
    regidate DATE
);


-- Sequence 정의
CREATE SEQUENCE foodstore_sequence
START WITH 1
INCREMENT BY 1;

-- Trigger 생성
-- BEFORE INSERT on '테이블명'
CREATE OR REPLACE TRIGGER foodstore_trigger
BEFORE INSERT
    ON foodstore_tbl
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT foodstore_sequence.nextval INTO :NEW.ID FROM dual;
END;


-- Sequence 정의
CREATE SEQUENCE foodstore_sequence
START WITH 1
INCREMENT BY 1;

-- Sequence 삭제 //
drop sequence foodname_sequence;

-- Trigger 생성
-- BEFORE INSERT on '테이블명'
-- NEW.ID (Table의 id를 가리킴)
CREATE OR REPLACE TRIGGER foodstore_trigger
BEFORE INSERT
    ON foodstore_tbl
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT foodstore_sequence.nextval INTO :NEW.ID FROM dual;
END;


-- 뷰 생성하기
create or replace view foodmenu_view as
select f1.id, f1.name, f1.price, f2.name as storename from foodmenu_tbl f1, foodstore_tbl f2 where f1.store_id = f2.id order by f1.id desc;


-- 페이징 SQL(뷰 방식)

SELECT * FROM (
SELECT /*+ INDEX_DESC(Z OP_SAMPLE_PK) */ ROWNUM AS RNUM, Z.* FROM (
SELECT * FROM FOODMENU_VIEW
) Z WHERE ROWNUM <= 20
) WHERE RNUM >= 11;



-- 페이징 SQL(뷰 원본으로 작성)
SELECT * FROM (
SELECT /*+ INDEX_DESC(Z OP_SAMPLE_PK) */ ROWNUM AS RNUM, Z.* FROM (
SELECT f1.id, f1.name, f1.price, f2.name as storename from foodmenu_tbl f1, foodstore_tbl f2 where f1.store_id = f2.id order by f1.id desc
) Z WHERE ROWNUM <= 10
) WHERE RNUM >= 1;



-- 특정 쿼리 페이징 SQL(뷰 원본으로 작성)
SELECT * FROM (
SELECT /*+ INDEX_DESC(Z OP_SAMPLE_PK) */ ROWNUM AS RNUM, Z.* FROM (
SELECT f1.id, f1.name, f1.price, f2.name as storename from foodmenu_tbl f1, foodstore_tbl f2 where f1.store_id = f2.id and f1.name like '%무봉리%' order by f1.id desc
) Z WHERE ROWNUM <= 10
) WHERE RNUM >= 1



-- 싱글 쿼리 (페이징)
SELECT * FROM (
SELECT /*+ INDEX_DESC(Z OP_SAMPLE_PK) */ ROWNUM AS RNUM, Z.* FROM (
SELECT * from foodmenu_tbl order by id desc
) Z WHERE ROWNUM <= 10
) WHERE RNUM >= 1



-- 특정 싱글 쿼리 SQL
SELECT * FROM (
SELECT /*+ INDEX_DESC(Z OP_SAMPLE_PK) */ ROWNUM AS RNUM, Z.* FROM (
SELECT * from foodmenu_tbl where name like '%야해해%' order by id desc
) Z WHERE ROWNUM <= 10
) WHERE RNUM >= 1



-- Sample Insert 문
-- 태스트 코드(foodmenu_tbl)
insert into foodmenu_tbl(name, price, store_id, cnt, regidate) values('사슴1', 1500, 1, 0, '2020-01-01');
insert into foodmenu_tbl(name, price, store_id, cnt, regidate) values('사슴2', 1400, 1, 0, '2020-01-01');
insert into foodmenu_tbl(name, price, store_id, cnt, regidate) values('사슴3', 1300, 1, 0, '2020-01-01');
insert into foodmenu_tbl(name, price, store_id, cnt, regidate) values('사슴4', 1100, 1, 0, '2020-01-01');
insert into foodmenu_tbl(name, price, store_id, cnt, regidate) values('사슴5', 1200, 1, 0, '2020-01-01');
insert into foodmenu_tbl(name, price, store_id, cnt, regidate) values('사슴6', 1300, 1, 0, '2020-01-01');
insert into foodmenu_tbl(name, price, store_id, cnt, regidate) values('사슴7', 1500, 1, 0, '2020-01-01');



-- 상점(foodstore_tbl)
-- 태스트 코드
insert into foodstore_tbl(name, address, regidate) values('치즈집1', '천사1', '2020-01-03');
insert into foodstore_tbl(name, address, regidate) values('치즈집2', '천사2', '2020-01-03');
insert into foodstore_tbl(name, address, regidate) values('치즈집3', '천사3', '2020-01-03');
insert into foodstore_tbl(name, address, regidate) values('치즈집4', '천사4', '2020-01-03');
insert into foodstore_tbl(name, address, regidate) values('치즈집5', '천사5', '2020-01-03');
insert into foodstore_tbl(name, address, regidate) values('치즈집6', '천사6', '2020-01-03');


-- 삭제 관련 Delete Query

delete from foodmenu_tbl;
select * from foodmenu_tbl where name = '야해해';


[파일명: food_tbl_sample_boardQueries.sql]


[첨부(Attachments)]

food_tbl_sample_boardQueries.zip




* 맺음글(conclusion)


게시판 페이징 관련해서 학습 또는 자습할 때, 고민을 하면서 쿼리를 날려보고 하면 좋을 듯 싶다.

반응형
728x90
300x250
[PC 활용] 오라클 XE 11(Oracle Express Edition 11g) - 설치 및 로그인


윈도우 10에서 오라클 XE를 설치하는 방법에 대해서 소개하려고 한다.

Standard Edition, Enterprise Edition에 비해서 설치 프로그램 용량도 적고, 간편하다.

다만, 아파치 톰캣을 사용하는 개발자라면, 포트 충돌이 날 수 있다.



[작성 환경]

1. MS윈도우 10

2. 포멧 후 깨끗한 상태



1. 설치하기


설치하는 방법은 다음과 같다.




그림 1. 오라클 설치하기


setup.exe를 실행한다.



그림 2. 오라클 설치하기


잠시 기다린다.



그림 3. 오라클 설치하기


Next를 누른다.



그림 4. 오라클 설치하기


"I accpet the terms......"을 체크한다.

Next를 누른다.




그림 5. 오라클 설치하기


Next를 누른다.



그림 6. 오라클 설치하기


이 비밀번호는 Oracle XE에서는 매우 중요한 암호가 된다. 기억해두자.

암호를 입력한 후에는 Next를 누른다.




그림 7. 오라클 설치하기


설치 환경설정을 살펴본다.

Oracle HTTP에서도 8080포트를 사용하는 것을 살펴볼 수 있다.


Install을 누른다.




그림 8. 오라클 설치하기


기다린다.



그림 9. 오라클 설치하기


Finish를 누르면 설치가 완료된 것이다.




2. 명령 프롬프트(cmd) 작업 - Sqlplus


설치를 완료하였다면, 바로 사용가능한 것이 아니라 몇 가지 계정 설정을 해줘야 한다.



그림 10. sqlplus 작업을 위한 명령 프롬프트 실행하기


시작 메뉴에서 cmd를 입력한다.



그림 11. sqlplus 작업을 위한 명령 프롬프트 실행하기


system이라고 입력한다.

아까 입력했던 패스워드를 입력한 후 엔터를 누른다.



그림 12. sqlplus 작업을 위한 명령 프롬프트 실행하기


경로: C:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin\
찾아야 하는 파일명: scott.sql


해당 파일을 찾아야 한다.



그림 13. sqlplus 작업을 위한 명령 프롬프트 실행하기


SQL> @C:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin\scott.sql
SQL> alter user scott identified by tiger;

SQL> commit;


3줄 명령어를 입력한다. (SQL>은 입력하는 게 아님)


scott 계정을 활성화한 것이다.



4. scott 계정 접속하기


앞서 작업한 scott 계정을 로그인해볼 것이다.



그림 14. sqlplus 작업을 위한 명령 프롬프트 실행하기


SQL> conn scott/tiger
SQL> show user;

SQL> select * from tab;


3줄 명령어는 다음과 같다.

1줄은 scott/tiger(비밀번호)로 연결하라는 것이다.

2줄은 접속중인 계정이 무엇인지 확인하는 명령어이다.

3줄은 tab 테이블을 조회하는 명령이다. (SELECT문)



그림 15. sqlplus 작업을 위한 명령 프롬프트 실행하기


SQL> exit


exit는 연결을 끊는다는 명령어이다.


c:\Users\{사용자계정명}>sqlplus
Enter user-name: system
Enter password: (비밀번호 입력하기)


관리자 계정으로 접속하는 명령어를 3줄로 요약한 것이다. 
(xe버전 방법은 standard, enterprise의 방법은 미세한 차이가 있을 수도 있음.)



5. HR 계정 - 활성화 하기


Oracle XE 11g에서 제공하는 연습용 계정 HR을 활성화 하는 방법이다.


SQL> alter user hr account unlock;



그림 16. sqlplus 작업을 위한 명령 프롬프트 실행하기


간단한 명령으로 연습용 HR 계정을 활성화 시킬 수 있다.


- 참고로 Oracle 공식 사이트에서 제공하는 메뉴얼도 있으니 참고하면 좋겠다.

https://docs.oracle.com/cd/E17781_01/admin.112/e18585/toc.htm#XEGSG120

반응형
728x90
300x250

[Spring-F.] 27. MyBatis 3.5, Spring Framework 5.4, Oracle 19g - 방법3(SqlMap-XML-Class)


소스 코드 위주로 소개하도록 하겠다.


[실험 결과]

1. [Spring-Framework] Spring Framework 5.4, MyBatis 3.5 연동 방법 - 실험 결과, 2020-10-02

   - https://yyman.tistory.com/1437


[이전 게시글]

1. [Spring-F.] 26. MyBatis 3.5, Spring Framework 5.4, Oracle 19g - 방법2(SqlMap-XML-XML 맵핑)     // 결과: 지원, 2020-10-02

    - https://yyman.tistory.com/1439



24. 결과


완성된 실험 결과이다.



그림 21. 결과



그림 22. 프로젝트 구성도




25. web.xml - 기본값(변동 없음)


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


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

version="3.1">


<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->

<context-param>

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

<param-value>

/WEB-INF/spring/root-context.xml

</param-value>

</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>


<!-- Processes application requests -->

<servlet>

<servlet-name>appServlet</servlet-name>

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

<init-param>

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

<param-value>

/WEB-INF/spring/appServlet/servlet-context.xml

</param-value>

</init-param>

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

</servlet>

<servlet-mapping>

<servlet-name>appServlet</servlet-name>

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

</servlet-mapping>


</web-app>




26. view - home.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 prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

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

<%@ page session="false" %>


<html>

<head>

<title>Home</title>

</head>

<body>

<h1>

Hello world!  

</h1>


<P>  The time on the server is ${serverTime}. </P>

<h3>SqlMapSessionFactory 방식(XML - 환경설정 - 클래스-Mappers)</h3>

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

    ${val.username} / 

    ${val.password} /

    ${val.enabled }<br>

</c:forEach>

<c:if test="${empty list }">

    ${"데이터가 존재하지않아요."}

</c:if>


<h3>XML - web.xml 설정방식</h3>

<c:forEach items="${list2 }" var="val" >

    ${val.username} / 

    ${val.password} /

    ${val.enabled }<br>

</c:forEach>

<c:if test="${empty list2 }">

    ${"데이터가 존재하지않아요."}

</c:if>


</body>

</html>



파일명: home.jsp


[첨부(Attachments)]

home.zip




27. com.example.spbatis.db - SqlMapSessionFactory.java


package com.example.spbatis.db;



import java.io.IOException;

import java.io.InputStream;


import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;


import com.example.spbatis.mapper.CompUsersMapper;


public class SqlMapSessionFactory {

public SqlSessionFactory ssf;

public SqlMapSessionFactory () {


        String resource = "com/example/spbatis/mapper/mybatis-config.xml";

        InputStream is = null;


        try {

            is = Resources.getResourceAsStream(resource);

        } catch (IOException e) {

            e.printStackTrace();

        }


        ssf = new SqlSessionFactoryBuilder().build(is);

        ssf.getConfiguration().addMapper(CompUsersMapper.class);


    }

    

    public SqlSessionFactory getSqlSessionFactory(){

        return ssf;

    }

    

}



파일명: SqlMapSessionFactory.java


[첨부(Attachments)]

SqlMapSessionFactory.zip





28. com.example.spbatis.mapper - mybatis-config.xml


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


<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 

"http://mybatis.org/dtd/mybatis-3-config.dtd">


<configuration>


<environments default="development">

    <environment id="development">

      <transactionManager type="JDBC"/>

      <!-- 커넥션 풀(MyBatis) -->

      <dataSource type="POOLED">

        <property name="driver" value="oracle.jdbc.driver.OracleDriver" />

        <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>

        <property name="username" value="UserName"/>

        <property name="password" value="Password"/>

        <property name="poolMaximumActiveConnections" value="20"/>

        <property name="poolMaximumIdleConnections" value="20"/>

        <property name="poolMaximumCheckoutTime" value="20000"/>

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

        <property name="poolPingQuery" value="select 1"/>

        <property name="poolPingConnectionsNotUsedFor" value="10000"/>

        <property name="poolTimeToWait" value="15000"/>

      </dataSource>

    </environment>

</environments>


</configuration>


파일명: mybatis-config.xml


[첨부(Attachments)]

mybatis-config.zip




29. com.example.spbatis.mapper - CompUsersMapper.java


package com.example.spbatis.mapper;


import java.util.List;


import org.apache.ibatis.annotations.Mapper;

import org.apache.ibatis.annotations.Select;


import com.example.spbatis.model.CompUsers;


@Mapper

public interface CompUsersMapper {

@Select("SELECT * FROM comp_users")

List<CompUsers> selectAll();

}


파일명: CompUsersMapper.java


[첨부(Attachments)]

CompUsersMapper.zip




30. com.example.spbatis.dao - CompUsersDao.java


package com.example.spbatis.dao;


import java.util.List;


import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

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


import com.example.spbatis.db.SqlMapSessionFactory;

import com.example.spbatis.mapper.CompUsersMapper;

import com.example.spbatis.model.CompUsers;



public class CompUsersDao {

    private SqlMapSessionFactory ssfc;

    private SqlSessionFactory factory;

    

    public CompUsersDao() {

   

        ssfc = new SqlMapSessionFactory();

        factory = ssfc.getSqlSessionFactory();

        

    }

    

    // SQL 세션 열기

    public List<CompUsers> selectAddress() {


    List<CompUsers> user = null;

   

try (SqlSession session = factory.openSession()) {

CompUsersMapper mapper = session.getMapper(CompUsersMapper.class);

user = mapper.selectAll();

// System.out.println("계정명:" + user.getUsername());


}

return user;


    }

    

}



파일명: CompUsersDao.java


[첨부(Attachments)]

CompUsersDao.zip





31. com.example.spbatis.service - CompUsersService.java


package com.example.spbatis.service;


import java.util.List;


import com.example.spbatis.dao.CompUsersDao;

import com.example.spbatis.model.CompUsers;


public class CompUsersService {


private CompUsersDao dao = null;

public CompUsersService() {

dao = new CompUsersDao();

}

public List<CompUsers> getAllCompUsers() {

return dao.selectAddress();

}

 

}



파일명: CompUsersService.java


[첨부(Attachments)]

CompUsersService.zip





32. com.example.spbatis - HomeController.java


package com.example.spbatis;


import java.text.DateFormat;

import java.util.Date;

import java.util.Locale;


import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

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

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

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

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


import com.example.spbatis.service.CompUsersService;


/**

 * Handles requests for the application home page.

 */

@Controller

public class HomeController {

private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

private CompUsersService compUserService;

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

public String home(Locale locale, Model model) {

logger.info("Welcome home3! The client locale is {}.", locale);

Date date = new Date();

DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

String formattedDate = dateFormat.format(date);

compUserService = new CompUsersService();

model.addAttribute("serverTime", formattedDate );

model.addAttribute("list", compUserService.getAllCompUsers()) ;

return "home";

}

}



파일명: HomeController.java


[첨부(Attachments)]

HomeController.zip



* 4부에서 만나요.


1. [Spring-F.] 28. MyBatis 3.5, Spring Framework 5.4, Oracle 19g - 방법4(SqlMap Spring전용)   // 결과: 지원, 2020-10-02

https://yyman.tistory.com/1441


반응형
728x90
300x250

[Spring-Framework] Spring Framework 5.4, MyBatis 3.5 연동 방법 - 실험 결과


아마 이런 실험을 시도한 인터넷 글은 최초가 되지 않을까 싶다.

현재에 떠돌아 다니는 정보들을 충분한 시간을 가지고 실험한 결과이다.


필자가 구독자들에게 한 가지 약속한다면, 검증을 확실히 완료하고 작성한 글이다.

이 글을 어떻게 전달해야 할지 고민을 충분히 하고 작성하게 되었다.


@Autowired 방식과 @Beans 방식을 사용하는 유저가 있다면, 사용하지 않아야 한다.



1. 결과


엄격한 태스트를 거쳐서 완료한 결과이다. 개발 환경을 구축하는데 있어서 삽질을 하지 않았으면 하는 바람이다.



그림 1. 실험 결과


[첨부(Attachments)]

MyBatis-Complete-summary.zip




2. 5가지 방법 - 정리


정리가 완료되는데로 공개하도록 하겠다.


1. [Spring-F.] 25. MyBatis 3.5, Spring Framework 5.4, Oracle 19g - 방법1(web.xml-Beans)            // 결과: 미지원, 2020-10-02

   - https://yyman.tistory.com/1438

2. [Spring-F.] 26. MyBatis 3.5, Spring Framework 5.4, Oracle 19g - 방법2(SqlMap-XML-XML 맵핑)   // 결과: 지원, 2020-10-02

   - https://yyman.tistory.com/1439

3. [Spring-F.] 27. MyBatis 3.5, Spring Framework 5.4, Oracle 19g - 방법3(SqlMap-XML-Class)    // 결과: 지원, 2020-10-02

   - https://yyman.tistory.com/1440

4. [Spring-F.] 28. MyBatis 3.5, Spring Framework 5.4, Oracle 19g - 방법4(SqlMap Spring전용)   // 결과: 지원, 2020-10-02

   - https://yyman.tistory.com/1441

5. [Spring-F.] 29. MyBatis 3.5, Spring Framework 5.4, Oracle 19g - 방법5(SqlMap Spring전용)  // 결과: 지원, 2020-10-02

   - https://yyman.tistory.com/1442


= (기타: 표준 지원에 대한 4, 5번 소스코드도 주석으로 포함 처리함.)




3. 실험 조건


실험 조건은 다음과 같다.


* IDE: Spring Tool-Suites 4-4.7.2 (Releases)

* Library:

- Spring-Framework 5.2.9.RELEASE (2020-09-15)

javax.servlet-api 4.0.1 (2018-04-20)

   - https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api/4.0.1

- mybatis-spring (2020-06-05) // Spring Framework만 사용가능함.

   - https://mvnrepository.com/artifact/org.mybatis/mybatis-spring/2.0.5

- mybatis 3.5.5 (2020-06-04)

   - https://mvnrepository.com/artifact/org.mybatis/mybatis/3.5.5

- Spring JDBC 

   - https://mvnrepository.com/artifact/org.springframework/spring-jdbc/5.2.9.RELEASE

- ojdbc8 (ojdbc8)

- mariadb-java-client 2.7.0 (2020-09-24)

   - https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client/2.7.0

- mysql-connector-java 8.0.21 (2020-07-12)


* DB:

- Oracle Databases 19g




4. 실험 결과 - 동작 영상


입증하기 위해서 영상을 준비하였다.



영상 1. Spring Framework 5.4, Oracle 19g, Mybatis 3.5 연동하기



영상 2. Spring Framework 5.4, Oracle 19g, Mybatis 3.5 연동하기(실험 1 - 영상 [예])


이런 형태로 프로젝트를 구성한 것이다.



5. 공통 - 프로젝트 생성 방법


5가지 방법에 관한 프로젝트 생성에 관한 것이다.

1~5번의 셋팅은 Build Path, Project Factes, POM.xml은 동일하다.



그림 1. 프로젝트 생성하기(1)


File->New->Spring Legacy Project를 클릭한다.



그림 2. 프로젝트 생성하기(2)


Spring MVC Project를 선택한다.

Next를 클릭한다.



그림 3. 프로젝트 생성하기(3)


top-level package 경로를 입력한 후 Finish를 누른다.



5-1. Build-Path, Project Factes 설정하기


자바 버전을 변경해줄 것이다.

초기 Spring Legacy Project로 Spring MVC Project를 생성하면, 1.6 버전으로 셋팅되어 생성될 것이다.

이러한 것을 변경해줄 것이다.



그림 4. 프로젝트 속성 들어가기


프로젝트를 선택한 후 마우스 오른쪽 버튼을 클릭한다.

Properties를 클릭한다.




그림 5. Build-path 버전 바꾸기


Java-Build Path를 클릭한다.

JRE System Library을 선택한다.

Edit 클릭하고 변경하면 된다.

(JRE -> JavaSE 14로 변경할 것)

Apply를 누른다.



그림 6. Project - Factes 설정하기


Project Factes를 클릭한다.

Java 버전을 14로 변경해준다.


Apply를 누른다.



5-2. Pom.xml 설정하기


pom.xml 설정에 관한 것이다.



그림 7. pom.xml 설정하기(1)


<org.springframework-version>을 5.2.9.RELEASE로 변경하였다.



그림 8. pom.xml 설정하기(2)


javax.servlet-api 버전을 4.0.1로 변경하였다.




그림 9. pom.xml 설정하기(3)


mybatis-spring, mybatis를 추가하였다.




그림 10. pom.xml - 오라클이 설치된 경우에만 따라하기(1)


pom.xml을 마우스 오른쪽 버튼으로 클릭한다.

Maven->Add Dependency를 클릭한다.




그림 11. pom.xml - 오라클이 설치된 경우에만 따라하기(2)


oracle이라고 검색한다.

com.oracle.database.jdbc | ojdbc8을 선택한다.

OK를 누른다.




그림 12. pom.xml - mariadb, mysql-connector 추가하기


추가로 몇 개의 DB 드라이버(MariaDB, MySQL-Connector)를 부착시켰다. 


<?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.example</groupId>

<artifactId>spbatis</artifactId>

<name>Spring-MVC-mybatis</name>

<packaging>war</packaging>

<version>1.0.0-BUILD-SNAPSHOT</version>

<properties>

<java-version>1.6</java-version>

<org.springframework-version>5.2.9.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>

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->

<dependency>

    <groupId>javax.servlet</groupId>

    <artifactId>javax.servlet-api</artifactId>

    <version>4.0.1</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>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->

<dependency>

    <groupId>org.mybatis</groupId>

    <artifactId>mybatis-spring</artifactId>

    <version>2.0.5</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->

<dependency>

    <groupId>org.mybatis</groupId>

    <artifactId>mybatis</artifactId>

    <version>3.5.5</version>

</dependency>

<!-- 스프링에서 JDBC 를 사용하기 위한 라이브러리 입니다. -->

<dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-jdbc</artifactId>

   <version>${org.springframework-version}</version>

</dependency>


<dependency>

<groupId>com.oracle.database.jdbc</groupId>

<artifactId>ojdbc8</artifactId>

<version>19.7.0.0</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->

<dependency>

    <groupId>org.mariadb.jdbc</groupId>

    <artifactId>mariadb-java-client</artifactId>

    <version>2.7.0</version>

</dependency>

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->

<dependency>

    <groupId>mysql</groupId>

    <artifactId>mysql-connector-java</artifactId>

    <version>8.0.21</version>

</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>



파일명: pom.xml


[첨부(Attachments)]

pom.zip



6. DB - Table 설계


Spring Security에서 사용자 계정의 테이블 설계를 사용하였다.



그림 13. 테이블 모습


CREATE TABLE comp_users (

username VARCHAR(50) NOT NULL,

password VARCHAR(300) NOT NULL,

enabled INT NOT NULL,

PRIMARY KEY (username)

);


-- 계정

INSERT INTO comp_users (username, password, enabled) VALUES ('user', '$2a$10$x04djNV2e9rpcPPRyXoLk.rMm6iZe2/vYdzpqHQcLeNSYdt7kc30O', 1);

INSERT INTO comp_users (username, password, enabled) VALUES ('admin', '$2a$10$QUddY3O/6ZgkYCR6MFlv9.nqA501Fm0cc/ZxQHX5pwb1o0CYCTiIS', 1);


파일명: Comp_users.sql


[첨부(Attachments)]

comp_user.zip





6-1. Model - CompUsers.java


공통으로 1~5 프로젝트에서 사용되는 부분이다.


package com.example.spbatis.model;


public class CompUsers {

private String username;

private String password;

private int enabled;

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public int getEnabled() {

return enabled;

}

public void setEnabled(int enabled) {

this.enabled = enabled;

}


}



파일명: CompUsers.java


[첨부(Attachments)]

CompUsers.zip




* 맺음글(Conclusion)


1~5개의 글을 추가로 살펴보면 되겠다.

반응형
728x90
300x250

[Spring-Framework] 14. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-XML) (2)


1부에 이어서 글을 작성하도록 하겠다.


1. [Spring-Framework] 14. Spring MVC, Spring Security 5.4, Oracle - 보안처리(로그인-XML) (1), 2020-09-26

https://yyman.tistory.com/1419




11. Controller - HomeController.java


HomeController.java에 관한 것이다.

파일은 처음 프로젝트(이하 "Spring MVC Project")를 생성하면, 자동으로 만들어진다.


package com.web.springsecurity5.controller;


import java.text.DateFormat;

import java.util.Date;

import java.util.Locale;


import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.security.core.context.SecurityContextHolder;

import org.springframework.security.core.userdetails.UserDetails;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

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

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


@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);

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

String username = null;

String password = null;

try {

UserDetails userDetails = (UserDetails)principal;

username = userDetails.getUsername();

password = userDetails.getPassword();

}catch(Exception e) {

e.getStackTrace();

}


model.addAttribute("username", username);

model.addAttribute("password", password);

model.addAttribute("serverTime", formattedDate );

return "home";

}

}



파일명: HomeController.java


[첨부(Attachments)]

HomeController.zip


비고: 의외로 Controller 코드는 간단하게 되어있는 것을 알 수 있다.




12. Controller - MemberController.java


MemberController에 관한 것이다.

자세히 코드를 살펴보면, "@RequestMapping"을 변경해봐도 되는 부분이 있다. (크게 무방하다.)

함수에 직접 경로를 입력한 형태로 servlet을 구성하였다.


package com.web.springsecurity5.controller;


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;


@Controller

public class MemberController {

private static final Logger logger = LoggerFactory.getLogger(MemberController.class);

@RequestMapping(value = "/member/loginForm", method = RequestMethod.GET)

public String loginForm(Locale locale, Model model) {

logger.info("안녕 - 로그인 폼(Hello - Login Form");

// model.addAttribute("serverTime", formattedDate );

return "member/loginForm";

}


@RequestMapping(value = "/member/accessDenied")

public String accessDenied(Locale locale, Model model) {


logger.info("접근 금지 - 이동(Accessed Denied)");

// model.addAttribute("serverTime", formattedDate );

return "redirect:/member/accessDeniedView";

}

@RequestMapping(value = "/member/accessDeniedView")

public String accessDeniedView(Locale locale, Model model) {


logger.info("접근 금지 - 출력(Accessed Denied)");

// model.addAttribute("serverTime", formattedDate );

return "member/accessDenied";


}

}


파일명: MemberController.java


[첨부(Attachments)]

MemberController.zip




13. Controller - AdminController.java


관리자 페이지에 관한 Controller이다.


package com.web.springsecurity5.controller;


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;


@Controller

public class AdminController {

private static final Logger logger = LoggerFactory.getLogger(AdminController.class);

@RequestMapping(value = "/admin/home", method = RequestMethod.GET)

public String home(Locale locale, Model model) {

logger.info("Welcome - 관리자 페이지(Admin Home)!");

return "admin/home";

}

}


파일명: AdminController.java


[첨부(Attachments)]

AdminController.zip




14. View - 구성도


출력되는 화면에 관한 프로젝트 구성도이다.



그림 25. view 프로젝트 구성도





15. View - home.jsp


코드와 실제 디자인 화면을 동시에 소개하겠다.


경로: src/main/java/webapp/WEB-INF/views


그림 26. 로그인 페이지(home.jsp) - 로그인 전



그림 27. 로그인 페이지(home.jsp) - 로그인 후





그림 27. 로그인 페이지(home.jsp) - 로그인 후 - 비밀번호 생성 페이지


비고: UI(이하 "User Interface")설계하는데 도움이 되었으면 한다.



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

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

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

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

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


<%@ page session="false" %>

<html>

<head>

<title>Spring-Security 5 (XML 방식)</title>

<meta charset="UTF-8">

<style>

body{

font-family:'Arial';

font-size:12px;

}

a{

text-decoration:none;

color:#666;

}

</style>

</head>

<body>

<h1>

Hello world!(Spring-Security 5(XML 방식)) - DB연동(Oracle)

</h1>

<hr />

<sec:authorize access="isAnonymous()">

<!-- 로그인 전 -->

<p>

<a href="<c:url value="/member/loginForm" />">로그인</a>

</p>

</sec:authorize> 


<sec:authorize access="isAuthenticated()">

<!-- 로그인 성공 -->

<form:form action="${pageContext.request.contextPath}/logout" method="POST">

<input type="submit" value="로그아웃" />

</form:form>

<p>

${username} &nbsp; ${password}

</p>

</sec:authorize> 


<h3>

<a href="<c:url value="/admin/home" />">관리자 홈</a>&nbsp;&nbsp;

<a href="<c:url value="/encode-password?password=pass" />">비밀번호</a>

</h3>


<!-- 비밀번호 생성기 -->

<c:set var="gene_pwd" value="${encode}" />

<c:if test="${gene_pwd != null}">

    <c:out value="${gene_pwd}" />

</c:if>


</body>

</html>



파일명: home.jsp


[첨부(Attachments)]

home.zip



16. View - admin/home.jsp


관리자 페이지에 관한 것이다.


경로: src/main/java/webapp/WEB-INF/views/admin



그림 28. 관리자 홈 화면 - (User-Interface) 설계


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

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

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

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

<!DOCTYPE html>

<html lang="ko">

<head>

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

    <title>관리자(ROLE_ADMIN) - 홈</title>

    <style>

    body{

    font-family:'Arial';

    font-size:12px;

    }

   

    a{

    text-decoration:none;

    color:#666;

    }

    </style>

</head>


<body>


<h1>관리자 홈 화면!</h1>

<hr />


<h3>[<a href="<c:url value="/" />">홈으로(Home)</a>]</h3>


</body>

</html>


파일명: home.jsp


[첨부(Attachments)]

home.zip




17. View - member/loginForm.jsp


로그인 페이지에 대한 것이다.


경로: src/main/java/webapp/WEB-INF/views/member



그림 29. 로그인 폼 - 화면



그림 30. 로그인 폼 - 계정 불일치(아이디 또는 비밀번호)



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

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

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

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

    <title>로그인 - 페이지(Login - Page)</title>

    <style>

    body{

    font-family:'Arial';

    font-size:12px;

    }

   

    a{

    text-decoration:none;

    color:#666;

    }

   

    </style>

</head>


<body>


<h1>아이디와 비밀번호를 입력해주세요.</h1>

<hr />


<c:url value="/login" var="loginUrl" />


<form:form name="f" action="${loginUrl}" method="POST">

    <p>

        <label for="username">아이디</label>

        <input type="text" id="id" name="id" />

    </p>

    <p>

        <label for="password">비밀번호</label>

        <input type="password" id="password" name="password"/>

    </p>

    <%-- <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> --%>

    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

    <button type="submit" class="btn">로그인</button>

    

    <!-- 에러 메시지 영역 -->

    <c:if test="${param.error != null}">

        <p>아이디와 비밀번호가 잘못되었습니다.</p>

    </c:if>

    <c:if test="${param.logout != null}">

        <p>로그아웃 하였습니다.</p>

    </c:if>

    

</form:form>

<h3>[<a href="<c:url value="/" />">홈으로(Home)</a>]</h3>


</body>

</html>



파일명: loginForm.jsp


[첨부(Attachments)]

loginForm.zip




18. View - member/accessDenied.jsp


인가되지 않은 화면 또는 오류 처리에 대한 것이다.



그림 31. Access Denied 페이지


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

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

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

<!DOCTYPE html>

<html lang="ko">

<head>

    <meta charset="UTF-8">

    <title>Access Denied</title>

</head>


<body>


<h1>Access Denied!</h1>


<h3>[<a href="<c:url value="/" />">홈</a>]</h3>


</body>

</html>



파일명: accessDenied.jsp


[첨부(Attachments)]

accessDenied.zip



19. 공식 사이트에서 배포하고 있는 Spring-Boot 기반 - 예제


https://github.com/spring-projects/spring-security/tree/5.4.0/samples/boot/helloworld


Spring Security 5.4를 자바 파일 환경 설정 방식으로 구현한 것이다.

(구현 방식에는 크게 "XML 방식"과 "Java 파일" 방식이 있다.)

-> 구현하는데 있어서, 차이점이 있다.



그림 32. github - Spring Security Official 사이트



* 맺음글(Conclusion)


아무쪼록 Spring-Security 5 적용에 있어서 어려움이 해소되길 진심으로 기원한다.



* 참고자료(References)


1. 스프링프레임웍 - Spring Security(2) : 커스텀 로그인 화면 및 권한에 따른 접근 제어, https://offbyone.tistory.com/91, Accessed by 2020-09-26, Last Modified 2018-04-08.

-> 추천(50점): 잘 되어 있는 블로그 중 하나이다.


2. 스프링 시큐리티 5 - There is no PasswordEncoder mapped for the id "null", https://meaownworld.tistory.com/129, Accessed by 2020-09-26, Last Modified 2018-03-11.


3. [spring security/스프링 시큐리티] 비밀번호 암호화와 로그인 하기, https://simsimjae.tistory.com/36, Accessed by 2020-09-26, Last Modified 2017-08-28.


4. BCryptPasswordEncoder : 암호 해시, http://www.devkuma.com/books/pages/1124, Accessed by 2020-09-26, Last Modified 2017-12-30.

-> 비고: Spring Security 암호 처리에 대해서 잘 소개하고 있음.


5. Spring Security JdbcDaoImpl Example, https://www.concretepage.com/spring-5/spring-security-jdbcdaoimpl#XML, Accessed by 2020-09-26, Last Modified 2019-12-11.

-> 추천(35점): Java방법론, XML방법론 두 타입을 자세하고 잘 설명하고 있음.


6. [Spring Security] 현재 로그인한 사용자 정보 가져오기, https://itstory.tk/entry/Spring-Security-%ED%98%84%EC%9E%AC-%EB%A1%9C%EA%B7%B8%EC%9D%B8%ED%95%9C-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A0%95%EB%B3%B4-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0, Accessed by 2020-09-26, Last Modified 2017-09-07.


7. [spring] 시큐리티 비밀번호 bcrypt 간단한 암호화, https://blog.naver.com/PostView.nhn?blogId=ljpark6&logNo=221578990976, Accessed by 2020-09-26, Last Modified 2019-07-06.


9. Spring Web MVC Security Basic Example Part 1 with XML Configuration, https://www.codejava.net/frameworks/spring/spring-web-mvc-security-basic-example-part-1-with-xml-configuration, Accessed by 2020-09-26, Last Modified 2019-06-24.

-> 비고: Spring Security 4를 기준으로 작성하였음. 

Spring-Framework 3.2~4.x 이전의 경우에는 내장 로그인 인터페이스가 해당 사이트와 동일하거나 흡사함.

이전 인터페이스보다는 Spring-Framework 4.x~5 이후부터는 디자인이 있는 형태의 내장 로그인 인터페이스로 출력됨.


10. [SPRING] Controller에서 redirect하기, https://sime.tistory.com/119, Accessed by 2020-09-26, Last Modified 2016-11-17.

-> 비고: Spring-Security의 Access-error-page처리에 있어서 메시지만 출력하고, accessDenied.jsp화면이 출력되지 않는 문제를 해결하는데

          redirect 방법을 참고하여 적용하였음.


11. Spring Security 5.4 - Docs, https://docs.spring.io/spring-security/site/docs/5.4.0/reference/html5/, Accessed by 2020-09-26, Last Modified 2020-09-09.

-> 비고: 공식 사이트이긴 하나, spring-boot을 주력으로 작성되어 있어서 크게 도움이 되지 않을 수도 있음.


12. Spring Security 5.4 - API, https://docs.spring.io/spring-security/site/docs/5.4.0/api/, Accessed by 2020-09-26, Last Modified .

-> 비고: API 사이트이니 구현해놓고 분석할 때 참고하면 될 것으로 보인다.


13. spring-security/samples/boot/helloworld at 5.4.0 · spring-projects/spring-security · GitHub, https://github.com/spring-projects/spring-security/tree/5.4.0/samples/boot/helloworld, Accessed by 2020-09-26, Last Modified .

-> 추천(15점): 간결하게 Java 환경설정 방식으로 예제를 소개하고 있다. (Spring-boot로 작성), Spring Security에서 공식 운영하는 github사이트이다.

반응형

+ Recent posts