[구름ide] Mysql 접속

2020. 2. 24. 23:57

컨테이너 생성할 때 Mysql을 체크하면 설치되어 있으나 설치되어 있지 않으면

sudo apt-get install mysql-server

 

설치되어 있으면 이미 설치되어 있다는 message가 나옴

mysql 서비스 시작

sudo service mysql start

mysql 접속 : 최초 root 계정의 password는 없으므로 비번없이 접속

mysql -uroot

접속시 다음에러가 나면

Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
sudo service mysql restart 를 실행 한 다음

mysql -uroot 로 접속해본다

mysql start가 되어있지 않으면 php laravel 에서 db migrate 했을 때 오류가 난다.

php artisan migrate            

  1   PDOException::("SQLSTATE[HY000] [2002] Connection refused")                            /vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70                                                                       

mysql db에 권한이 없으면

   php artisan migrate                                                                                        

Illuminate\Database\QueryException  : SQLSTATE[HY000] [1698] Access denied for user 'root'@'localhost' (SQL: select * from information_schema.tables where table_schema = blog and table_name = migrations and table_type = ...                                      

그래서

mysql 접속한 뒤 DB 생성, 권한주기

create database blog;

GRANT ALL PRIVILEGES ON * . * TO 'root'@'localhost';
FLUSH PRIVILEGES;

그런데... 그래도 접속이 안된다.

이유는 DB 접속파일인 env에 있다.
.env 파일에 db접속정보가 있다.

여기에
DB_HOST=127.0.0.1 로 되어있으면
위에서 grant 'root'@'127.0.0.1' 를 추가
또는
DB_HOST=localhost 로 바꿔주면 정상적으로 접속된다.

table 없다는 오류가 나오면
php artisan migrate 으로 table 생성하면 됨

 

 

728x90

컨테이너로 php 선택하여 생성

#update 및 upgrade
$sudo apt update && sudo apt upgrade

# php -v 를 실행하여 7.3.1이 나옴 그래서 7.3으로 install
$sudo apt install php7.3-common php7.3-cli php7.3-gd php7.3-mysql php7.3-curl php7.3-intl php7.3-mbstring php7.3-bcmath php7.3-imap php7.3-xml php7.3-zip

# composer 설치
$curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer

제대로 설치가 되었는지 확인 : composer --version

# Installing Laravel
$composer create-project --prefer-dist laravel/laravel mylaravel

설치결과 확인. 아래 메세지가 나오면 됨.

Package manifest generated successfully.
> @php artisan key:generate --ansi
Application key set successfully.


# 생성한 프로젝트로 이동
$cd mylaravel
# 서버가동
$php artisan serve

정상가동 확인 message : Laravel development server started: http://127.0.0.1:8000

브라우저에서 실행
goormide 상단메뉴 > 프로젝트 > 실행 URL과 포트에서 링크 클릭

그런데!!!
브라우저에 나타나는 메세지...
Connection Refused 가 웬말이냐....

ctrl + c 로 서버 중지 시키고 host, port를 추가하여 실행

$php artisan serve --host 0.0.0.0 --port 80

정상가동 확인 : Laravel development server started: http://0.0.0.0:80

 

서버가동 Test 결과

가동 명령어 성공여부
php artisan serve Connection Refused
php artisan serve --host=127.0.0.1 Connection Refused
php artisan serve --host=0.0.0.0 Connection Refused
php artisan serve --host=0.0.0.0 --port 80 Laravel 화면 나옴

휴~ 며칠만에 성공했는지 모르겠네

보통은 localhost로 하기 때문에 서버가동시 주소:포트를 입력하면 접속이 되는데
외부에서 접속할 때는 도메일이랑 포트가 맞아야 되어서 겨우 됨.

구글 뒤지다가 0.0.0.0 으로 접속하라는 얘기가 생각나 해 봤더니 되네 ㅎㅎㅎ

환경설정은 이것으로 끝~

 

 

 

728x90

구름 IDE 대시보드에서 '새 컨테이너 생성'

이름 : nodejs

지역 : 아무데나

공개범위 : 아무거나

템플릿 : Template

배포 : Not used

소프트웨어 스택 : Express 선택

다 선택했으면 화면 상단의 생성(Ctrl + M)버튼 클릭

컨테이너가 생성되었으면 컨테이너 실행

터미널에서 ls 입력했을 때

app.js 등이 있으면 됨

 

테스트 : node app.js  실행 후
브라우저에서 확인

브라우저에 입력할 주소는
상단메뉴의 '프로젝트' > 실행 URL과 포트 에서

등록된 url과 포트에 있는 경로를 입력하면 된다.
링크버튼이 있으니 그래도 눌러도 됨.

 

 

 

 

728x90

[React] npm start 시 에러

2020. 1. 12. 11:22

React 에서 npm start 로 브라우저를 시작했는데...

원래는 브라우저가 실행되면서 localhost:3000 에 다음 그림이 나타나야하는데...

브라우저는 실행되는데 화면이 그냥 하얗다....

개발자모드로 보면 콘솔에 에러가 하나 보인다.

SCRIPT5022: SCRIPT5022: SyntaxError

답은 아~주 간단하다.

인터넷 브라우저 중 I.E Edge 는 지원안한댄다... ㅋ

크롬이나 파이어 폭스에서 localhost:3000을 하면 정상으로 나옴

728x90

블로그꾸미기 1에서 web, service, dao 등을 bbs에서 복사해서 사용했다.
그런데.. VO 파일에서 오류가 난다.

egovframework.com.cop.bbs.service.BoardVO cannot be cast to egovframework.blog.service.BoardVO

귀찮아서 그랬는데 casting이 안된다. extends BoardVO로 해도 마찬가지..

그냥 BlogController에서 호출하는 서비스를 EgovEgovArticleService 로 한다.

그리고 egov는 기본적으로 로그인 된 유저를 기본으로 하다보니...
로그인체크를 여러군데에서 한다.

 

로그인부분은 comment 를 조회할 때 로그인되어 있지 않아 저리로 보내버린다...
결국 comment 조회, 저장로직은 수정이 필요하겠다.

    /**
     * 게시물에 대한 목록을 조회한다.
     * 
     * @param boardVO
     * @param sessionVO
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/blog/selectArticleList.blog")
    public String selectArticleList(@ModelAttribute("searchVO") BoardVO boardVO, ModelMap model) throws Exception {
String bbsId = "BBSMSTR_000000000002";// 블로그는 1개만 운영하므로 생성된 블로그의 bbsId 사용-- 나중에 property로
        boardVO.setBbsId(bbsId);
        boardVO.setBbsNm(boardVO.getBbsNm());
boardVO.setPageUnit(propertyService.getInt("pageUnit"));
boardVO.setPageSize(propertyService.getInt("pageSize"));

PaginationInfo paginationInfo = new PaginationInfo();

paginationInfo.setCurrentPageNo(boardVO.getPageIndex());
paginationInfo.setRecordCountPerPage(boardVO.getPageUnit());
paginationInfo.setPageSize(boardVO.getPageSize());

boardVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
boardVO.setLastIndex(paginationInfo.getLastRecordIndex());
boardVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

Map<String, Object> map = blogArticleService.selectArticleList(boardVO);
int totCnt = Integer.parseInt((String)map.get("resultCnt"));

//공지사항 추출
List noticeList = blogArticleService.selectNoticeArticleList(boardVO);

paginationInfo.setTotalRecordCount(totCnt);

model.addAttribute("resultList", map.get("resultList"));
model.addAttribute("resultCnt", map.get("resultCnt"));
model.addAttribute("articleVO", boardVO);
model.addAttribute("bbsNm", "Custom Blog Sample");
model.addAttribute("bbsId", bbsId);
model.addAttribute("bbsTmplatCours", "/css/egovframework/com/cop/tpl/egovBaseTemplate.css");//기본 BBS template 지정 : css 경로. 추후 변경
model.addAttribute("paginationInfo", paginationInfo);
model.addAttribute("noticeList", noticeList);
return "egovframework/com/blog/BlogArticleList";
    }
    
    
    
    /**
     * 게시물에 대한 상세 정보를 조회한다.
     * 
     * @param boardVO
     * @param sessionVO
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/blog/selectArticleDetail.blog")
    public String selectArticleDetail(@ModelAttribute("searchVO") BoardVO boardVO, ModelMap model) throws Exception {

BoardVO vo = blogArticleService.selectArticleDetail(boardVO);

model.addAttribute("result", vo);
//----------------------------
// template 처리 (기본 BBS template 지정  포함)
//----------------------------
model.addAttribute("bbsTmplatCours", "/css/egovframework/com/cop/tpl/egovBaseTemplate.css");//기본 BBS template 지정 : css 경로. 추후 변경
////-----------------------------
if (egovArticleCommentService != null){
if (egovArticleCommentService.canUseComment(boardVO.getBbsId())) {
    model.addAttribute("useComment", "true");
}
}
////--------------------------
model.addAttribute("bbsId", "BBSMSTR_000000000002");// 블로그는 1개만 운영하므로 생성된 블로그의 bbsId 사용-- 나중에 property로
return "egovframework/com/blog/BlogArticleDetail";
    }
728x90

실제로 /blog/selectArticleList.do 를 하면 로그인 페이지로 넘어간다
(정상적으로 화면이 보였다면 다른 세션으로 로그인 해서 filter를 통과한 경우이다.)

간단히 해결하는 방법은 .do 대신 .blog를 사용하면 된다.

호출하는 url을 바꾸면 되는 것인데

    @RequestMapping("/blog/selectArticleList.blog")
    public String selectArticleList(@ModelAttribute("searchVO") BoardVO boardVO, ModelMap model) throws Exception

와 같이 하면 된다.

src/main/webapp/WEB-INF/config/egovframework/springmvc/egov-com-servlet.xml 에

 

그리고 블로그 게시물이 1개 있었는데 안나왔던 이유는

controller에서 bbsID 가 없어서였다.
원래는 넘겨받는 boardVO 안에 bbsId가 있으나 이번경우는 블로그도 1개만운영하고 바로 호출하므로 직접 하드코딩한다.

 

쿼리 로그 확인시 bbsId가 있는것이 확인되고
실행해보면 게시글 1개가 있다.

SELECT a.NTT_ID, a.NTT_SJ, a.NTT_CN, a.FRST_REGISTER_ID, IFNULL(b.USER_NM, a.NTCR_NM) as FRST_REGISTER_NM, 
DATE_FORMAT(a.FRST_REGIST_PNTTM, '%Y-%m-%d') as FRST_REGIST_PNTTM, a.RDCNT, a.PARNTSCTT_NO, 
a.ANSWER_AT, a.ANSWER_LC, a.USE_AT, a.ATCH_FILE_ID, a.BBS_ID, a.NTCE_BGNDE, a.NTCE_ENDDE, a.SJ_BOLD_AT, 
a.NOTICE_AT, a.SECRET_AT, c.COMMENT_CO 
FROM COMTNBBS a LEFT OUTER JOIN COMVNUSERMASTER b 
ON a.FRST_REGISTER_ID = b.ESNTL_ID 
LEFT OUTER JOIN (SELECT NTT_ID, BBS_ID, COUNT(1) AS COMMENT_CO 
FROM COMTNCOMMENT WHERE USE_AT = 'Y' GROUP BY NTT_ID, BBS_ID) c 
ON a.NTT_ID = c.NTT_ID AND a.BBS_ID = c.BBS_ID 
WHERE a.BBS_ID = 'BBSMSTR_000000000002' AND a.USE_AT = 'Y' AND a.NTT_SJ 
LIKE CONCAT ('%', '','%') ORDER BY a.SORT_ORDR DESC, NTT_NO ASC LIMIT 10 OFFSET 0 
;

 

이제 jsp파일을 수정할 차례

BlogArticleList.jsp 파일에서

cop/bbs/selectArticleList.do 등  cop/bbs -> blog로, .do로 되어있는 것을 .blog로 모두 찾아 바꿔준다.

 

728x90

전자정부 프레임워크를 통해 게시판, 블로그 등을 쉬게 생성할 수 있다.

그러나 내 입맞대로 고치기 어려워 관련내용을 남긴다.

컨셉 : 관리는 기존 전자정부프레임워크를 그대로 쓰고 이용자 화면만 별도로 만든다.

먼저 관리자 로그인 한 뒤에 블로그를 생성한다.
기본개념이 블로그를 여러개 만들수 있도록 되어있다.
블로그 추가방법은 아래 링크 참조
https://nobang.tistory.com/entry/%EC%A0%84%EC%9E%90%EC%A0%95%EB%B6%80-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EB%B8%94%EB%A1%9C%EA%B7%B8-%EC%B6%94%EA%B0%80

기존로직은 그대로(글쓰기, 글저장, 글목록, 글내용보기) 두고
글목록과 글 내용보기만 별도로 만든다.

1. Controller, Service, DAO, VO 등 서버단
참조 대상

유형 대상소스 비고
Controller egovframework.com.cop.bbs.EgovBBSAttributeManageController.java 게시판 관리를 위한 컨트롤러 클래스
Service egovframework.com.cop.bbs.service.EgovBBSAttributeManageService.java 게시판 관리를 위한 서비스 인터페이스
ServiceImpl egovframework.com.cop.bbs.service.impl.EgovBBSAttributeManageServiceImpl.java 게시판 관리를 위한 서비스 구현 클래스
DAO egovframework.com.cop.bbs.service.impl.EgovBBSAttributeManageDAO.java 게시판 관리를 위한 데이터처리 클래스
VO egovframework.com.cop.bbs.service.BoardMaster.java 게시판 관리를 위한 모델 클래스
VO egovframework.com.cop.bbs.service.BoardMasterVO.java 게시판 관리를 위한 VO 클래스

Blog만 사용할 예정이므로 blog package를 새로 만들고 그 아래에 각 파일들을 위치시킨다.

특이하게 service package에 Board, BoardVO가 위치해있다.(구조는 그대로 가져가기로 했으므로 그대로 사용)
기존서비스는 그대로 사용할 예정이므로 Board, BoardVO는 package경로만 확인한다.

이제 BBS로 되어있는 것을 Blog로 바꾸는 작업이다. 오류를 최소화 하기 위해 아랫단부터 변경한다.

- dao 도 특이하게 service.impl과 같이있다..
 

package egovframework.blog.service.impl;

import java.util.List;

import org.springframework.stereotype.Repository;

import egovframework.com.cmm.service.impl.EgovComAbstractDAO;
import egovframework.blog.service.Board;
import egovframework.blog.service.BoardVO;

@Repository("BlogArticleDAO")
public class BlogArticleDAO extends EgovComAbstractDAO {

public List<?> selectArticleList(BoardVO boardVO) {
return list("BBSArticle.selectArticleList", boardVO);
}

public int selectArticleListCnt(BoardVO boardVO) {
return (Integer)selectOne("BBSArticle.selectArticleListCnt", boardVO);
}

public int selectMaxInqireCo(BoardVO boardVO) {
return (Integer)selectOne("BBSArticle.selectMaxInqireCo", boardVO);
}

public void updateInqireCo(BoardVO boardVO) {
update("BBSArticle.updateInqireCo", boardVO);
}

public BoardVO selectArticleDetail(BoardVO boardVO) {
return (BoardVO) selectOne("BBSArticle.selectArticleDetail", boardVO);
}

public void replyArticle(Board board) {
insert("BBSArticle.replyArticle", board);
}

public List selectNoticeArticleList(BoardVO boardVO) {
return (List) list("BBSArticle.selectNoticeArticleList", boardVO);
}

public List<?> selectGuestArticleList(BoardVO vo) {
return list("BBSArticle.selectGuestArticleList", vo);
}

public int selectGuestArticleListCnt(BoardVO vo) {
return (Integer)selectOne("BBSArticle.selectGuestArticleListCnt", vo);
}

/*
 * 블로그 관련
 */
public BoardVO selectArticleCnOne(BoardVO boardVO) {
return (BoardVO) selectOne("BBSArticle.selectArticleCnOne", boardVO);
}

public List selectBlogNmList(BoardVO boardVO) {
return (List) list("BBSArticle.selectBlogNmList", boardVO);
}

public List<?> selectBlogListManager(BoardVO vo) {
return list("BBSArticle.selectBlogListManager", vo);
}

public int selectBlogListManagerCnt(BoardVO vo) {
return (Integer)selectOne("BBSArticle.selectBlogListManagerCnt", vo);
}

public List selectArticleDetailDefault(BoardVO boardVO) {
return (List) list("BBSArticle.selectArticleDetailDefault", boardVO);
}

public int selectArticleDetailDefaultCnt(BoardVO boardVO) {
return (Integer)selectOne("BBSArticle.selectArticleDetailDefaultCnt", boardVO);
}

public List selectArticleDetailCn(BoardVO boardVO) {
return (List) list("BBSArticle.selectArticleDetailCn", boardVO);
}


}

- service Interface는 select만 남겨놓는다(insert/update/delete는 제거)

package egovframework.blog.service;

import java.util.List;
import java.util.Map;

import egovframework.rte.fdl.cmmn.exception.FdlException;

public interface BlogArticleService {

Map<String, Object> selectArticleList(BoardVO boardVO);

BoardVO selectArticleDetail(BoardVO boardVO);

List selectNoticeArticleList(BoardVO boardVO);

Map<String, Object> selectGuestArticleList(BoardVO vo);

/*
 * 블로그 관련
 */
BoardVO selectArticleCnOne(BoardVO boardVO);

List selectBlogNmList(BoardVO boardVO);

Map<String, Object> selectBlogListManager(BoardVO boardVO);

List selectArticleDetailDefault(BoardVO boardVO);

int selectArticleDetailDefaultCnt(BoardVO boardVO);

List selectArticleDetailCn(BoardVO boardVO);

int selectLoginUser(BoardVO boardVO);
}

- service Impl

package egovframework.blog.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import egovframework.blog.service.BlogArticleService;
import egovframework.blog.service.Board;
import egovframework.com.cmm.service.EgovFileMngService;
import egovframework.blog.service.BoardVO;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import egovframework.rte.fdl.cmmn.exception.FdlException;
import egovframework.rte.fdl.idgnr.EgovIdGnrService;
import egovframework.rte.fdl.property.EgovPropertyService;

@Service("BlogArticleService")
public class BlogArticleServiceImpl extends EgovAbstractServiceImpl implements BlogArticleService {

@Resource(name = "BlogArticleDAO")
    private BlogArticleDAO blogArticleDao;

    @Resource(name = "EgovFileMngService")
    private EgovFileMngService fileService;

    @Resource(name = "propertiesService")
    protected EgovPropertyService propertyService;

    @Resource(name = "egovNttIdGnrService")
    private EgovIdGnrService nttIdgenService;

@Override
public Map<String, Object> selectArticleList(BoardVO boardVO) {
List<?> list = blogArticleDao.selectArticleList(boardVO);


int cnt = blogArticleDao.selectArticleListCnt(boardVO);

Map<String, Object> map = new HashMap<String, Object>();

map.put("resultList", list);
map.put("resultCnt", Integer.toString(cnt));

return map;
}

@Override
public BoardVO selectArticleDetail(BoardVO boardVO) {
    int iniqireCo = blogArticleDao.selectMaxInqireCo(boardVO);

    boardVO.setInqireCo(iniqireCo);
    blogArticleDao.updateInqireCo(boardVO);

return blogArticleDao.selectArticleDetail(boardVO);
}

@Override
public BoardVO selectArticleCnOne(BoardVO boardVO) {
return blogArticleDao.selectArticleCnOne(boardVO);
}

@Override
public List selectArticleDetailDefault(BoardVO boardVO) {
return blogArticleDao.selectArticleDetailDefault(boardVO);
}

@Override
public int selectArticleDetailDefaultCnt(BoardVO boardVO){
return blogArticleDao.selectArticleDetailDefaultCnt(boardVO);
}

@Override
public List selectArticleDetailCn(BoardVO boardVO) {
return blogArticleDao.selectArticleDetailCn(boardVO);
}


@Override
public List selectNoticeArticleList(BoardVO boardVO) {
return blogArticleDao.selectNoticeArticleList(boardVO);
}

@Override
public List selectBlogNmList(BoardVO boardVO) {
return blogArticleDao.selectBlogNmList(boardVO);
}

@Override
public Map<String, Object> selectGuestArticleList(BoardVO vo) {
List<?> list = blogArticleDao.selectGuestArticleList(vo);


int cnt = blogArticleDao.selectGuestArticleListCnt(vo);

Map<String, Object> map = new HashMap<String, Object>();

map.put("resultList", list);
map.put("resultCnt", Integer.toString(cnt));

return map;
}

//@Override
//public void insertArticle(Board board) throws FdlException {
// insert/update는 관리자 화면에서

//}

//@Override
//public void updateArticle(Board board) {
// insert/update는 관리자 화면에서

//}

//@Override
//public void deleteArticle(Board board) throws Exception {
// insert/update는 관리자 화면에서

//}

//@Override
//public Map<String, Object> selectBlogListManager(BoardVO boardVO) {
// insert/update는 관리자 화면에서

//return null;
//}

@Override
public int selectLoginUser(BoardVO boardVO) {
// TODO Auto-generated method stub
return 0;
}



}

- Controller 에서 request받을 경로와 return받을 경로, 사용할 service 경로 등을 수정

package egovframework.blog.web;


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springmodules.validation.commons.DefaultBeanValidator;

import egovframework.com.cmm.EgovMessageSource;
import egovframework.com.cmm.EgovWebUtil;
import egovframework.com.cmm.LoginVO;
import egovframework.com.cmm.service.EgovFileMngService;
import egovframework.com.cmm.service.EgovFileMngUtil;
import egovframework.com.cmm.service.FileVO;
import egovframework.com.cmm.util.EgovUserDetailsHelper;
import egovframework.com.cmm.util.EgovXssChecker;

//import egovframework.blog.service.Blog;//관리는 제외 : 블로그게시판 관리를 위한 모델 클래스
//import egovframework.blog.service.BlogVO;//관리는 제외 : 커뮤니티 관리를 위한 VO 클래스
import egovframework.blog.service.Board;//게시물에 대한 데이터 처리 모델
//import egovframework.blog.service.BoardMaster;//관리는 제외 : 게시판 속성정보를 담기위한 엔티티 클래스
//import egovframework.blog.service.BoardMasterVO;//관리는 제외 : 게시판 속성 정보를 관리하기 위한 VO  클래스
import egovframework.blog.service.BoardVO;//게시물 관리를 위한 VO 클래스
import egovframework.blog.service.BlogArticleService;
//import egovframework.blog.service.EgovBBSMasterService; // 관리자는 제외
//import egovframework.blog.service.EgovBBSSatisfactionService;// 만족도 제외

import egovframework.com.cop.cmt.service.CommentVO;
import egovframework.com.cop.cmt.service.EgovArticleCommentService;
import egovframework.com.cop.cmy.service.CommunityVO;
import egovframework.com.cop.tpl.service.EgovTemplateManageService;
import egovframework.com.cop.tpl.service.TemplateInfVO;
import egovframework.rte.fdl.property.EgovPropertyService;
import egovframework.rte.fdl.string.EgovStringUtil;
import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;

/**
 * 게시물 관리를 위한 컨트롤러 클래스
 * @author 공통서비스개발팀 이삼섭
 * @since 2009.06.01
 * @version 1.0
 * @see
 *
 * 
 * << 개정이력(Modification Information) >>
 *   
 *   수정일      수정자           수정내용
 *  -------       --------    ---------------------------
 *   2009.3.19  이삼섭          최초 생성
 *   2009.06.29	한성곤			2단계 기능 추가 (댓글관리, 만족도조사)
 *   2011.07.01 안민정		 	댓글, 스크랩, 만족도 조사 기능의 종속성 제거
 *   2011.8.26	정진오			IncludedInfo annotation 추가
 *   2011.09.07 서준식           유효 게시판 게시일 지나도 게시물이 조회되던 오류 수정
 *   2016.06.13 김연호			표준프레임워크 3.6 개선
 * 

 */

@Controller
public class BlogController {

private static final Logger LOGGER = LoggerFactory.getLogger(BlogController.class);

@Resource(name = "BlogArticleService")
    private BlogArticleService blogArticleService;
//
//    @Resource(name = "EgovBBSMasterService")
//    private EgovBBSMasterService egovBBSMasterService;
//
//    @Resource(name = "EgovFileMngService")
//    private EgovFileMngService fileMngService;
//
//    @Resource(name = "EgovFileMngUtil")
//    private EgovFileMngUtil fileUtil;
//
    @Resource(name = "propertiesService")
    protected EgovPropertyService propertyService;
//    
    @Resource(name="egovMessageSource")
    EgovMessageSource egovMessageSource;
//    
    @Resource(name = "EgovArticleCommentService")
    protected EgovArticleCommentService egovArticleCommentService;
//
//    @Resource(name = "EgovBBSSatisfactionService")
//    private EgovBBSSatisfactionService bbsSatisfactionService;
//
@Resource(name = "EgovTemplateManageService")
private EgovTemplateManageService egovTemplateManageService;
//    
//    @Autowired
//    private DefaultBeanValidator beanValidator;

    //protected Logger log = Logger.getLogger(this.getClass());
    
    /**
     * XSS 방지 처리.
     * 
     * @param data
     * @return
     */
    protected String unscript(String data) {
        if (data == null || data.trim().equals("")) {
            return "";
        }
        
        String ret = data;
        
        ret = ret.replaceAll("<(S|s)(C|c)(R|r)(I|i)(P|p)(T|t)", "<script");
        ret = ret.replaceAll("</(S|s)(C|c)(R|r)(I|i)(P|p)(T|t)", "</script");
        
        ret = ret.replaceAll("<(O|o)(B|b)(J|j)(E|e)(C|c)(T|t)", "<object");
        ret = ret.replaceAll("</(O|o)(B|b)(J|j)(E|e)(C|c)(T|t)", "</object");
        
        ret = ret.replaceAll("<(A|a)(P|p)(P|p)(L|l)(E|e)(T|t)", "<applet");
        ret = ret.replaceAll("</(A|a)(P|p)(P|p)(L|l)(E|e)(T|t)", "</applet");
        
        ret = ret.replaceAll("<(E|e)(M|m)(B|b)(E|e)(D|d)", "<embed");
        ret = ret.replaceAll("</(E|e)(M|m)(B|b)(E|e)(D|d)", "<embed");
        
        ret = ret.replaceAll("<(F|f)(O|o)(R|r)(M|m)", "<form");
        ret = ret.replaceAll("</(F|f)(O|o)(R|r)(M|m)", "<form");

        return ret;
    }

    /**
     * 게시물에 대한 목록을 조회한다.
     * 
     * @param boardVO
     * @param sessionVO
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/blog/selectArticleList.do")
    public String selectArticleList(@ModelAttribute("searchVO") BoardVO boardVO, ModelMap model) throws Exception {
LoginVO user = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();

Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated(); //KISA 보안취약점 조치 (2018-12-10, 이정은)

        if(!isAuthenticated) {
            return "egovframework/com/uat/uia/EgovLoginUsr";
        }

        boardVO.setBbsId(boardVO.getBbsId());
        boardVO.setBbsNm(boardVO.getBbsNm());
boardVO.setPageUnit(propertyService.getInt("pageUnit"));
boardVO.setPageSize(propertyService.getInt("pageSize"));

PaginationInfo paginationInfo = new PaginationInfo();

paginationInfo.setCurrentPageNo(boardVO.getPageIndex());
paginationInfo.setRecordCountPerPage(boardVO.getPageUnit());
paginationInfo.setPageSize(boardVO.getPageSize());

boardVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
boardVO.setLastIndex(paginationInfo.getLastRecordIndex());
boardVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

Map<String, Object> map = blogArticleService.selectArticleList(boardVO);
int totCnt = Integer.parseInt((String)map.get("resultCnt"));

//공지사항 추출
List noticeList = blogArticleService.selectNoticeArticleList(boardVO);

paginationInfo.setTotalRecordCount(totCnt);

if(user != null) {
     model.addAttribute("sessionUniqId", user.getUniqId());
    }

model.addAttribute("resultList", map.get("resultList"));
model.addAttribute("resultCnt", map.get("resultCnt"));
model.addAttribute("articleVO", boardVO);
model.addAttribute("bbsNm", "Custom Blog Sample");
model.addAttribute("bbsId", "BBSMSTR_000000000002");// 블로그는 1개만 운영하므로 생성된 블로그의 bbsId 사용-- 나중에 property로
model.addAttribute("bbsTmplatCours", "/css/egovframework/com/cop/tpl/egovBaseTemplate.css");//기본 BBS template 지정 : css 경로. 추후 변경
model.addAttribute("paginationInfo", paginationInfo);
model.addAttribute("noticeList", noticeList);
return "egovframework/com/blog/BlogArticleList";
    }
    
    
    
    /**
     * 게시물에 대한 상세 정보를 조회한다.
     * 
     * @param boardVO
     * @param sessionVO
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/blog/selectArticleDetail.do")
    public String selectArticleDetail(@ModelAttribute("searchVO") BoardVO boardVO, ModelMap model) throws Exception {
LoginVO user = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();


boardVO.setLastUpdusrId(user.getUniqId());
BoardVO vo = blogArticleService.selectArticleDetail(boardVO);

model.addAttribute("result", vo);
model.addAttribute("sessionUniqId", user.getUniqId());

//비밀글은 작성자만 볼수 있음 
if(!EgovStringUtil.isEmpty(vo.getSecretAt()) && vo.getSecretAt().equals("Y") && !user.getUniqId().equals(vo.getFrstRegisterId()))
return"forward:/blog/selectArticleList.do";

//----------------------------
// template 처리 (기본 BBS template 지정  포함)
//----------------------------
model.addAttribute("bbsTmplatCours", "/css/egovframework/com/cop/tpl/egovBaseTemplate.css");//기본 BBS template 지정 : css 경로. 추후 변경

////-----------------------------
if (egovArticleCommentService != null){
if (egovArticleCommentService.canUseComment(boardVO.getBbsId())) {
    model.addAttribute("useComment", "true");
}
}
////--------------------------

model.addAttribute("bbsId", "BBSMSTR_000000000002");// 블로그는 1개만 운영하므로 생성된 블로그의 bbsId 사용-- 나중에 property로

return "egovframework/com/blog/BlogArticleDetail";
    }


    

    
    /*********************
     * 블로그관련
     * ********************/
    
    
    /**
     * 블로그 게시물에 대한 상세 타이틀을 조회한다.
     * 
     * @param boardVO
     * @param sessionVO
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/blog/selectArticleBlogDetail.do")
    public ModelAndView selectArticleBlogDetail(@ModelAttribute("searchVO") BoardVO boardVO, ModelMap model) throws Exception {
LoginVO user = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();


BoardVO vo = new BoardVO();

boardVO.setPageUnit(propertyService.getInt("pageUnit"));
boardVO.setPageSize(propertyService.getInt("pageSize"));

PaginationInfo paginationInfo = new PaginationInfo();

paginationInfo.setCurrentPageNo(boardVO.getPageIndex());
paginationInfo.setRecordCountPerPage(boardVO.getPageUnit());
paginationInfo.setPageSize(boardVO.getPageSize());

boardVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
boardVO.setLastIndex(paginationInfo.getLastRecordIndex());
boardVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

List blogSubJectList = blogArticleService.selectArticleDetailDefault(boardVO);
vo = blogArticleService.selectArticleCnOne(boardVO);

int totCnt = blogArticleService.selectArticleDetailDefaultCnt(boardVO);
paginationInfo.setTotalRecordCount(totCnt);

ModelAndView mav = new ModelAndView("jsonView");
mav.addObject("blogSubJectList", blogSubJectList);
mav.addObject("paginationInfo", paginationInfo);

if(vo.getNttCn() != null){
mav.addObject("blogCnOne", vo);
}

//비밀글은 작성자만 볼수 있음 
if(!EgovStringUtil.isEmpty(vo.getSecretAt()) && vo.getSecretAt().equals("Y") && !user.getUniqId().equals(vo.getFrstRegisterId()))
mav.setViewName("forward:/blog/selectArticleList.do");
return mav;
    }
    
    /**
     * 블로그 게시물에 대한 상세 내용을 조회한다.
     * 
     * @param boardVO
     * @param sessionVO
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/blog/selectArticleBlogDetailCn.do")
    public ModelAndView selectArticleBlogDetailCn(@ModelAttribute("searchVO") BoardVO boardVO, @ModelAttribute("commentVO") CommentVO commentVO, ModelMap model) throws Exception {
LoginVO user = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();

boardVO.setLastUpdusrId(user.getUniqId());

Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated(); //KISA 보안취약점 조치 (2018-12-10, 이정은)

        if(!isAuthenticated) {
         throw new IllegalAccessException("Login Required!");
        }

BoardVO vo = blogArticleService.selectArticleDetail(boardVO);

//----------------------------
// 댓글 처리
//----------------------------
CommentVO articleCommentVO = new CommentVO();
commentVO.setWrterNm(user.getName());

PaginationInfo paginationInfo = new PaginationInfo();
paginationInfo.setCurrentPageNo(commentVO.getSubPageIndex());
paginationInfo.setRecordCountPerPage(commentVO.getSubPageUnit());
paginationInfo.setPageSize(commentVO.getSubPageSize());

commentVO.setSubFirstIndex(paginationInfo.getFirstRecordIndex());
commentVO.setSubLastIndex(paginationInfo.getLastRecordIndex());
commentVO.setSubRecordCountPerPage(paginationInfo.getRecordCountPerPage());

Map<String, Object> map = egovArticleCommentService.selectArticleCommentList(commentVO);
int totCnt = Integer.parseInt((String)map.get("resultCnt"));

paginationInfo.setTotalRecordCount(totCnt);

    //댓글 처리 END
//----------------------------

List blogCnList = blogArticleService.selectArticleDetailCn(boardVO);
ModelAndView mav = new ModelAndView("jsonView");

// 수정 처리된 후 댓글 등록 화면으로 처리되기 위한 구현
if (commentVO.isModified()) {
    commentVO.setCommentNo("");
    commentVO.setCommentCn("");
}

// 수정을 위한 처리
if (!commentVO.getCommentNo().equals("")) {
mav.setViewName ("forward:/cop/cmt/updateArticleCommentView.do");
}

mav.addObject("blogCnList", blogCnList);
mav.addObject("resultUnder", vo);
mav.addObject("paginationInfo", paginationInfo);
mav.addObject("resultList", map.get("resultList"));
mav.addObject("resultCnt", map.get("resultCnt"));
mav.addObject("articleCommentVO", articleCommentVO); // validator 용도

commentVO.setCommentCn(""); // 등록 후 댓글 내용 처리

//비밀글은 작성자만 볼수 있음 
if(!EgovStringUtil.isEmpty(vo.getSecretAt()) && vo.getSecretAt().equals("Y") && !user.getUniqId().equals(vo.getFrstRegisterId()))
mav.setViewName("forward:/blog/selectArticleList.do");
return mav;

    }
    


  
        
    
}

 

2. JSP 등 클라이언트단

com.cop.bbs에 있는 com.blog관련파일을 blog폴더로 복사하여 사용

3. properties

resources의 message를 blog폴도 아래에도 생성.
com.cop.bbs property 말고 com.cop.blog property를 복사한다

그리고는 경로를 새로 생성한 경로로 호출해본다.

--localhost:8080/egovframework-all-in-one/blog/selectArticleList.do

일단 화면은 나온다.

이제 뭐가 문제인지 따져보자 ㅎ

Controller 안에 method마다 있는 login 관련로직은 모두 제거한다.
모든 사용자가 볼 수 있으므로

LoginVO user = (LoginVO)EgovUserDetailsHelper.getAuthenticatedUser();

Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
        if(!isAuthenticated) {
            return "egovframework/com/uat/uia/EgovLoginUsr";
        }
728x90

전자정부 프레임워크의 게시판 등 템플릿으로 설정해 둔 뒤
설정한 템플릿으로 적용이 가능하다.

협업 > 템플릿관리

css 파일 경로 : main > webapp > css >  에 있어야 하는데
기본으로 있는 템플릿 목록의 egovbbsTemplate.css 는 없네?

jsp 파일 경로로 WEB-INF/jsp/egovframework/com/cop/tpl/EgovClbBaseTmpl.jsp .

 

참고할만한 Tmpl파일을 복사하여 수정한 뒤 등록.

등록결과

728x90

새로운 블로그를 만들어 보자

http://localhost:8080/egovframework-all-in-one/ 에서
업무사용자 선택
로그인 : TEST1
PW : 공통12

로그인 한 뒤에 협업 > 블로그 관리
처음이라 블로그가 없음.
등록버튼을 누른다.

등록하기
블로그명 : 샘플블로그
블로그 소개내용 : 처음 만든 블로그

등록 결과
등록한 블로그명과 설명이 나옴

게시글을 등록하려고 등록버튼을 누르면
게시판(카테고리)를 먼저 등록해야한다는 알림이 나옴

카테고리 등록
실제로는 게시판이지만. 블로그에서는 카테고리라고 한다.
게시판명 : 블로그게시판1
게시판 소개내용 : 블로그 게시판으로 사용
게시판 유형 : 블로그형게시판
.. 항목들을 채운 뒤 등록버튼을 누른다.

카테고리 추가 완료를 하면
생성한블로그가 표시되면서 게시글이 없다는 알림이 뜸
이제 등록버튼으로 게시글 등록을 한다.

게시글 등록
제목 : 블로그 게시글 1
내용 : 첫번째 게시글
입력 후 등록버튼을 누르면

블로그 완성

 

개인블로그 관리
여러 블로그 또는 게시판을 관리

해당 게시판(블로그게시판1)을 클릭하면 상세내용이 나옴

728x90

Spring Boot를 이용하여 Login까지 간단히 끝냄. Maven버전이 아닌 Gradle 버전으로 남김

1. 새로운 프로젝트 생성
   - Type : Gradle 로 선택(필수)

2. Next 버튼 누른 후 Dependency 설정
   - 이전에 사용했던 항목이 있으면 Frequently Used 로 바로 보임. 체크를 하면 됨
   - 없으면 왼쪽 하단 부분에서 찾아(세모 클릭하면 펼쳐짐) 체크
   - 선택된 dependencies는 오른쪽 하단에 Selected 로 표시 됨

 

3.프로젝트 구조
   - 파일 위치 및 파일명 참조

4. Build.gradle 확인
   - dependencies 에서 implementation은 선택한 항목-
   - commons-beanutils 를 추가함.

-- jquery, bootstrap 추가

https://www.webjars.org/ 에서 해당 버전에 맞게 찾아옴
   - Build Tool 에서 해당 Tool 선택
   - 사용할 jar 의 추가방법 복사 : compile 'org.webjars:jquery:3.4.1'

-- 추가한 build.gradle

5. DB 연결 : src/main/resources 아래에 application.properties
   - server 포트 변경할 때 사용. 기본값은 8080이므로 변경할 때만 추가
   - mysql 설정에 localhost:3306 뒤에 연결할 db명을 적고 username, password
   - JPA를 사용하므로 hibernate.dll-auto=create 으로 추가

6. db script
  - mysql 을 사용하는 경우 id column에 PK, Auto_increment 속성을 넣는다.
  - oracle을 사용하는 경우에는 auto_increment 는 필요없다(별도의 sequence 사용)

   - key 정보를 잘못 설정한 경우 : table 생성 후 auto_increment 를 추가하려고 하면 foreign key가 있다고 오류남
     Key 삭제 후 다시 만들어야 함. table drop 이후에는... 애매해 짐

# unique key 삭제 및 생성
drop index 유니크키명 on 테이블명;
create unique index  유니크키명 on 테이블명 (컬럼명, 컬럼명);


# type이 innodb일 경우에는 unique key 삭제 하기전에 foreign key를 삭제해야 한다.
alter table 테이블명 drop foreign key 포린키명;
drop index 유니크키명 on 테이블명;


# innodb 타입 foreing key 재생성
alter table 테이블명 add CONSTRAINT 포린키명  foreign key (컬럼명) references 디비명 (컬럼명) on delete cascade;7. 미리보기
   - build.gradle에서 bootstrap, jquery를 추가하지 않은 경우
   - 개발자 모드로 확인시 script 오류가 확인 됨.

   - 추가 후

 

source

- UserRegistrationDto : package com.nobang.sample.web.dto

import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;

import com.nobang.sample.constraint.FieldMatch;



@FieldMatch.List({
    @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match"),
    @FieldMatch(first = "email", second = "confirmEmail", message = "The email fields must match")
})
public class UserRegistrationDto {

    @NotEmpty
    private String firstName;

    @NotEmpty
    private String lastName;

    @NotEmpty
    private String password;

    @NotEmpty
    private String confirmPassword;

    @Email
    @NotEmpty
    private String email;

    @Email
    @NotEmpty
    private String confirmEmail;

    @AssertTrue
    private Boolean terms;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getConfirmPassword() {
        return confirmPassword;
    }

    public void setConfirmPassword(String confirmPassword) {
        this.confirmPassword = confirmPassword;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getConfirmEmail() {
        return confirmEmail;
    }

    public void setConfirmEmail(String confirmEmail) {
        this.confirmEmail = confirmEmail;
    }

    public Boolean getTerms() {
        return terms;
    }

    public void setTerms(Boolean terms) {
        this.terms = terms;
    }
}

 

- SampleUser : package com.nobang.sample.model

import javax.persistence.*;
import java.util.Collection;

@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class SampleUser {

    @Id
//    @GeneratedValue(strategy = GenerationType.AUTO) // ORACLE
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String firstName;
    private String lastName;
    private String email;
    private String password;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(
        name = "sample_users_roles",
        joinColumns = @JoinColumn(
            name = "user_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(
            name = "role_id", referencedColumnName = "id"))
    private Collection < SampleRole > roles;

    public SampleUser() {}

    public SampleUser(String firstName, String lastName, String email, String password) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
    }

    public SampleUser(String firstName, String lastName, String email, String password, Collection < SampleRole > roles) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
        this.roles = roles;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Collection < SampleRole > getRoles() {
        return roles;
    }

    public void setRoles(Collection < SampleRole > roles) {
        this.roles = roles;
    }

    @Override
    public String toString() {
        return "User{" +
            "id=" + id +
            ", firstName='" + firstName + '\'' +
            ", lastName='" + lastName + '\'' +
            ", email='" + email + '\'' +
            ", password='" + "*********" + '\'' +
            ", roles=" + roles +
            '}';
    }
}

 

- SampleRole : package com.nobang.sample.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class SampleRole {

    @Id
//    @GeneratedValue(strategy = GenerationType.AUTO) // ORACLE
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    public SampleRole() {}

    public SampleRole(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Role{" +
            "id=" + id +
            ", name='" + name + '\'' +
            '}';
    }
}

 

- UserRepository : package com.nobang.sample.repository;

@Repository
public interface UserRepository extends JpaRepository < SampleUser, Long > {
    SampleUser findByEmail(String email);
}

참고 : JPA에서 기본으로 제공하는 method

- FieldMatch : package com.nobang.sample.constraint;

import javax.validation.Payload;
import javax.validation.Constraint;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({
    TYPE,
    ANNOTATION_TYPE
})
@Retention(RUNTIME)
@Constraint(validatedBy = FieldMatchValidator.class)
@Documented
public @interface FieldMatch {
//    String message() default "{constraints.field-match}";
//    Class << ? > [] groups() default {};
//    Class << ? extends Payload > [] payload() default {};
    
    String message() default "{constraints.fieldmatch}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};    
    
    String first();
    String second();

    @Target({
        TYPE,
        ANNOTATION_TYPE
    })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        FieldMatch[] value();
    }
}

 

- FieldMatchValidator : package com.nobang.sample.constraint;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.apache.commons.beanutils.BeanUtils;

public class FieldMatchValidator implements ConstraintValidator < FieldMatch, Object > {

    private String firstFieldName;
    private String secondFieldName;

    @Override
    public void initialize(final FieldMatch constraintAnnotation) {
        firstFieldName = constraintAnnotation.first();
        secondFieldName = constraintAnnotation.second();
    }

    @Override
    public boolean isValid(final Object value, final ConstraintValidatorContext context) {
        try {
            final Object firstObj = BeanUtils.getProperty(value, firstFieldName);
            final Object secondObj = BeanUtils.getProperty(value, secondFieldName);
            return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj);
        } catch (final Exception ignore) {}
        return true;
    }
}

 

- UserService : package com.nobang.sample.service;

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

import com.nobang.sample.model.SampleUser;
import com.nobang.sample.web.dto.UserRegistrationDto;


public interface UserService extends UserDetailsService {

    SampleUser findByEmail(String email);

    SampleUser save(UserRegistrationDto registration);
}

- UserServiceImpl : package com.nobang.sample.service;

import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.nobang.sample.model.SampleRole;
import com.nobang.sample.model.SampleUser;
import com.nobang.sample.repository.UserRepository;
import com.nobang.sample.web.dto.UserRegistrationDto;



@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    public SampleUser findByEmail(String email) {
        return userRepository.findByEmail(email);
    }

    public SampleUser save(UserRegistrationDto registration) {
        SampleUser user = new SampleUser();
        user.setFirstName(registration.getFirstName());
        user.setLastName(registration.getLastName());
        user.setEmail(registration.getEmail());
        user.setPassword(passwordEncoder.encode(registration.getPassword()));
        user.setRoles(Arrays.asList(new SampleRole("ROLE_USER")));
        return userRepository.save(user);
    }

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        SampleUser user = userRepository.findByEmail(email);
        if (user == null) {
            throw new UsernameNotFoundException("Invalid username or password.");
        }
        return new org.springframework.security.core.userdetails.User(user.getEmail(),
            user.getPassword(),
            mapRolesToAuthorities(user.getRoles()));
    }

//    private Collection << ? extends GrantedAuthority > mapRolesToAuthorities(Collection < Role > roles) {
//        return roles.stream()
//            .map(role - > new SimpleGrantedAuthority(role.getName()))
//            .collect(Collectors.toList());
//    }
    
    private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection roles){
        return roles.stream()
                .map(role -> new SimpleGrantedAuthority(role.getName()))
                .collect(Collectors.toList());
    }
}

 

- SecurityConfiguration : package com.nobang.sample.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.nobang.sample.service.UserService;

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers(
                "/registration**",
                "/js/**",
                "/css/**",
                "/img/**",
                "/webjars/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
            .logout()
            .invalidateHttpSession(true)
            .clearAuthentication(true)
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login?logout")
            .permitAll();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
        auth.setUserDetailsService(userService);
        auth.setPasswordEncoder(passwordEncoder());
        return auth;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }
}

 

- MainController : package com.nobang.sample.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MainController {

    @GetMapping("/")
    public String root() {
        return "index";
    }

    @GetMapping("/login")
    public String login(Model model) {
        return "login";
    }

    @GetMapping("/user")
    public String userIndex() {
        return "user/index";
    }
}

 

- UserRegistrationController :

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.nobang.sample.model.SampleUser;
import com.nobang.sample.service.UserService;
import com.nobang.sample.web.dto.UserRegistrationDto;



@Controller
@RequestMapping("/registration")
public class UserRegistrationController {

    @Autowired
    private UserService userService;

    @ModelAttribute("user")
    public UserRegistrationDto userRegistrationDto() {
        return new UserRegistrationDto();
    }

    @GetMapping
    public String showRegistrationForm(Model model) {
        return "registration";
    }

    @PostMapping
    public String registerUserAccount(@ModelAttribute("user") @Valid UserRegistrationDto userDto,
        BindingResult result) {

        SampleUser existing = userService.findByEmail(userDto.getEmail());
        if (existing != null) {
            result.rejectValue("email", null, "There is already an account registered with that email");
        }

        if (result.hasErrors()) {
            return "registration";
        }

        userService.save(userDto);
        return "redirect:/registration?success";
    }
}

 

참조 : https://www.javaguides.net/2019/02/spring-mvc-5-spring-security-5-hibernate-5-mysql.html

728x90
BLOG main image
"그게 뭐 어쨌다는 거냐?" 늘 누가 나에게 나에대한 말을할 때면 이말을 기억해라. by nobang

카테고리

nobang이야기 (1933)
Life With Gopro (7)
Life With Mini (79)
Diary (971)
너 그거 아니(do you know) (162)
난 그래 (159)
Study (290)
속지말자 (10)
Project (34)
Poem (15)
Song (0)
Photo (113)
낙서장 (45)
일정 (0)
C.A.P.i (2)
PodCast (0)
nobang (27)
고한친구들 (4)
recieve (0)
History (0)
android_app (2)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

Total :
Today : Yesterday :