<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>one_2s</title>
        <link>https://velog.io/</link>
        <description>코딩 일기장</description>
        <lastBuildDate>Wed, 11 May 2022 15:40:46 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>one_2s</title>
            <url>https://images.velog.io/images/one_2s/profile/cd23b339-6a08-47d8-89c9-3afb0258c7f0/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. one_2s. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/one_2s" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[스프링 시큐리티 권한별 어노테이션 설정]]></title>
            <link>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EA%B6%8C%ED%95%9C%EB%B3%84-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EA%B6%8C%ED%95%9C%EB%B3%84-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Wed, 11 May 2022 15:40:46 GMT</pubDate>
            <description><![CDATA[<p>스프링 시큐리티에서 자주 쓰는 표현식에 대해 보겠습니다.
조건식으로 사용하며 sec태그와 조합해 쓰는것이 특징입니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/897841fe-d262-4ea7-813c-08ae0b9ef89d/image.png" alt=""></p>
<p>/secu/all의 주소로 접속했을때 이제 로그인 안한 사용자에게는 로그인창 링크를, 그리고 로그인한 사용자에게는 로그아웃 링크를 보여주도록 코드를 위와 같이 고칩니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/a388245d-b7be-4dff-960f-d76602ee7236/image.png" alt="">
실행해보면
<img src="https://velog.velcdn.com/images/one_2s/post/5a23f0f4-a66b-4f3c-ace0-a9fbe10a887b/image.png" alt="">
로그인 한후
<img src="https://velog.velcdn.com/images/one_2s/post/a2b7d254-ac4f-4e87-8dd9-2d7c5b261eea/image.png" alt="">
/secu/all 들어가면 로그아웃을 볼수있고
로그아웃된 상태로 들어가게 되면
<img src="https://velog.velcdn.com/images/one_2s/post/3e7f5fbc-a63c-4782-967d-eaca3335c10b/image.png" alt="">
로그인을 볼수 있다. 
(sec:authorize 태그에 의해 조건식처럼 로그인한 사용자와 그렇지 않은 사용자가 보여지는 내용이 살짝 달라짐)</p>
<p>==
이제 자동로그인 기능을 구현해보겠습니다.
한 번 로그인하면 일정 시간동안 로그인로직 없이도 로그인유지가 되도록 만드는것으로 먼저 테이블을 추가합니다. 
(아래 테이블 양식으로 만드는게 스프링시큐리티의 공식 문저 권장사항)
<img src="https://velog.velcdn.com/images/one_2s/post/3e62f6f7-a187-48e6-a897-98b51005a01a/image.png" alt="">
테이블이 새로 생성되었다면
security-context.xml을 위와 같이 수정해줍니다. 
604800초 만큼 자동로그인이 유지되도록 해 주는것으로 설정은 자유
<img src="https://velog.velcdn.com/images/one_2s/post/da4afaa3-caa6-4dc3-82e2-8165810c19c1/image.png" alt=""></p>
<p>로그인 화면에 checkbox를 구현합니다.
name속성에는 remember-me를 주면 됩니다.
customLogin.jsp
<img src="https://velog.velcdn.com/images/one_2s/post/35509f67-3d9d-47d0-9bb6-9741f1bf090b/image.png" alt="">
로그인시 f12 -&gt; application-&gt;storage에서 세션발급여부를 검사하면 JSESSIONID에 이어서 remeber-me라는 쿠키가 추가로 발급되는것을 볼 수 있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/8c6b4db8-494c-4e17-8063-029e7f221f26/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/88edee5c-6ba7-4503-91f1-c98b196003d3/image.png" alt="">
그리고 DB쪽의 persistent_logins 테이블을 조회해보면
특정 유저의 마지막 접속 시점이 기록으로 자동기록 됩니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/747c68c4-0713-4306-bd90-9fb58821de09/image.png" alt="">
브라우저를 다 껏다 켜도 로그인이 유지되는지 
/secu/admindm으로 브라우저를 완전히 껏다가 접속해도 유지되면 성공.</p>
<p>== 
로그아웃시 remember-me 쿠키를 파기해야 합니다.
security-context.xml에 위와 같이 추가합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/5afbb580-4ade-4c80-a3a1-e6bae7d28c27/image.png" alt=""></p>
<p>==
모든 주소를 하나하나 security-context.xml에 security-intercept-url태그를 추가해 시큐리티를 적용하는 것은 복잡하고 관리도 어려운 일입니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/101c70f0-d798-428a-bf42-2b304d5d2553/image.png" alt=""></p>
<p>따라서 이제는 <strong>어노테이션으로 처리하는 방법</strong>에 대해 배워봅니다. </p>
<p>먼저 servlie-context.xml의Namespace탭에서 security를 체크해줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/c6ae820f-3c37-4eae-8dfb-44d4cd208e1b/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/3993ed8c-6af4-4783-a275-9c3fc521203b/image.png" alt=""></p>
<p>servlet-context.xml에도 역시 -5.0을 제거
<img src="https://velog.velcdn.com/images/one_2s/post/56622dd5-4f62-4327-a720-3c7b58b7bc92/image.png" alt="">
제거가 완료 되었다면 security:global-method-security태그를 추가하고 아래 두속성을 모두 enabled로 고쳐줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/6cf208f9-bb66-4b37-a61d-0f3784692c81/image.png" alt=""></p>
<p>이제 security-context.xml내부의 security:intercept-url을 주석처리하면 검증요건 없이 접속이 잘 되는걸 확인할 수 있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/101c70f0-d798-428a-bf42-2b304d5d2553/image.png" alt=""></p>
<p>실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/c5746c54-b6b9-4d94-9873-e4bbeef89a70/image.png" alt="">
멤버주소로 들어가지는걸 확인할 수 있습니다. </p>
<p>SecurityController로 와서, /member와 /admin 패턴에 위와 같이 @PreAuthorize 어노테이션과 표현식을 추가합니다.
<img src="https://velog.velcdn.com/images/one_2s/post/d53bc6e6-affa-4daf-99f8-0ba3c6f23124/image.png" alt="">
실행해보면
/secu/member아까와 달리 로그인창이 뜨는걸 확인할수 있습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/11a3fd44-8816-46cf-bb4e-a05b7ac0ba03/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/10c74f69-2779-47d4-b9c8-42dc6a713bed/image.png" alt="">
로그인후 /secu/member 로 user0으로 들어가면 접근실패가 뜹니다.
<img src="https://velog.velcdn.com/images/one_2s/post/d494f8c0-cb06-4fd4-a210-1c5cd0fb679c/image.png" alt="">
/secu/all로 들어가면 접근이 허용되는걸 확인할 수 있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/a391b8d8-8e87-4148-976b-9f927ee34e7a/image.png" alt=""></p>
<p>--
member페이지에 관리자페이지로 가기버튼을
관리자 한정으로 볼 수 있게 처리
<img src="https://velog.velcdn.com/images/one_2s/post/80bc1f0b-4698-4942-bf9c-60bc5c8235fc/image.png" alt=""></p>
<p>실행하면
/secu/member
user0 pw0 로그인
<img src="https://velog.velcdn.com/images/one_2s/post/ca0337aa-81ff-4c0a-b6ea-4b893499541d/image.png" alt="">
/secu/member
user15 pw15 로그인
<img src="https://velog.velcdn.com/images/one_2s/post/d887ea83-cc1b-4961-9920-78abfa9b751d/image.png" alt="">
/secu/member
user22 pw22 로그인
<img src="https://velog.velcdn.com/images/one_2s/post/66c2202e-f70d-4f5a-be3b-197ad71e8c13/image.png" alt="">
관리자여서 멤버 주소로 접속했을시 관리자페이지로가기가 보인다. </p>
<p>==
회원가입
회원가입은 SecurityController에 /secu/join주소로 처리합니다. get방식으로 폼연결, post방식으로 가입처리를 합니다.
암호화를 위해 PasswordEncoder도 넣어준다. 
<img src="https://velog.velcdn.com/images/one_2s/post/b07b0723-9593-402f-964e-ed2c8954bc17/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/14147535-649e-44b1-92a8-41a70429c87f/image.png" alt="">
join jspfile를 만들어주고
<img src="https://velog.velcdn.com/images/one_2s/post/32162225-9ac9-48ff-b3e5-b99ab9344497/image.png" alt="">
 아이디, 비밀번호, 이름은 MemberVO 변수이름과 member_tbl 
컬럼명을 감안해 name속성을 주고
권한은 여러개를 동시에 주기 위해 role이라는 이름으로 체크박스 처리합니다.
스프링 시큐리티 적용 프로젝트에서는 폼에 csrf토큰을 포함해 보내야 합니다.
<img src="https://velog.velcdn.com/images/one_2s/post/69534005-7ac0-4594-bf0c-678e7b21a0d3/image.png" alt=""></p>
<p>실행해보면
/secu/join
<img src="https://velog.velcdn.com/images/one_2s/post/327e4a0b-5464-4892-89d4-150cfdf52814/image.png" alt="">
가입하기를 누르면
<img src="https://velog.velcdn.com/images/one_2s/post/99b4d539-63ea-4204-81d0-7473a5b6e143/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 시큐리티DB연동 완료 및 principle조회]]></title>
            <link>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0DB%EC%97%B0%EB%8F%99-%EC%99%84%EB%A3%8C-%EB%B0%8F-principle%EC%A1%B0%ED%9A%8C-npg1gayf</link>
            <guid>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0DB%EC%97%B0%EB%8F%99-%EC%99%84%EB%A3%8C-%EB%B0%8F-principle%EC%A1%B0%ED%9A%8C-npg1gayf</guid>
            <pubDate>Wed, 11 May 2022 13:26:56 GMT</pubDate>
            <description><![CDATA[<p>이제 처리된 Member관련 테이블을 Mybatis로 처리해보겠습니다. 
com.ict.mapper 패키지 내에 MemberMapper인터페이스와 xml을 같이 만들겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/9ba3221a-dcca-4b0d-a8d3-f6e37db18c88/image.png" alt="">
MemberMapper인터페이스
<img src="https://velog.velcdn.com/images/one_2s/post/9b458657-fc43-4566-b431-5bdf1aabcafd/image.png" alt="">
MemberMapper.xml
상단의 
<img src="https://velog.velcdn.com/images/one_2s/post/038b7526-5b75-43a6-bbd9-0fb3fc39e438/image.png" alt="">
작성해주고
<img src="https://velog.velcdn.com/images/one_2s/post/470612e8-c833-46de-a160-19e3674d9695/image.png" alt="">
ResultMap은 기존 컬럼명과 VO의 변수명이 다르거나 혹은 구조가 달라질 때 (지금 같은경우 List AuthVO&gt;는 두 개 이상이 들어올 수 있습니다.) 처리할 구조에 대해 미리 설정해두는 태그입니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/ea423d69-8e2b-42a9-a2ce-6220fe21c460/image.png" alt="">
이제 MemberMapper를 계정명으로 집어넣으면 계정관련 정보가 정확하게 나오는지 테스트코드로 확인해보겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/13d2316e-c65f-486c-be66-ec7d3b26fd8e/image.png" alt="">
실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/8befd52f-10b7-4d8f-8604-c726b4518ec7/image.png" alt="">
초록불이 들어오면서 정보를 확인하면 성공입니다!</p>
<p>이제 받아온 MemberMapper의 데이터를 스프링 시큐리티에서 처리할 수 있도록 커스터마이징 해보겠습니다.
com.ict.security에 CustomUserDetailService를 만들고 UserDetailService를 implements 해줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/14158d39-6f16-4205-be31-90a212aff71e/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/24137e98-863d-4851-962c-4e7db2afea69/image.png" alt=""></p>
<p>security-context.xml에는 CustomUserDetailService를 빈컨테이너에 넣어주고, 그걸 이용해 로그인하도록 바꿔줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/74781b37-c112-4a8b-8c21-c4f275ddefe1/image.png" alt="">
실행했을때
<img src="https://velog.velcdn.com/images/one_2s/post/496f9eab-f14e-4627-ba14-6f17700373f9/image.png" alt="">
콘솔창에
<img src="https://velog.velcdn.com/images/one_2s/post/be0d091f-dccf-4584-adf7-604653defc98/image.png" alt="">
 InternalAuthenticationServiceException이 나온다면 제대로 작동한 것입니다. 
저렇게 나오는 이유는 UserDetails를 리턴하기로 해놓고 null을 리턴하고 있어서 입니다. </p>
<p>그럼 이제 로그인 로직에서 MemberVO를 UserDetails로 바꾸도록 처리하겠습니다.
User를 상속한 CustomUser를 먼저 만들겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/24eb5bb0-269d-44be-8bf5-142e11eca844/image.png" alt=""></p>
<p>이제 MemberVO가 입력되면 CustomUser의 생성자를 이용해 vo를 변환할수 있고, CustomUser클래스는 User를 상속받았는데, User는 다시 스프링 시큐리티에서 사용하는 UserDetail을 상속받은 상태입니다. 따라서 MemberVO를 스프링 시큐리티에서 쓸 수 있게 수정한 것입니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/ea24abae-4eed-48a0-8af5-67abcf151237/image.png" alt=""></p>
<p>스프링 시큐리티 심화
기초적인 내용을 배웠다면 이제는 실질적으로 내가 만든 웹사이트에 스프링 시큐리티를 적용하는 방법을 배워보겠습니다. 
먼저, jsp에서 스프링 시큐리티 옵션을 쓰는 법을 배워본 다음, 자동로그인 체크와 어노테이션을 이용한 적용까지 배우면
웹 사이트에 스프링 시큐리티를 좀 더 편하게 적용할 수 있습니다. </p>
<p>먼저 admin.jsp파일 내부에서 sec태그를 사용해보겠습니다.
c태그 라이브러리 처리 taglib설정을 해주면 됩니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링시큐리티 기본로그인 완료, 커스텀 디비 처리 1]]></title>
            <link>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EA%B8%B0%EB%B3%B8%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%99%84%EB%A3%8C-%EC%BB%A4%EC%8A%A4%ED%85%80-%EB%94%94%EB%B9%84-%EC%B2%98%EB%A6%AC-1</link>
            <guid>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EA%B8%B0%EB%B3%B8%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%99%84%EB%A3%8C-%EC%BB%A4%EC%8A%A4%ED%85%80-%EB%94%94%EB%B9%84-%EC%B2%98%EB%A6%AC-1</guid>
            <pubDate>Wed, 11 May 2022 13:26:13 GMT</pubDate>
            <description><![CDATA[<p>로그아웃
security-context.xml에는 security:logout 태그를 사용하며, 로그아웃시 사용할 주소를 logout-url속성에 저장하고 invalidate-session 속성에 true줘서 로그아웃시 세션을 파기하게 합니다.
(security:http 내부에 작성해야 합니다. )
<img src="https://velog.velcdn.com/images/one_2s/post/b2d32001-717a-483f-a6e2-b3b76c376fde/image.png" alt=""></p>
<p>CommonController에는
이제 customLogout을 처리한느 폼으로 이동하는 메서드를 추가합니다. 
추가로 customLogout.jsp도 생성해줍니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 시큐리티 로그인 처리(커스텀 로그인, csrf토큰)]]></title>
            <link>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%B2%98%EB%A6%AC%EC%BB%A4%EC%8A%A4%ED%85%80-%EB%A1%9C%EA%B7%B8%EC%9D%B8-csrf%ED%86%A0%ED%81%B0</link>
            <guid>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%B2%98%EB%A6%AC%EC%BB%A4%EC%8A%A4%ED%85%80-%EB%A1%9C%EA%B7%B8%EC%9D%B8-csrf%ED%86%A0%ED%81%B0</guid>
            <pubDate>Sun, 08 May 2022 14:50:34 GMT</pubDate>
            <description><![CDATA[<p>커스텀 로그인 페이지를 써 보겠습니다. 
기존 로그인 페이지는 너무 다지인이 단순해 테스트 이상으로 쓰기는 어렵습니다. 
먼저 security-context.xml내부의 security:form의 속성을 변경해줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/5c443e2a-9bd9-48d1-8b51-f3a290671383/image.png" alt=""></p>
<p>그리고 CommonController에 새롭게 /customLogin을 주소로 하는 메서드를 만들고
에러로 접근했는지 로그앙수 상태로 접근했는지 구분하도록 사전세팅 합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/7ff91ebf-fc8b-4e54-90c7-d7d252c4af95/image.png" alt=""></p>
<p>views에는 customLogin.jsp를 준비합니다. 이 페이지는 어떻데 이 페이지오게 되었는지와, 로그인시 사용할 폼을 제공합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/24da471d-e5da-4feb-b466-90c767fb1ec6/image.png" alt=""></p>
<p>실행보면
<img src="https://velog.velcdn.com/images/one_2s/post/531dd0a6-58ac-4f79-a759-d791a1909453/image.png" alt="">
로그인을 하고 로그아웃후 (쿠키삭제후)
다시 로그인 페이지로 돌아가면
<img src="https://velog.velcdn.com/images/one_2s/post/b6d3b2c3-0714-4c7a-9320-5511dec2004c/image.png" alt="">
토큰 값이 계속 바뀌는걸 확인할 수 있다. </p>
<p>(csrf는 cross-site request forgery공격이라고 불리며, csrf검증로직이 없는 사이트는 form이나 img 태그 내부의 링크설정을 곧이곧대로 받아 처리하기 때문에 악의적으로 공격을 할 수 있게 됩니다.
scrf 토큰은 매번 value값이 바뀌고, hidden으로 포함되어 들아가기 때문에 공격자 입장에서는 고정된 쿼리문만 전송해서는 더이상 명령이 작동하지 않고 매번바뀌는 csrf토큰값을 그때그때 찍어서 맞춰야 사실상 완전방어가 됩니다. )</p>
<p>콘솔창을 확인해 보면
admin 페이지로 접속시
<img src="https://velog.velcdn.com/images/one_2s/post/73214a6b-81b2-4a09-baba-aa69b6937dbc/image.png" alt="">
admin으로 로그인
<img src="https://velog.velcdn.com/images/one_2s/post/e969b765-2e00-49e0-8d64-45d729b5a6f9/image.png" alt=""></p>
<p>member 페이지로 접속시 member로 로그인
<img src="https://velog.velcdn.com/images/one_2s/post/dd8a599f-45f7-49fc-b5ec-9d851be17509/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/9018533f-4b3b-4316-93fd-19d67e95732e/image.png" alt=""></p>
<p>로그인을 해보면 제대로 로그인시 제대로된 페이지가 나오고 아이디 비밀번호를 잘못 입력하면 에러페이지가 나옵니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/b9d41598-fffd-4d67-9596-7287210e4412/image.png" alt="">
다만, 권한검증 등의 로직이 확실하게 처리되지는 않습니다.</p>
<p>이제 로그인 성공을 처리해보도록 해보겠습니다.
AuthenticationSuccessHandler를 이용해서 처리합니다.
com.ict.security에 먼저 CustomLoginSuccessHandler를 생성하고
AuthenticationSuccessHandler 인터페이스를 구현합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/38108b5e-cb10-499b-b401-d0d6b8e52eb7/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/9305e030-82a1-48ee-8f6a-a6578ee89feb/image.png" alt=""></p>
<p>오버라이딩 하는 onAuthenticationSuccess 메서드는 로그인 성공시 실행하는 로직들을 작성해줍니다. 
(return구문도 각 if마다 붙여주세요. 안붙여주면 리아디렉트가 중복 호출됨)
<img src="https://velog.velcdn.com/images/one_2s/post/fbae64da-c1bf-42f5-9021-7895f990f242/image.png" alt=""></p>
<p>이제 기존 로그인 처리 로직을 커스텀 처리로직으로 바꿔 적용하기 위해 security-context.xml 내용을 바꿔줍니다.
<img src="https://velog.velcdn.com/images/one_2s/post/e4606d4c-6879-4524-8f9a-dc1eeacd8ee0/image.png" alt=""></p>
<p>(앞으로는 다른 로직을 커스텀 작성시</p>
<ol>
<li>커스텀 로직 작성</li>
<li>security-context.xml내부에 bean 생성</li>
<li>태그 적용순으로 진행하면 됩니다. )</li>
</ol>
<p>실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/a903d0a3-c8d6-4ab4-a30e-dfc58a2b9ecd/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/652b976f-09da-4438-8eeb-cb7f351b9264/image.png" alt="">
접근 계정에 따라 로그인이 다르게 처리 잘되는것을 볼수 있습니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 시큐리티 기초1(디폴트 폼 등)]]></title>
            <link>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EA%B8%B0%EC%B4%881%EB%94%94%ED%8F%B4%ED%8A%B8-%ED%8F%BC-%EB%93%B1</link>
            <guid>https://velog.io/@one_2s/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EA%B8%B0%EC%B4%881%EB%94%94%ED%8F%B4%ED%8A%B8-%ED%8F%BC-%EB%93%B1</guid>
            <pubDate>Thu, 05 May 2022 13:42:37 GMT</pubDate>
            <description><![CDATA[<p>security-context에
Authentcation Manager(인증매니저)를 추가해줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/58106f23-9ec4-4172-a98d-26cf5cb85969/image.png" alt="">
(beans Graph에 들어가보면 구조가 엄청 많은걸 확인할 수 있음)</p>
<p>서버를 돌려 에러가 나는지 안나는지 확인을 해 보겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/ce08a2db-c7f1-4eca-b01c-2bc896603af1/image.png" alt=""></p>
<p>서버 실행 후 에러가 나지 않는것을 확인했다면 
SecurityController를 추가 해주고 url 세팅을 하겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/a7e031ba-2fe5-45af-bd57-1c03225d91ae/image.png" alt=""></p>
<p>권한에 따라 접속할 수 있는 형태를 차등으로 두기 위해서
비회원, 회원, 운영자 3단계로 나눠서 접속 주소를 컨트롤러에 세팅합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/e9d28965-cfe8-4d9b-80d5-a4992c358125/image.png" alt=""></p>
<p>views 아래에 설정한 주소에 맞는 .jsp파일 3개를 만들어주신 다음 접속이 잘 되는지 확인 해보겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/de80c1ed-f386-4cf5-876a-83eb719238c5/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/3db173fe-353b-4f8a-a0f1-9e292640b268/image.png" alt="">
(all, member도 접속이 잘됨)</p>
<p>연결이 완료 되었다면 이제 필터와 스프링 <strong>시큐리티의 역할</strong>에 대해 보겠습니다.
기본적으로로는 접속요청을 스프링 시큐리티가 가로채서 확인을 한 다음 진행시킬지 말지를 결정시킨다는 것 입니다. 
(어떤한 요청이 와도 시큐리티를 거치고 지나감)</p>
<p>이를 위해 security-context 내부에 어떤 url 접속을 가로챌지, 그리고 접근에 따른 처리를 어떻게 할지 세팅해야 합니다. 
security:http 내부에 security:intercept-url을 먼저 지정할 수 있고 pattern에 접근 패턴을, access에는 권한이 부여된 사용자를 처리할 때는 위와 같이 hasRole(&#39;ROLE_직접부여권한명&#39;)을 적습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/78fb6363-5af5-4d72-a561-715ef70a6db6/image.png" alt="">
실행해보면
all로 들어갔을때
<img src="https://velog.velcdn.com/images/one_2s/post/d62256ea-264a-4ae7-8513-85ee1150d70d/image.png" alt="">
<a href="http://localhost:8181/secu/member">http://localhost:8181/secu/member</a>
로 들어가면
<img src="https://velog.velcdn.com/images/one_2s/post/3366fa7b-5fe4-4675-9821-726b2e744186/image.png" alt="">
로그인 창으로 넘어가는것을 확인할 수 있습니다. 
(로그인이 안됐다면 폼로그인으로 )</p>
<p>/secu/member는 접속이 안 되는것을 볼 수 있습니다.
MEMBER 권한을 부여받은 사용자가 로그인한 경우만 접근 가능하기 때문 입니다.
(위의 로그인창은 우리가 만든것이 아닌 스프링 시큐리티가 임시로 생성하는 로그인 창 입니다. (나중에 커스터마이징하겠습니다 .))</p>
<p>이제 로그인이 가능한 아이디 하나를 security-context.xml에 부여해 보겠습니다. 
이러면 동작 여부를 db를 거치지 않고도 임시로 확인 가능합니다. 
아이디 비밀번호는 name,password에 각각 member로
권한은 authorities에 &quot;ROLE_MEMBER&quot;를 줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/0a406d95-9e49-432c-9dfd-fb6b94405aa4/image.png" alt="">
실행해보면
<a href="http://localhost:8181/secu/member">http://localhost:8181/secu/member</a>
<img src="https://velog.velcdn.com/images/one_2s/post/7765906d-b5ba-4d33-bc7f-740b9f448e4d/image.png" alt="">
member로 로그인 했을시
<img src="https://velog.velcdn.com/images/one_2s/post/b8f16b31-8bee-4f4c-9fcc-4896f706da6d/image.png" alt="">
500에러가 납니다. 그러면 성공!
(500이 뜨는 이유는 암호화를 안해났기 때문)
스프링 시큐리티에서는 스프링 5버전부턴느 반드시 비밀번호를 암호화해서 처리하도록 강제됩니다.
우리는 암호화 설정을 하지 않았기 때문에, 우선 암호화 이전에 로그인만 테스트하기 위해 비밀번호 앞에 &quot;{noop}&quot;을 추가해 암호화 기능을 꺼둡니다.
<img src="https://velog.velcdn.com/images/one_2s/post/5cebf0cc-836c-45e5-8521-1bcab8b76d8a/image.png" alt="">
실행해보면
<a href="http://localhost:8181/secu/member">http://localhost:8181/secu/member</a>
<img src="https://velog.velcdn.com/images/one_2s/post/7765906d-b5ba-4d33-bc7f-740b9f448e4d/image.png" alt="">
member로 로그인 했을시</p>
<p>member페이지로 들어가지는걸 확인할 수 있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/b8bd2571-7115-486a-b3d8-7fa3a5734d23/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/352bf488-458a-4d37-bf71-244a901c7e4c/image.png" alt=""></p>
<p>로그인을 풀고싶다면 f12-&gt;application-&gt;stroage-&gt;cookies 우클릭후 쿠키를 전부 삭제해주면 로그인이 풀립니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/6ddcd48c-8e45-4b96-895c-674cf29cad33/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/03fd58ce-a7b5-413c-975c-fef7e3f307c4/image.png" alt=""></p>
<p>다음으로
admin 권한을 처리하겠습니다.
admin은 member,admin에 모두 접속 가능하게 두 권한을 나열합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/80d54cbd-beeb-466d-9987-023d7dc646f4/image.png" alt="">
실행해보면
<a href="http://localhost:8181/secu/admin">http://localhost:8181/secu/admin</a>
admin으로 로그인
<img src="https://velog.velcdn.com/images/one_2s/post/73601f08-521b-462b-a70c-b553b28a5a30/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/1aae6d54-3778-465d-aa93-8140d7cdd390/image.png" alt="">
로그아웃 하고
<a href="http://localhost:8181/secu/member">http://localhost:8181/secu/member</a>
admin으로 로그인
<img src="https://velog.velcdn.com/images/one_2s/post/60926a4e-c051-42f5-bc6a-e4a3fbf2bd30/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/ec834736-f438-4549-9006-cf6564407f4b/image.png" alt="">
admin계정으로 member주소에 접속이 가능한걸 확인 할 수 있다.</p>
<p>==커스텀 에러페이지
admin주소에 member계정으로 접속을하면
403에러가 뜹니다.
<img src="https://velog.velcdn.com/images/one_2s/post/0f4f18d0-2427-43e9-90b7-a85ca746c0f1/image.png" alt="">
이제 톰캣 에러 페이지가 아닌 다른 화면을 처리해 보겠습니다. </p>
<p>접근 제한 페이지는 (에러페이지)
security-context.xml 상단의 security:http 태그 내부를 위와 같이 고칩니다.
접근 주소는 /accessError이외에 다른 주소를 넣으면 작동하지 않습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/c3c251ad-97b4-495d-9e33-f32326eda06e/image.png" alt="">
CommomComtroller를 만들어서
<img src="https://velog.velcdn.com/images/one_2s/post/ce58a133-7b94-4e57-944d-e8acaa2ca4d5/image.png" alt="">
접근주소 /accessError를 처리하도록 세팅합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/b4dc3ae7-6c40-4bfa-8cbf-454a3fd84888/image.png" alt="">
views 폴더에 accessError.jsp를 생성해주고
<img src="https://velog.velcdn.com/images/one_2s/post/a83f808c-3f42-4a5d-a8e6-e43ff1c3cfe8/image.png" alt="">
에러 메세지를 출력하도록 코드를 작성해보겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/60ea765e-3fb6-4f0c-a1bd-b4b8dd9b904f/image.png" alt="">
실행해보면
admin주소에 member 계정으로 접속을 하면
<img src="https://velog.velcdn.com/images/one_2s/post/21779c8f-a868-4fed-8598-80603cc51328/image.png" alt="">
에러가 뜨는걸 확인할 수 있습니다. </p>
<p>==
스프링 시큐리티에서 제공하는 기본 에러 페이지 처리 방식이고 커스터마이징을 할 경우는 AccessDeniedHandler 인터페이스를 직접 오버라이딩해 구현해야 합니다.
대신 오버라이딩을 하는 만큼 세팅된 동작에 추가로직을 작성할 수 있습니다. 먼저 com.ict.security 패키지를 만들고 AccessDeniedHandler구현할 CustomAccessDeniedHandler를 만듭니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/2930ccac-aeb1-4836-b6d6-2286748f741f/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/c0bce08b-f39c-439b-b564-3c17e3b2771d/image.png" alt="">
이제 디폴트 AccessDeniedHandler를 사용하는 대신
커스텀 핸들러를 쓰도록 security-context.xml을 위와 같이 수정합니다. 
security:http내부 속성도 모두 삭제해 디폴트 설정을 못쓰게 만들어주세요.
beans graph에도 추가되어있는지 학인해주세요
(스프링 시큐리티는 계층 구조가 매우 복잡하니 주의)
<img src="https://velog.velcdn.com/images/one_2s/post/6a2da1df-60e7-487f-9785-66aa1877e4f1/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/2ec15ba5-370e-46df-a3b7-e3fea67251e4/image.png" alt="">
실행하면
<img src="blob:https://velog.io/ee81107d-be0d-4e09-ae8e-9d64afda9ec6" alt="업로드중..">
콘솔창에 이전과 달리 먼저 CustomAccessDEniedHandler를 처리는 내요의 로그가 뜬다면 제대로 연동된것
<img src="blob:https://velog.io/b6310652-9299-4384-9de5-2c841cd9fd97" alt="업로드중.."></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[시큐리티 세팅]]></title>
            <link>https://velog.io/@one_2s/%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EC%84%B8%ED%8C%85</link>
            <guid>https://velog.io/@one_2s/%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EC%84%B8%ED%8C%85</guid>
            <pubDate>Thu, 05 May 2022 10:28:28 GMT</pubDate>
            <description><![CDATA[<p>스프링 시큐리티는 특정 사이트로 들어오는 접근을 가로채서 로그인이 되어있는지 등을 검증한 다음 로직을 실행시켜줍니다.
원래 jsp에서 &quot;필터&quot;라는 기능을 이용해서 구현 가능했지만
스프링에서는 빈 컨테이너에서 관련 자원들을 같이 관리하기 때문에 이미 작성된 빈들을 연계한 여러가지 인증 방식을 구현하기 쉬워집니다.</p>
<p>security_prj프로젝트를 생성하겠습니다. </p>
<p><a href="https://velog.io/@one_2s/rest-%EC%83%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%ED%8C%85%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95">https://velog.io/@one_2s/rest-%EC%83%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%ED%8C%85%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</a>
(프로젝트 세팅 참고)</p>
<p>pom.xml에 
spring-security-web 5.0.7 RELEASE 버전 
spring-security-config 5.0.7 RELEASE 버전 
spring-security-core 5.0.7 RELEASE 버전 
spring-security-taglibs 5.0.7 RELEASE 버전<br>추가 해줍니다. </p>
<p>프로젝트 내부 WEB_INF폴더 내부의 spring폴더에 Stpring Bean Configuration File을 선택해 security-context.xml파일을 만듭니다. 
(이 파일의 용도는 스프링 시큐리티용 bean관리 컨테이너 입니다. )
<img src="https://velog.velcdn.com/images/one_2s/post/d4f93c22-37fc-4a4a-855f-eb3c7679ac38/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/ebae6c1a-2c1f-4211-a6ce-ade7ade0f34a/image.png" alt="">
위에 상단을 
<img src="https://velog.velcdn.com/images/one_2s/post/f1216248-0866-44e2-a13a-2106f72a5c95/image.png" alt="">
http로 끊고
security-5.0.xsd 에서 -5.0을 지워주면 된다. </p>
<p>다음으로 web.xml설정을 해줍니다. 
필터를 이용해 스프링 동작에 관여하도록 코드를 수정해줍니다. 
(오타가 나지 않게 주의 해야함 . 제대로 적어도 에러남)
<img src="https://velog.velcdn.com/images/one_2s/post/02ef3c14-8552-48d8-bc53-28b30ba2db2e/image.png" alt="">
에러를 없애려면 먼저 빈 컨테이너에 있는 시큐리티 관련 로직을 web.xml에서 인식하도록 설정해줘야 합니다. 
root-context인증 경로 아래에 security-context.xml을 푸가해 주세요.
<img src="https://velog.velcdn.com/images/one_2s/post/5192d549-e9c8-4f8b-ada9-740cd502d874/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ 트랜잭션 적용 댓글처리, 삭제, ]]></title>
            <link>https://velog.io/@one_2s/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%A0%81%EC%9A%A9-%EB%8C%93%EA%B8%80%EC%B2%98%EB%A6%AC-%EC%82%AD%EC%A0%9C-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EC%84%B8%ED%8C%85-swx8erw0</link>
            <guid>https://velog.io/@one_2s/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%A0%81%EC%9A%A9-%EB%8C%93%EA%B8%80%EC%B2%98%EB%A6%AC-%EC%82%AD%EC%A0%9C-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EC%84%B8%ED%8C%85-swx8erw0</guid>
            <pubDate>Tue, 03 May 2022 15:19:34 GMT</pubDate>
            <description><![CDATA[<p>프로젝트 SpringBoard로 돌아와서 aspectj 관련 의존성 pom.xml에 추가해주고 root-context.xml 설정을 해줍니다. 
(전글 참고)</p>
<p>board_tbl에 replycount컬럼을 추가하겠습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/9eff4f6e-32e5-446c-8df2-e01957f96ce2/image.png" alt="">
(commit;꼭 해줘야함)</p>
<p>com.ict.domain
BoardVO에 방금 추가한 replyCount를 추가해줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/dc89cf6f-492d-4a44-a5a7-7674480092f1/image.png" alt=""></p>
<p>boardMapper.xml에 select부분에 replyCount 추가 해줘야함
<img src="https://velog.velcdn.com/images/one_2s/post/777f0b62-c208-44be-a244-38070b8f0b3f/image.png" alt="">
(별을 이용해서 다 불러오고 있기 때문에 따로 수정은 필요없음)</p>
<p>boardMapper 인터페이스에 
<img src="https://velog.velcdn.com/images/one_2s/post/fcb3c437-22a4-443e-943a-60c3d15778e0/image.png" alt="">
bno는 해당 게시물의 번호, amount는 변동값을 나타내며, 마이바티스는 기존적으로 하나의 파라미터를 쓰는것을 전제로 하기 때문에  위와 같이 2개 이상을 정의 할때는 @Param 어노테이션을 붙여준다. </p>
<p>boardmapper.xml
amount로 댓글의 증감을 나타내고, bno로 해당 글이 몇번이 었는지 카운팅해 댓글 숫자를 가늠합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/266e6ec0-6f92-4a4c-b782-50924dbb0ea8/image.png" alt=""></p>
<p>이제 댓글 추가와, replyCount 컬럼 업데이트라는 작업이 댓글 쓰기라는 하나의 서비스에 동반실행됩니다. 
즉, 트랜잭션의 대상이 됩니다.
replyServiceImpl내부에서 boardMapper를 사용할 수 있게 처리 합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/8d4bd55e-7c05-47d6-8ab9-774e4dbbe359/image.png" alt=""></p>
<p>삭제시 댓글 갯수를 1줄이는 작업부터 하겠습니다.
먼저rno만을호 bno를 유추해야 하기 때문에 ReplyMapper쪽에 getBno메서드를 정의 및 구 구현합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/fa2fd8f5-b383-4baa-8804-7d5dd7978ffd/image.png" alt="">
ReplyMapper.xml
<img src="https://velog.velcdn.com/images/one_2s/post/44637b9e-a082-4a27-a2dd-4cc510cabf9d/image.png" alt=""></p>
<p>메서드는 리플 삭제라는 하나의 서비스 기능 구현에 실행시에는 정작 3개의 쿼리문을 돌려야 하기 때문에 반드시 트랜잭션이 적용해야 합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/aa3a4b38-8380-403c-b230-5d93418b90c7/image.png" alt=""></p>
<p>boardList.jsp
<img src="https://velog.velcdn.com/images/one_2s/post/6a14b70e-e52e-4c42-8dd0-0e8387abc09a/image.png" alt=""></p>
<p>실행해 보면
<img src="https://velog.velcdn.com/images/one_2s/post/8bac0346-7271-4d62-b39a-7427c6139b86/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/one_2s/post/14a6559b-2b0e-4d23-8a64-7b5133bf6df7/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/0f69b618-a3d4-44fd-843f-100fd200d6e7/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/adaabbd6-1c5d-4066-a7fc-7ce6984a546f/image.png" alt="">
댓글이 삭제되는걸 확인 할 수 있습니다. </p>
<p>=========
register</p>
<p>replyServiceImpl
 <img src="https://velog.velcdn.com/images/one_2s/post/25590b30-e111-40f9-bae3-b4b1f856d5cd/image.png" alt=""></p>
<p>실행해보면
<img src="https://velog.velcdn.com/images/one_2s/post/e94045b2-f615-4228-b60c-60b6126b3c2c/image.png" alt=""></p>
<p>댓글작성을 하고
<img src="https://velog.velcdn.com/images/one_2s/post/1b8888c1-d48f-4c43-a88d-4744ae7c4b68/image.png" alt=""></p>
<p>글목록으로 나가면
<img src="https://velog.velcdn.com/images/one_2s/post/3a68b03e-cedd-4857-947c-2348c3af40ee/image.png" alt="">
댓글 갯수가 늘어난걸 확인할 수 있다. </p>
<p>==
글삭제시</p>
<ol>
<li>댓글 전체 삭제(replyMapper에 쿼리문 및 메서드 추가해야함)</li>
<li>글 삭제
순 으로 삭제되어야 논리적 구조가 맞으므로 개선해 보겠습니다. 
먼저
replyMapper.java
<img src="https://velog.velcdn.com/images/one_2s/post/4770c52d-15b2-4f3a-b6a3-b5a32ef3969a/image.png" alt="">
replyMapper.xml
<img src="https://velog.velcdn.com/images/one_2s/post/0410a3ec-1d3a-48c8-a164-eca384b5bb67/image.png" alt=""></li>
</ol>
<p>boardServiceImpl
<img src="https://velog.velcdn.com/images/one_2s/post/ad672608-1e5b-433b-be6c-174135e5bed0/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/789aa1d8-57ef-451a-a580-b750ce51b907/image.png" alt=""></p>
<p>실행해보면
<img src="https://velog.velcdn.com/images/one_2s/post/22b6a039-3688-4100-9416-72065ce3462b/image.png" alt="">
196608번이 삭제된걸 확인할수 있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/29fe4906-c5af-48dd-99fb-8dc927ba8be5/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[트랜잭션 설정 및 테스트 완료]]></title>
            <link>https://velog.io/@one_2s/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%84%A4%EC%A0%95-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%99%84%EB%A3%8C</link>
            <guid>https://velog.io/@one_2s/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%84%A4%EC%A0%95-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%99%84%EB%A3%8C</guid>
            <pubDate>Mon, 02 May 2022 15:39:11 GMT</pubDate>
            <description><![CDATA[<p>같은 명령을 받으면 둘 중 하나만 돌아갈 가능성이 존재하는 테스트 테이블을 만들어 보겠습니다.
test 테이블을 2개를 생성합니다. 
테이블들은 각각 50글자와 5글자를 저장할 수 있는 컬럼을 가집니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/71c65fae-79fa-42a4-bd54-3628e8a39519/image.png" alt="">
(test1 50글자, test2 5글자만 받을수 있음)</p>
<p>Sammple1Mapper 인터페이스와 Sample2Mapper 인터페이스는 mapper xml은 따로작성하지 않고, 어노테이션으로 구문을 작성합니다.
<img src="https://velog.velcdn.com/images/one_2s/post/98b6821b-242f-4eb5-adbf-a6e0106cec9d/image.png" alt="">
Sammple1Mapper 
<img src="https://velog.velcdn.com/images/one_2s/post/d6d38e1c-b3d8-453b-97ab-b64b6f408199/image.png" alt="">
Sample2Mapper 
<img src="https://velog.velcdn.com/images/one_2s/post/f2d41921-2509-4de6-90df-06291fc9eb84/image.png" alt=""></p>
<p>방금 생성한 두 테이블에 같은 길이의 문자열을 집어넣는 서비스를 생성하기 위해 SampleTxService인터페이스, SampleTxServiceImpl 구현 클래스를 만들어 줍니다. 
SampleTxService
<img src="https://velog.velcdn.com/images/one_2s/post/8394136e-f7fb-4984-88b5-9c8ec1c0f3fc/image.png" alt="">
SampleTxServiceImpl
<img src="https://velog.velcdn.com/images/one_2s/post/97252647-5476-4808-b8e2-48e4fe008c04/image.png" alt=""></p>
<p>src/test/java 내부의 com.ict.service 패키지 내부에다 SampleTxServiceTests 클래스를 만들어서 테스트를 해봅니다.
26글자를 테이블 두개에 넣어주는 로직 입니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/ee9f25aa-e1c8-4527-9ef8-596db82abd1b/image.png" alt="">
 abcd ~를 addDate에 넣어주겠다
 addDate를 집어 넣을때 mapper1 mapper2를 호출</p>
<p>실행하면
빨간불이 들어오고
<img src="https://velog.velcdn.com/images/one_2s/post/691aa513-b392-4c2c-a9b7-0d100475a5f1/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/ded4aa69-c32a-4086-bb85-f89cdee01063/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/501bcde9-9944-481b-8781-473ef08b6917/image.png" alt="">
둘다 안들어온걸 확인할 수있다.
@@Transactional을 빼고 돌리면
<img src="https://velog.velcdn.com/images/one_2s/post/cd212bec-dfca-4b06-803f-232edfce479b/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/80dd14bc-c29e-442c-a0d5-fed82f9bf15b/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/b1fa56d8-3a0d-4a70-805a-3668e0e269a0/image.png" alt="">
col1에는 들어왔지만
<img src="https://velog.velcdn.com/images/one_2s/post/afc4ba66-d61c-42f5-b98d-3e20ce0368cd/image.png" alt="">
col2에는 안들어온걸 확인할 수 있다. </p>
<p>@@Transactional이 있는 상태로 abcd 5글자 이내로 실행해보겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/de5e8456-1b74-4d55-bf14-5ad6635879fd/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/5b50e703-09b0-4084-956c-e56ce6aff0cf/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/476fc8f4-7e50-4d0b-9031-2d258c1884af/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/b146ed38-138f-4e26-b0fc-9173d5c14451/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/afe3a71a-3c88-4f89-9e87-cc62f237ced9/image.png" alt="">
col1 col2 둘다 들어간걸 확인할 수 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[aop마무리, 트랜잭션 개념 및 설정]]></title>
            <link>https://velog.io/@one_2s/aop%EB%A7%88%EB%AC%B4%EB%A6%AC-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@one_2s/aop%EB%A7%88%EB%AC%B4%EB%A6%AC-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Mon, 02 May 2022 13:54:48 GMT</pubDate>
            <description><![CDATA[<p>SampleServiceTests.java 
<img src="https://velog.velcdn.com/images/one_2s/post/00c8aa64-4959-46ec-9ca4-3886a1c0ba16/image.png" alt="">
작성하고 실행해보면
<img src="https://velog.velcdn.com/images/one_2s/post/3b132fe4-f8b6-44b2-b102-3970ee5cd8df/image.png" alt="">
123+456을 먼저 계산하기 전, 먼저 ====== 라고 로깅부터 하느것을 볼 수 있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/4deedb1d-a9ef-44ba-bfbb-e299bc760c61/image.png" alt=""></p>
<p>== 파라미터 넣는 방법==
이번에는 execute 구문에 args를 이용해 파라미터를 추적해 보겠습니다.
분명히 로깅자체는 마음에 들지만, 파라미터별로 무슨 값을 받았는지 알 수 있다면 더 좋기 때문에 LogAdvice에 추가호 위와같이 메서드를 추가합니다. 
(접근 제한자 모두 허용
com.ict.service.SampleService로 시작하는 모든 클래스 doAdd(String.string)인 메서드 타겟이며 파라미터는 각각 str1, str2로 명명)
<img src="https://velog.velcdn.com/images/one_2s/post/d0bde64e-cf39-4139-8845-36804d4846a6/image.png" alt="">
메서드명이 doAdd여야 실행하겠고
파라미터 이름은 String1 String2이어야 한다. 
<img src="https://velog.velcdn.com/images/one_2s/post/7f40ac1e-0c2b-4e7b-b768-4ec34b69be35/image.png" alt="">
옆에 저 화살표가 떠야 되고 갖다되면 어디에 적용되는지 알 수 있다. 
실행 하면
<img src="https://velog.velcdn.com/images/one_2s/post/4f9557af-f7c9-430c-b86d-ab9039f80b8a/image.png" alt="">
BeFore === 이게 먼저 나오고
str1 에는 123
str2  에는 456이 들어오는걸 확인 할 수 있다. </p>
<p><strong>Advice</strong>는 한 메서드에 2개 이상도 동시에 적용받을 수 있기 때문에
테스트 코드를 실행하면 이번에는 2개가 모두 실행됩니다.
둘다 @Before이기 때문에 원본 메서드 이전에 작성된 순서대로 실행 후 핵심로직이 실행 됩니다. </p>
<p>다음은 에외가 발생했을때만 작동하는 <strong>@AfterThrowing</strong> 을 추가해보겠습니다.
LogAdvice 내부에 작성해줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/0ec09eb3-ee4f-4d15-91f6-a672b6643dee/image.png" alt="">
SampleServiceTests에서는 일부러 에러를 발생시켜보겠습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/1c04240c-3a72-4250-9679-30972f9493c2/image.png" alt="">
실행했을때
<img src="https://velog.velcdn.com/images/one_2s/post/e9cf190b-5222-455d-aedc-5067e6db22bf/image.png" alt="">
빨간불이 나오면서 에러가 뭐였는지 로깅을 해줍니다.
제대로 맞게 넣으면
<img src="https://velog.velcdn.com/images/one_2s/post/d76e67e6-5dd8-4cdd-89e8-5eb96b796df1/image.png" alt="">
실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/74b7ae0f-db13-44c2-a41b-26c51f06953b/image.png" alt="">
예외가 안나오는걸 확인할 수 있습니다. </p>
<p><strong>@Around</strong>는 메서드 실행 내내 실행되는 특이한 경우입니다.
특히, @Around와 함께 사용하는 ProceedingJoinPoint객체를 활용하면 파라미터와 예외 등등을 한 번에 처리할 수 있습니다. 
(메서드의 실행요소 시간을 구하는  Advice 입니다)</p>
<p>LogAdvice.java
<img src="https://velog.velcdn.com/images/one_2s/post/cd3fad58-2e9e-4803-a80c-b383d1a02739/image.png" alt="">
실행 해보면
<img src="https://velog.velcdn.com/images/one_2s/post/f1456b5b-d238-436a-9db6-d2d8c4dae901/image.png" alt=""></p>
<p>==============</p>
<h4 id="스프링의-aop와-트랜잭션">스프링의 AOP와 트랜잭션</h4>
<p>AOP를 응용해 트랜잭션을 이해하고 적용해 보겠습니다.
먼저 트랜잭션은 2개이상의 쿼리문이 실행된다면 전부 실행되고 실패한다면 전부 실패하게 만드는 것을 의미합니다.
<img src="https://velog.velcdn.com/images/one_2s/post/69f0ab79-a0bf-4660-8bc1-35b225125bb1/image.png" alt="">
4가지 원칙에 따라 기능을 묶어주는것을 트랜잭션이라고 합니다. </p>
<p>트랜잭션 실습을 위해 pox.xml에 라이브러리를 추가해줍니다.
prj-aop프로젝트
spring-jdbc 5.0.7버전
spring-tx 5.0.7버전
HikariCP 4.0.3버전
log4jdbc-log4j2-jdbc4 1.16버전
mybatis 3.5.6 버전
Spring bridge f 2.0.6 버전
ojdbc8 추가</p>
<p>src/main/resources 내부에 log4jdbc.log4j2.properties파일 추가
<img src="https://velog.velcdn.com/images/one_2s/post/40fca25c-9e68-4c29-9fcb-c9c8031b2b6a/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/3b473a88-d5fc-449a-aee4-5d080a380916/image.png" alt="">
root-context.xml을 열고 Namespace탭에 tx를 체크해줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/bd7df768-ed27-46f1-84ef-f0ddfa66a7d1/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/de8d2dbb-64ea-481b-b1be-f906a4c6baa6/image.png" alt=""></p>
<p>com.ict.dao패키지 내부에
OracleConnectionPoolTest.java를 생성해 테스트를 코드를 실행해줍니다 .
<img src="https://velog.velcdn.com/images/one_2s/post/e7e1353b-2169-4219-a9eb-81cce9c56f6a/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/10fdacd4-40ab-45c8-b44a-afac44aff045/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/a190fc80-eb39-4c90-949f-bbf720f42a25/image.png" alt="">
연결 성공!</p>
<p>root-context.xml 내부에 트랜잭션 실행을 위한
transactionManager객체 생성과 annotation-driven 태그 작성 쿼리문을 입력한 마이바티스 매퍼를 스캔합니다. 
<img src="blob:https://velog.io/3431cf84-badf-40d4-8b65-82a4cfc6efb1" alt="업로드중.."></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[댓글 작업 마무리, aop기초]]></title>
            <link>https://velog.io/@one_2s/%EB%8C%93%EA%B8%80-%EC%9E%91%EC%97%85-%EB%A7%88%EB%AC%B4%EB%A6%AC-aop%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@one_2s/%EB%8C%93%EA%B8%80-%EC%9E%91%EC%97%85-%EB%A7%88%EB%AC%B4%EB%A6%AC-aop%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Thu, 28 Apr 2022 15:11:17 GMT</pubDate>
            <description><![CDATA[<p>형제 태그 .reply의 내용을 대신 가져올수 있도록 수정해 보겠습니다. 
boardDetail.jsp
<img src="https://velog.velcdn.com/images/one_2s/post/610813b7-bbf4-4c5d-bfe9-bb46fb92b79f/image.png" alt=""></p>
<p>실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/05c2ee3b-e10e-48f7-9393-a0b2e4930c03/image.png" alt="">
수정 버튼을 눌렀을때 내용만 뜨는 걸 확인 할 수 있다. </p>
<p>다음은 댓글 등록창을 만들어 보겠습니다.
위치는 댓글 목록 아래에 두겠습니다.
역시 간단하게 input태그와 버튼으로 이벤트를 처리합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/c3e382c6-f4a1-4eaa-823b-2b0450c9372c/image.png" alt=""></p>
<p>실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/50532a7a-339d-4c24-a388-58c6341ff12e/image.png" alt="">
댓글 쓰는 폼이 만들어 진걸 확인할 수 있다. </p>
<p>===============================</p>
<h4 id="스프링의-aop와-트랜잭션">스프링의 AOP와 트랜잭션</h4>
<p>AOP는 핵심 로직과 보조 로직을 분리하자는 개념에서 출발합니다.
예)
핵심 로직 - 소개팅가기(), 출근하기(), 놀러가기(), 해외여행()
(목표가 되는 로직)
보조 로직 - 씻기(), 그루밍(), 대중교통타기()
(핵심로직 실행을 위해 실행하는 보조적 기능들)</p>
<p><strong>여태까지는 모든 메서드의 실행요소시간이 몇 초인지 구하고 싶으면 메서드마다 기능을 추가해야 했지만, 이제는 실행요소시간 구하는 기능을 하나만 만들어 두면, 모든 메서드에 기능을 전역적으로 추가하거나 혹은 기능을 추가할 메서드 범위를 지정할 수 도 있습니다. 
이런 개념을 AOP라고 부르며, 주로 로그, 보안등 주요 기능은 아니지만 주요 기능을 보조하는 기능을 구현 할때 많이 사용합니다.</strong> </p>
<h4 id="aop용어정리"><strong>AOP용어정리</strong></h4>
<p><img src="https://velog.velcdn.com/images/one_2s/post/be4b49d4-3de5-4fda-88af-0ccb2e271323/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/2b75592c-767e-4081-8ebf-2d30e2f850cf/image.png" alt=""></p>
<p>====
프로젝트를 생성하겠습니다. 
prj_aop 프로젝트를 생성하고
pom.xml에가서 값을 수정 해줍니다.
<img src="https://velog.velcdn.com/images/one_2s/post/e2e972d6-78d3-4cbb-9504-283b50de447c/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/f2cfb27c-f391-4516-a141-25686de9d6be/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/4bafda23-19d1-4ca1-8bb5-8c208fe23169/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/87ddb9f8-2bfd-458d-bcd2-33fb07da6f47/image.png" alt=""></p>
<p> spring-test 5.07버전 
 lombok 1.18.18버전
 aspectjweaver 1.9.0버전
 aspectjrt 1.9.0버전 추가</p>
<p> <img src="https://velog.velcdn.com/images/one_2s/post/4a326b84-6239-446e-a43e-bdd743553063/image.png" alt="">
com.ict.service 패키지를 만들어
SampleService 인터페이스
SapmleServiceImpl 구현 클래스를 만들어 줍니다.
SampleService.java
<img src="https://velog.velcdn.com/images/one_2s/post/3c140824-abe0-43e7-9c52-a1ed56a70f96/image.png" alt="">
SapmleServiceImpl.java 
<img src="https://velog.velcdn.com/images/one_2s/post/f01fe811-4708-4c98-8522-73bbb22ef81e/image.png" alt=""></p>
<p>(service의 코드는 현재 로그를 기록하는 기능이 없습니다.
보조 기능과 핵심 기능을 따로 개발하는 AOP 개념을 적용해 로깅기능을 추가할 것이기 때문입니다.
로그를 자동기록해주는 Advice를 지금부터 작성해보겠습니다.)
com.ict.aop 패키지에 LogAdvice클래스를 생성
<img src="https://velog.velcdn.com/images/one_2s/post/cb8a4da8-68c6-41b3-babc-1b776a75fc34/image.png" alt="">
LogAdvice.java
<img src="https://velog.velcdn.com/images/one_2s/post/ff6c4418-631b-41dd-8c19-99587e9b9417/image.png" alt="">
(pom.xml에서 aspectjrt의 scope 태그를 주석처리 해야 LogAdvice.java내부에서 @Aspect어노테이션이 인식되니 주의)</p>
<p>(@Log4j가 에러나는 경우는 pom.xml의 log4j버전이 1.2.15일경우 exclusions를 남기고 1.2.17인 경우는 삭제하신 다음 두 버전 모두 공통적으로 내부 scope를 주석처리하면 풀림)</p>
<p>LogAdvice.java
<img src="https://velog.velcdn.com/images/one_2s/post/eca15705-55db-4eed-8e1e-d6c3b8fd3a50/image.png" alt="">
@Before는 핵심로직 실행 전에 logBefore메서드가 실행됨을 나타내며, 내부 문자열은 규칙에 맞는 메서드 전부를 실행하기 전에 실행됨을 나타냅니다. 
위의 경우 맨 앞의 *은 접근제한자 상관 없음, 가운덴는 어느 패키지 어느 클래스까지, 뒤의 *은 클래스명, 메서드명, 파라미터 종류이다. 
(@Aspect를 받은 클래스는 AOP의 타겟임을 알리는것)</p>
<p>root-content.xml 
aop,  context설정
<img src="https://velog.velcdn.com/images/one_2s/post/149c7b96-8067-4532-8c7b-ec39d1c5143f/image.png" alt="">
내부에 작성
<img src="https://velog.velcdn.com/images/one_2s/post/b62dd091-a134-4dab-ac17-1e2a24d66f59/image.png" alt=""></p>
<p>이제 컴포넌트 스캔이 되면서 위와 같이 메서드 왼쪽에 화살표 마크가 추가됩니다.
<img src="https://velog.velcdn.com/images/one_2s/post/e9249cf3-011c-426a-a072-c9c6d62c47b7/image.png" alt=""></p>
<p>com.ict.service 패키지 내부에
SampleServiceTest클래스를 생성해 작성하고
<img src="https://velog.velcdn.com/images/one_2s/post/7931a486-14ad-4dc3-b5dd-0e5a5913f035/image.png" alt=""></p>
<p>실행했을때 Proxy객체가 확인되어야 AOP 적용이 완벽하게 된 것입니다.
<img src="https://velog.velcdn.com/images/one_2s/post/e3c90dc5-d27a-4393-b3b0-4f6e5b1af4d3/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[댓글 디자인 갱신, 시분초 표시]]></title>
            <link>https://velog.io/@one_2s/%EB%8C%93%EA%B8%80-%EB%94%94%EC%9E%90%EC%9D%B8-%EA%B0%B1%EC%8B%A0-%EC%8B%9C%EB%B6%84%EC%B4%88-%ED%91%9C%EC%8B%9C</link>
            <guid>https://velog.io/@one_2s/%EB%8C%93%EA%B8%80-%EB%94%94%EC%9E%90%EC%9D%B8-%EA%B0%B1%EC%8B%A0-%EC%8B%9C%EB%B6%84%EC%B4%88-%ED%91%9C%EC%8B%9C</guid>
            <pubDate>Wed, 27 Apr 2022 15:12:31 GMT</pubDate>
            <description><![CDATA[<p>테스트에서 작성했던걸 boardDetail.jsp로 옮겨주겠습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/fb6436ba-8600-49cf-baa1-6e99b283993f/image.png" alt="">
bno를 그때마다 받아올수있게 처리.</p>
<p>(insertTest.jsp에서 썻던걸 복사!!
테스트를 해서 성공이 되는걸 확인했기 때문에 알맞게 복사하면 됨)</p>
<p>잘 복사했으면 수정,삭제,닫기 버튼기능들이 잘 작동됨.</p>
<p>==
<img src="https://velog.velcdn.com/images/one_2s/post/d0c17d43-d746-4f07-87b4-1acd85d0a3c2/image.png" alt=""></p>
<p>댓글 디자인을 해보겠습니다. </p>
<p>getJSON부분을 수정해 줍니다. 
구문 내에 먼저updeteDate를 받아온 다음.
Date 타입으로 변경을 해 줍니다.
그 뒤 getFullYear()로 연도를, getMonth로 월을(0부터 시작)
getDate로 일자를 받아와 출력위치에 둡니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/6230e73f-82ea-4077-a1b7-5e3b5ac8f270/image.png" alt="">
실행하면
<img src="blob:https://velog.io/0ce16b37-7768-4efa-bb49-b6a7b73101ed" alt="업로드중..">
댓글 작성한 시간, 디자인 변경된걸 확인 가능!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[비동기 CRUD 전체 마무리]]></title>
            <link>https://velog.io/@one_2s/%EB%B9%84%EB%8F%99%EA%B8%B0-CRUD-%EC%A0%84%EC%B2%B4-%EB%A7%88%EB%AC%B4%EB%A6%AC</link>
            <guid>https://velog.io/@one_2s/%EB%B9%84%EB%8F%99%EA%B8%B0-CRUD-%EC%A0%84%EC%B2%B4-%EB%A7%88%EB%AC%B4%EB%A6%AC</guid>
            <pubDate>Tue, 26 Apr 2022 15:39:54 GMT</pubDate>
            <description><![CDATA[<p>모달 창을 만들어 보겠습니다.
수정 및 삭제 처리를 위한 창을 만들겠습니다.
이 창은 modal을 변형해서 만들며, html요소에는 존재하지만 평소에는 보이지 않다가, 추후에 버튼을 클릭했을때만 화면에 표출되는 창으로 설계합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/06a2cc27-e6bb-4113-a0c2-b4f2190f2e67/image.png" alt="">
상단 head태그 내에 stype 부분도 작성 해줍니다
<img src="https://velog.velcdn.com/images/one_2s/post/f77313a8-d989-47aa-910e-baf2a2c0cd9d/image.png" alt="">
이벤트 위임은 이제 alert창 대신 모달이 직접 열리도록 수정해 보겠습니다. 모달의 경우,jquery로 모달창을 설정한 다음,
<img src="https://velog.velcdn.com/images/one_2s/post/af89ce47-371f-4bd8-b3b6-b2ef0bb5034f/image.png" alt="">
show()를 사용하면 드러나도록 설계되어있습니다. 
&quot;slow&quot;를 붙여서 천천히 열리는 애니메이션 효과를 추가합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/e4329d5d-7f2b-418a-88d6-d37eeb00a965/image.png" alt="">
실행했을때
<img src="https://velog.velcdn.com/images/one_2s/post/6f5f7aab-1b02-47dd-ba3a-56292ec2dd19/image.png" alt="">
창이 열리면 성공입니다.
(버튼을 안눌러짐)</p>
<p>모달 닫기
.hide()로 닫고, show()로 연다
closeBtn을 클릭했을때 모달이 닫히도록 처리해보겠습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/36f1416c-60e1-4135-a4e1-76f8217cbb3c/image.png" alt="">
실행했을때
<img src="https://velog.velcdn.com/images/one_2s/post/24da9569-96cf-4a97-8fca-798f4eeba552/image.png" alt="">
닫기 버튼이 눌려지면 성공입니다!</p>
<p><img src="https://velog.velcdn.com/images/one_2s/post/6695a08f-50c1-4d50-9fba-7f841235d9e0/image.png" alt=""></p>
<p>===
삭제버튼 로직
modal-title의 글 번호를 얻어오고, reply의 수정할 글 내용을 가져온 다음 ajax통신을 이용해 delete로직을 실행한 다음 모달을 닫고 댓글목록을 갱신합니다.<br><img src="https://velog.velcdn.com/images/one_2s/post/b7e0c1be-c06b-4685-a858-26226bd42c65/image.png" alt="">
실행하면 
삭제 버튼을 눌렀을시 삭제가 되는걸 확인 가능
<img src="https://velog.velcdn.com/images/one_2s/post/7ac78d8f-9435-4fa1-af98-099cede794ea/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/2d6887a9-f5b0-4a1c-8925-085dbcf34bef/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/56e77e96-e3ef-49f7-a6dd-c89a05d92844/image.png" alt=""></p>
<p>==
수정버튼 로직
전박전으로 delete와 같고, type만 put(patch)로 바꿉니다.
단, 수정은 삭제와 달리 수정할 내용이 동반되므로 data속성도 추가합니다. contentType은 만약  415에러가 뜬다면 추가하면 되는 부분입니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/2da6d0a6-a3fb-49c7-8b91-dc193cdc3c8e/image.png" alt="">
실행을 하면
<img src="https://velog.velcdn.com/images/one_2s/post/695e61e0-1976-4707-ac54-58deeb010334/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/a3065dd7-6d15-44df-a79a-9b69bd9306f1/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/64113f8b-1235-4a90-b110-734ee3b7f1e9/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/907fa923-0222-44a4-b355-dada49eebdf9/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ajax 데이터 갱신 등]]></title>
            <link>https://velog.io/@one_2s/ajax-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B0%B1%EC%8B%A0-%EB%93%B1</link>
            <guid>https://velog.io/@one_2s/ajax-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B0%B1%EC%8B%A0-%EB%93%B1</guid>
            <pubDate>Mon, 25 Apr 2022 15:54:19 GMT</pubDate>
            <description><![CDATA[<p>댓글과, 댓글쓰기 창이 한 번에 보이도록 코드를 수정해 보겠습니다. 
(getJSON을 정의하지 않아서 댓글목록을 볼수 없음)
insertTest.jsp
/test에서 ul태그 #replies, 코드를 복붙
<img src="https://velog.velcdn.com/images/one_2s/post/5e292ac2-b7b0-4c67-a5c9-0fa22db8bd52/image.png" alt="">
jquery  cdn 가져오기 
<img src="https://velog.velcdn.com/images/one_2s/post/03922e03-11e0-4237-be18-b8612ee7e819/image.png" alt="">
댓글 전체 가져오기
<img src="https://velog.velcdn.com/images/one_2s/post/0a8401c8-62dd-4245-89fc-c0d743714466/image.png" alt="">
댓글추가버튼눌르면 댓글 추가 기능
<img src="https://velog.velcdn.com/images/one_2s/post/a96c6226-6c10-4d55-8b7a-2f417a3461d9/image.png" alt="">
하단에 getAllList();를 다시 호출해줘야함
호출을 안하게 되면 댓글을 등록을 할때
새로고침을 해야 댓글이 등록됨 등록을 해야 새로고침을 안해도 글이 등록이 된다. </p>
<p>실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/d8959eb6-017a-4ae0-ae62-98acd3374013/image.png" alt=""></p>
<p>댓글 추가 후
<img src="https://velog.velcdn.com/images/one_2s/post/31bc8b8f-cfd7-460f-b3e2-60c2e432ce63/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/3a0c1957-d78e-4cc9-8dde-dc0575666a06/image.png" alt="">
폼 태그 안이 비워지게 되도록 하겠습니다.</p>
<p><img src="https://velog.velcdn.com/images/one_2s/post/569f5718-6a16-4603-a6d8-d2a3be10a7ce/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/f3f72bc5-d2cf-4410-a153-32655583ff46/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/d75df7b3-4b16-4fdb-9bac-db08f0df4092/image.png" alt="">
댓글이 비어지는걸 확인할 수 있다. </p>
<p>이제 모든 댓글은 표출시 버튼을 가질 수 있도록 수정하겠습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/d2f6c2d3-4adc-496b-b6aa-077ed8b6c9f5/image.png" alt="">
결과가
<img src="https://velog.velcdn.com/images/one_2s/post/3a8749a3-00b9-401e-878a-4cae8ea37db3/image.png" alt="">
수정 버튼이 생기면 성공!</p>
<p>각 이벤트 버튼 모두가 독립적으로 클릭시 반응하도록 &quot;위임&quot;처리를 했습니다. 
onclick 이벤트를 처리 할때 두 번째 파라미터로 함수 대신
&quot;부모요소 자식요소&quot;와 같이 적으면, 실제로는 replyLi하위의 button모두가 따로따로 기능합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/65619f6f-28bd-4e5d-9bbb-a5ebb4157f56/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[비동기 요청 insert, onclick]]></title>
            <link>https://velog.io/@one_2s/%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%9A%94%EC%B2%AD-insert-onclick</link>
            <guid>https://velog.io/@one_2s/%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%9A%94%EC%B2%AD-insert-onclick</guid>
            <pubDate>Sat, 23 Apr 2022 19:22:17 GMT</pubDate>
            <description><![CDATA[<p>ajax는 비동기 통신의 의미
기존 방식 개발로는 일단 페이지 로딩이 완료된 다음 어떤 동작을 했을때 페이지의 이동을 전제로 개발이 이루어졌지만
비동기 방식 개발을 할 경우, 페이지의 이동이 아닌 해당 페이지 내의 html코드만 수정된다던지 하는 식으로 전체 페이지의 변겅을 지양합니다.
이런 방식의 장점은 전체적인 페이지를 매번 그릴 필요가 없기 때문에 전반적인 서버 부담도 줄어들고 사용자 입장에서도 응답을 빨리 받을 수 있다는 장점을 가집니다. </p>
<p>온클릭 하는법
HomeController.java에 onClockTest메서드를 만들어 줍니다.
<img src="https://velog.velcdn.com/images/one_2s/post/962d2cae-1d46-4939-a8dc-eeadcdedd6f6/image.png" alt=""></p>
<p>viesw - 우클릭 new - jspFile - onClickTest 생성
onClickTest 
body 태그 안에 작성해주고 ul,button, jquery cdn 
<img src="https://velog.velcdn.com/images/one_2s/post/412996ae-7fbf-4268-9c2b-d019bd03cc62/image.png" alt=""></p>
<p>script태그에 @requestBtn에 대한 onclick이벤트를 걸어줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/396394a9-e35b-4c89-bb5e-88b73d9b9051/image.png" alt=""></p>
<p>실행했을때
<a href="http://localhost:8181/onClickTest">http://localhost:8181/onClickTest</a>
<img src="https://velog.velcdn.com/images/one_2s/post/8b7c031f-231a-43ca-a22b-c87df1496105/image.png" alt="">
댓글 로딩해오기 버튼을 클릭하면
<img src="https://velog.velcdn.com/images/one_2s/post/4f3c6977-ffea-4a67-a48a-2c8a4da5aa45/image.png" alt="">
댓글 내용이 나온느것을 확인할 수 있다. </p>
<p>===
ajax 테스트하기
전체 댓글 불러온느 기능은 많이 사용하므로 함수화 해서 저장해둡니다. 마지막에 한번 호출해서 제대로 작동하는지만 체크하고 넘어갑ㄴ다. 
<img src="https://velog.velcdn.com/images/one_2s/post/4a4e43f4-dcc8-41b1-806c-69d7aa642add/image.png" alt="">
실행하면 <a href="http://localhost:8181/test">http://localhost:8181/test</a>
<img src="https://velog.velcdn.com/images/one_2s/post/686ffbf0-04e1-4f8b-9341-9722a934f872/image.png" alt="">
댓글 목록이 다 나오는걸 확인할 수 있습니다. </p>
<p>===
댓글 등록화면 테스트
HomeController.java에 insertTest메서드를 만들어 줍니다.
<img src="https://velog.velcdn.com/images/one_2s/post/7ab06497-6100-494e-a2e7-4c85e6f6bc7f/image.png" alt="">
viesw - 우클릭 new - jspFile - insertTest 생성</p>
<p>insertTest.jsp
body 태그 안에 먼저 작성해줍니다.
<img src="https://velog.velcdn.com/images/one_2s/post/6c2d974b-e0d2-45b7-95a9-565d13aabf58/image.png" alt="">
(AJAX는 form 태그가 필요없음)
실행했을때 
<img src="https://velog.velcdn.com/images/one_2s/post/1924586e-3597-437f-b094-07791be17376/image.png" alt="">
(폼은 아니지만 폼형식의 형태가 만들어 지는걸 확인할수 있음)
<img src="https://velog.velcdn.com/images/one_2s/post/2d08f6cf-d0a7-43f4-9a81-82f200bb9955/image.png" alt="">
실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/9dbd7174-5735-44b2-8034-7f6ab4aaec84/image.png" alt="">
즉, $.getJSON()은 이 페이지에서 데이터를 서버에 요쳥해 가지고 올때, $.ajax()는 이 페이지에 입력된 어떤 자료를 서버에 보낼때 사용하는 기능들 입니다.
이상의 로직들은 페이지 이동 없이 이루어졌습니다.
이런 식으로 rest서버에 ajax요청을 해서 비동기 작업을 하는것이 바로 rest개발 방식이며, 어플리케이션 등에서도 비슷하 수순으로 개발이 이루어집니다. </p>
<p><img src="https://velog.velcdn.com/images/one_2s/post/905da846-8244-40e6-8d8f-acbd6f93bcaf/image.png" alt="">
등록하기 버튼을 누르면 등록 되었습니다 라고 나오고
<img src="https://velog.velcdn.com/images/one_2s/post/3840c6f8-5d0a-4c84-b7dc-80260a5fa19c/image.png" alt="">
댓글이 추가되는걸 확인할 수 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[rest컨트롤러 이용해 댓글 출력테스트]]></title>
            <link>https://velog.io/@one_2s/rest%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-%EC%9D%B4%EC%9A%A9%ED%95%B4-%EB%8C%93%EA%B8%80-%EC%B6%9C%EB%A0%A5%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@one_2s/rest%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-%EC%9D%B4%EC%9A%A9%ED%95%B4-%EB%8C%93%EA%B8%80-%EC%B6%9C%EB%A0%A5%ED%85%8C%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Thu, 21 Apr 2022 16:48:40 GMT</pubDate>
            <description><![CDATA[<p>ajax는 비동기 통신을 의미합니다.
기존 방식 개발로는 일단 페이지 로딩이 완료된 다음 어떤 동작을 했을때 페이지의 이동을 전제로 개발이 이루어졌지만 
비동기 방식 개발을 할 경우, 페이지의 이동이 아닌 해당 페이지 내의 html코드만 수정된다던지 하는 식으로 전체 페이지의 변경을 지양합니다. 
이런 방식의 장점은 전체적인 페이지를 매번 그릴 필요가 없기 때문에 전반적인 서버 부담도 줄어들고 사용자 입장에서도 응답을 빨리 받을 수 있다는 장점을 가집니다. </p>
<p>먼저 개발시간의 단축을 위해 HomeController 하단에 ajaxText 메서드를 작성합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/e044d580-8fae-4aa6-bc8a-95caffcd7529/image.png" alt=""></p>
<p>테스트를 할 test.jsp를 생성합니다
view바로 아래에 생성하면 되고, body태그는 다음과 같이 구성합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/af010f41-ad71-4f83-974e-ca20488f961c/image.png" alt="">
jquery는 
구글 jquery 검색
Download 클릭
Google CDN 클릭
3.x snippet 복사 
<img src="https://velog.velcdn.com/images/one_2s/post/51b9fd5b-a1e0-4254-89df-5fc248c0c785/image.png" alt="">
하면 된다. </p>
<p>DB를 조회해 댓글이 2개이상인 글번호(bno)를 미리 기억해주세요.
없다면 insert구문을 실행해 댓글을 2개 이상 보유한 글을 만들어 줍니다. 
(글번호 1번으로 진행 하겠습니다)
(댓글 추가 전 장에 있음)
<img src="https://velog.velcdn.com/images/one_2s/post/7283bd60-5081-4b23-a380-b6480bbcda64/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/3b77807a-e47f-40e3-b653-b3fa27a865f0/image.png" alt=""></p>
<p>(body태그 하단)
첫 번째로는 페이지를 열자마자 해당 글(1번bno)의 글 개수를 콘솔창에 찍어주는 자바스크립트 코드를 작성해보겠습니다.
$.getJSON(&quot;주소&quot;,function(data){
    console.log(data.length);
});
는 rest주소에 데이터를 요청하고 받아온 데이터를 data변수에 담아줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/afe08c3c-82ff-430e-aa54-e355d957fca8/image.png" alt="">
(var 대신 let 사용해도됨)
실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/a6d8a132-47ba-4642-89bf-0590b7ec7043/image.png" alt="">
1번글에 댓글이 몇개있는지 알수 있다. (댓글 갯수22개)</p>
<p><img src="https://velog.velcdn.com/images/one_2s/post/c5cb8650-c106-476d-845d-888ae44c0b05/image.png" alt="">
length를 빼고 데이터로만 조회하면 데이터가 나오는것을 확인할 수있다. 
<img src="https://velog.velcdn.com/images/one_2s/post/5cc06d37-f84d-4606-b0b6-5652e643dfe9/image.png" alt=""></p>
<p>==
str내부에 li태그로 구성된 태그를 전체 댓글 개수만큼 반복해서 작성해두록.each구문을 사용하고, 그에 다른 결과는 아까 생성해놨던 ul태그 내부에 삽입하도록 처리 했습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/84d883f2-61b4-4409-bbb6-4c10987418e6/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[rest컨트롤러 modify로직까지 확인]]></title>
            <link>https://velog.io/@one_2s/rest%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-modify%EB%A1%9C%EC%A7%81%EA%B9%8C%EC%A7%80-%ED%99%95%EC%9D%B8</link>
            <guid>https://velog.io/@one_2s/rest%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-modify%EB%A1%9C%EC%A7%81%EA%B9%8C%EC%A7%80-%ED%99%95%EC%9D%B8</guid>
            <pubDate>Wed, 20 Apr 2022 17:20:47 GMT</pubDate>
            <description><![CDATA[<p>BoardController
@RequestMapping(&quot;/board&quot;)를 추가해주고
주소들을 다 수정해준다. 
board파일안에 다 넣어주고
<img src="https://velog.velcdn.com/images/one_2s/post/8589a4d0-8f63-4b23-ba6a-9591ff0d8b26/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/df1c6f9d-87c1-4bad-98cf-a9baada0c678/image.png" alt="">
이런식으로 다 수정해준다. </p>
<p>====</p>
<p>삭제로직</p>
<p>삭제로직은 delete요청을 처리하기 위해 @DeleteMapping을 걸어서 로직을 정의합니다. </p>
<p>ReplyCnotroller.java
<img src="https://velog.velcdn.com/images/one_2s/post/88200237-0c70-4ef1-930c-41dcae8d87cf/image.png" alt="">
댓글을 쓴 게시물 번호를 조회를 한 다음 그안에 댓글 번호를 가져옵니다. 저는 (14번을 가져오겠습니다)
<img src="https://velog.velcdn.com/images/one_2s/post/6e937b65-8e47-4290-94f0-f0f278877382/image.png" alt="">
YARC에 가서 작성을 해주고 돌려보면
<img src="https://velog.velcdn.com/images/one_2s/post/f44c6927-7525-4292-b7bd-010bf99f8ec4/image.png" alt="">
14번 댓글이 삭제되는걸 확인할 수 있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/35395ec8-bcc0-4aff-8ca3-c5ba0b864d01/image.png" alt=""></p>
<p>======
수정로직
PUT, PATCH 방식은 구분이 엄격하지 않기에 위와 같이 두 가지를 모두 포함시켜줍니다.
consumes에는  json을 입력받음을 명시하고, produces에는 문자열을 리턴한다고 명시합니다. </p>
<p>ReplyCnotroller.java
<img src="https://velog.velcdn.com/images/one_2s/post/6d20e86d-c19d-413b-8ecc-3cec2b8eb879/image.png" alt="">
댓글을 쓴 게시물 번호를 조회를 한 다음 그안에 댓글 번호를 가져옵니다. 저는 (13번을 가져오겠습니다)
<img src="https://velog.velcdn.com/images/one_2s/post/d4d68a90-85b2-4366-ae87-19b4b266c73e/image.png" alt="">
YARC에 가서 작성을 해주고 돌려보면
(PUT, PATCH 둘중의 하나로 돌려주면 됨)
<img src="https://velog.velcdn.com/images/one_2s/post/6051a8f9-ee82-4117-bea2-e3950d480b52/image.png" alt="">
13번의 댓글이 수정된걸 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/0bee09a6-3e78-4f58-8c67-a7a7f3c7165c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/one_2s/post/b8438fe3-fe56-47fa-8f91-03fa79a6fb62/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/one_2s/post/429172b6-22d4-485a-b824-27e7307aa163/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[협업할때 db버전이 다를경우]]></title>
            <link>https://velog.io/@one_2s/%ED%98%91%EC%97%85%ED%95%A0%EB%95%8C-db%EB%B2%84%EC%A0%84%EC%9D%B4-%EB%8B%A4%EB%A5%BC%EA%B2%BD%EC%9A%B0</link>
            <guid>https://velog.io/@one_2s/%ED%98%91%EC%97%85%ED%95%A0%EB%95%8C-db%EB%B2%84%EC%A0%84%EC%9D%B4-%EB%8B%A4%EB%A5%BC%EA%B2%BD%EC%9A%B0</guid>
            <pubDate>Wed, 20 Apr 2022 15:23:01 GMT</pubDate>
            <description><![CDATA[<p>context 네임스페이스 태그를 이용해 평문을 그대로 적지 않고
파일명만 명시해서 어떤 자료인지 다른 사용자가 모르게 처리
src/main/resources  내부에 작성한 properties 내부에 기술된 사항을 명칭으로만 가져올 수 있도록 처리
<img src="https://velog.velcdn.com/images/one_2s/post/18493201-7a09-4548-8bfb-aea0d582ac2e/image.png" alt=""></p>
<p>src/main/resource 우클릭 new - file - db.properties 생성
(파일명은 아무렇게 적어도 상관없음)
여기 안에 4개를 적어야 합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/25f3662b-72e8-4e1e-8bcb-1ffaf70fd1c4/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[rest컨트롤러, 댓글정보 조회]]></title>
            <link>https://velog.io/@one_2s/rest%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-%EB%8C%93%EA%B8%80%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C</link>
            <guid>https://velog.io/@one_2s/rest%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-%EB%8C%93%EA%B8%80%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C</guid>
            <pubDate>Tue, 19 Apr 2022 17:39:13 GMT</pubDate>
            <description><![CDATA[<p>TARC에서 확인해보기
<img src="https://velog.velcdn.com/images/one_2s/post/a0258c39-4dd1-49dd-ab65-912cbc3a6abc/image.png" alt="">
작성하고 sendRequest를 누르면
<img src="https://velog.velcdn.com/images/one_2s/post/113ce177-f038-4efe-965f-5247a6b6ab1d/image.png" alt="">
200뜨는걸 확인할 수 있다. 
오라클을 실행했을때
500번글에 <img src="https://velog.velcdn.com/images/one_2s/post/e4221178-5460-413c-bd1e-51037153b22f/image.png" alt="">
댓글이 추가된것읗 확인할 수 있다. </p>
<p>다음은 전체 글 목록을 요청하는 list메서드를 생성합니다.
이 메서드의 파라미터에는 @PathVariable이라는 어노테이션이 있는데 이는 상단의 {bno}자리에 들어온 요소는 ?bno=과 같이 간주한다는 의미입니다.
이번에는 produces를 확장해 xml,json을 모두 다루게 해보겠습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/654a65ad-db39-4fd0-a837-608d70de7e11/image.png" alt=""></p>
<p>실행을 해보겠습니다(get방식이라 trac를 안써도됨)
주소 = <a href="http://localhost:8181/replies/all/500">http://localhost:8181/replies/all/500</a>
xml버전
<img src="https://velog.velcdn.com/images/one_2s/post/75854e7e-726c-47e3-9520-1d9a7780a8db/image.png" alt="">
json버전
<img src="https://velog.velcdn.com/images/one_2s/post/7c07875a-adff-42ba-9980-a5ef284016c7/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/9f410de7-4ec5-4d00-b90c-858234e2527a/image.png" alt=""></p>
<p>==============
rest 방식의 가장 큰 차별점:</p>
<p>비동기
예)업비트</p>
<hr>
<p>mvc는 동기식
데이터가 수시로 넘어가지 않음. 한 번에 화면단에서 쓸 데이터를 다 넘겨주고 일단 화면으로 넘어가면 추가 데이터를 받아올 수 없음
(받기 위해서는 전환이 필요함)
  21156</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[rest 서버 시작]]></title>
            <link>https://velog.io/@one_2s/rest-%EC%84%9C%EB%B2%84-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@one_2s/rest-%EC%84%9C%EB%B2%84-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Mon, 18 Apr 2022 16:35:04 GMT</pubDate>
            <description><![CDATA[<p>먼저
prj_rest_2로 돌려지는지 확인
<img src="https://velog.velcdn.com/images/one_2s/post/32b21650-7994-4f03-84b9-0c275eb85286/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/218307b4-84ad-4ed1-95b2-8693f74aa8cf/image.png" alt="">
돌렸을때 이렇게 나오면 맞음!</p>
<p>com.ict.controller - 우클릭 new - class - TestController 생성
<img src="https://velog.velcdn.com/images/one_2s/post/39912438-b44e-444a-8a77-b2de9b1704bc/image.png" alt="">
@RestController 는 일반 컨트롤러와는 달리 이 컨트롤러가 rest방식으로 작동할것이라는 선언을 하는 어노테션입니다.
이제, 이 서버는 .jsp파일을 필요로 하지 않으며, 단순히 결과는 문자열, xml문서,json문서만을 화면에 표시합니다. 
(클래스 위에 붙인 RequestMapping은 해당 컨트롤러의 공통된 진입주소를 설정해줍니다. )</p>
<p><img src="https://velog.velcdn.com/images/one_2s/post/db0b1048-e1fd-4712-8a99-f539931daaa3/image.png" alt="">
단순 문자열을 다뤄보겠습니다. 
메서드가 리턴은 String으로 하면 그 문자를 화면에 표룽할 뿐입니다.
거기에 더해 F12를 눌러 개발자 도구를 열어 Network탭으로 이동한 다음 다시 새로고침을 하면 위와 같은 서버가 전송한 데이터에 대한 정보가 나와있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/844f2e5e-3621-4944-93ce-4cd5e0878098/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/de9677c1-fb54-4318-a3f7-8e243669f246/image.png" alt=""></p>
<p>com.ict.controller / 우클릭 package / com.ict.domain 생성
com.ict.domain / 우클릭 new / class / TestVO 생성
<img src="https://velog.velcdn.com/images/one_2s/post/3fe08027-8cf1-4ae6-9118-353e2fec270d/image.png" alt="">
RestController에서 객체 (vo등)은 전부 json으로 변환됩니다.
먼저 테스트용 vo를 생성해보겠습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/27cfa02a-fae7-43bb-93ab-d0e05c68f5d5/image.png" alt=""></p>
<p>TestController에서 방금 생성한 TestVO를 리턴하는 메서드를 생성하겠습니다. 
TestController
<img src="https://velog.velcdn.com/images/one_2s/post/745afc5f-fd66-498e-b70e-4e08c97768ea/image.png" alt="">
실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/1f3990fc-f8c3-4617-95b0-999875ac3e76/image.png" alt="">
500에러가 뜹니다. 
이유는 json타입을 반환하기 하지만 변환하는 기능이 바로 작동하지 않기 때문입니다. 
따라서, mvnrepository에서 jackson-databind 라이브러리를 새로 pom.xml에 추가 해줍니다.
jackjon-dataformat-xml 도 검색해서 추가해주면 xml형식으로도 같이 처리 할 수 있습니다. 
pom.xml
<img src="https://velog.velcdn.com/images/one_2s/post/96d400dd-d4c3-4b9c-a5f2-5fdb3e3da80a/image.png" alt="">
그리고 다시 실행 해보면
<a href="http://localhost:8181/test/sendVO">http://localhost:8181/test/sendVO</a> (xml 형식)
<img src="https://velog.velcdn.com/images/one_2s/post/4ba0114c-17f8-481a-9644-8592a8a13824/image.png" alt="">
<a href="http://localhost:8181/test/sendVO.json">http://localhost:8181/test/sendVO.json</a> (.json형식)
<img src="https://velog.velcdn.com/images/one_2s/post/449e12cf-0985-4fc6-b209-40ad47ee2ce9/image.png" alt="">
나오는 것을 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/one_2s/post/7ab96826-b666-430e-a078-f6f7667d4361/image.png" alt="">
json타입을 리턴했음을 명시해주고 있다.</p>
<p>listVO로 처리하는 법
TestController
<img src="https://velog.velcdn.com/images/one_2s/post/69b70da8-cf45-4f9d-81d1-a035a65a19b8/image.png" alt=""></p>
<p>실행하면 +f12
<img src="https://velog.velcdn.com/images/one_2s/post/dd5bd87e-d13b-41dc-99f7-32e9071f28fb/image.png" alt="">
json으로 나오는거 확인할수 있음
(대괄호 안에 하나하나의 중괄호 데이터로 묶어서 주고 있음)
이렇게 전달받은 객체 리스트 위와 같이 대괄호로 감싸진 json객체의 집합으로 표시됩니다. </p>
<p>json처럼 표현되는 Map자료형 역시 그대로 표현할 수 있습니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/aca4cae0-3559-428a-9361-99f22c80bda0/image.png" alt="">
실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/1cc048cc-0f15-4c1c-988f-360c35479640/image.png" alt="">
(맵 같은 경우는 중괄호가 아니라 대괄호를 쓴다. )
객체 내부의 객체로 표현됩니다. 
대괄호로 동등하게 나열하는 형태가 아님에 유의</p>
<p>====
<img src="https://velog.velcdn.com/images/one_2s/post/f5faf8c5-e824-4336-a2be-4a29bfa03ae7/image.png" alt="">
서버는 요청을 처리하며, 결과로 코드를 함께 전송합니다.
그리고 <strong>ResponseEntity</strong>를 사용하면 개발자가 의도한 타이밍에 의도한 응답을 사요자에게 전달할 수 있습니다. </p>
<p>이제 접속하는 족족 400에러를 발생시키는 ResponseEntity&lt;&gt;를전송해보겠습니다. </p>
<p>HttpStatus.BAD_REQUEST와 같이 HttpStatus 객체를 ResponseEntity객체의 생성자로 넣어 return구문에 제공하면 됩니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/5f81464c-7d25-4bb6-bfc2-71370de0d699/image.png" alt="">
실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/6f3866fa-5ed9-4151-82e7-155bdd4bcb46/image.png" alt="">
정확한 주소로 접속했음에도 불구하고 400에러가 나는걸 확인 할 수 있습니다. 
(마치 에러처리를 하듯 상황에 맞는 에러를 전달하면 됩니다. )
new ResponseEntity&lt;&gt;(HttpStatus.BAD_REQUEST);
ㄴ&gt; 익명클래스</p>
<p>메세지만 전달할 수 있는것은 아닙니다.
에러가 발생했음에도 불구하고, 데이터를 동시에 전달해야 하는 경우도 있는데 ResponseEntity 객체를 생성할때 파라미터를 2개 넣어주면 됩니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/d1c407c7-9a3b-413b-b302-703b82f4e3e1/image.png" alt="">
실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/24091948-bbea-4800-93c0-0b543d91c8c6/image.png" alt="">
데이터는 보여주며 404에러를 발생시킬수도 있습니다.
보통 호출한쪽에 에러의 원인과 함께 원인데이터를 제공할때 사용합니다. </p>
<p>===
rest 방식 개발
get - 데이터 조회
post - 데이터 삽입
put - 데이터 수정
delete - 데이터의 삭제 
URL부터 시작해 모든 부분을 REST방식으로 구성해 댓글비스를 개발하겠습니다. </p>
<p>==
oraclel를 켜 댓글을 위한 테이블을 작성해줍니다.
댓글은 글과 무조건 연동되기 때문에 이를 감안해, 외래 키까지 걸어주도록 하겠습니다.
쿼리문을 실행해 테이블을 생성후, SpringBoardPrj로 옮겨 작성합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/256f5a8c-70b2-4a2c-8d6f-65d7fd2495cc/image.png" alt=""></p>
<p>다시 SpringBoardPrj 게시판 프로젝트로 돌아와주시고
domain에 이제 리플 관련 정보를 처리할 수 있는 VO를 생성합니다. 
SpringBoardPrj - com.ict.domain / 우클릭 new / class / ReplyVO 생성
ReplyVO 
<img src="https://velog.velcdn.com/images/one_2s/post/5c2307f1-8179-4411-9768-83170746e54c/image.png" alt=""></p>
<p>com.ict.mapper / 우클릭 new / interface / ReplyMapper.java 생성
com.ict.mapper / 우클릭 new / interface / ReplyMapper.xml 생성
<img src="https://velog.velcdn.com/images/one_2s/post/bf7336e1-e4c8-48d2-992e-ebf734145b83/image.png" alt="">
ReplyMapper.java
<img src="https://velog.velcdn.com/images/one_2s/post/7d803d0d-503d-4843-9b83-a3491347a8e6/image.png" alt="">
ReplyMapper.xml
<img src="https://velog.velcdn.com/images/one_2s/post/a2f508fb-c1ff-4f76-9fad-bf49b2edb78e/image.png" alt="">
위에 작성하고
<img src="https://velog.velcdn.com/images/one_2s/post/5fd5cd4f-faee-4ebe-9cb0-9fb23fe9074f/image.png" alt="">
쿼리문 작성해주면 됩니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/7c9b454a-5c0a-4a7c-b57b-77d123159514/image.png" alt=""></p>
<p>com.ict.service / 우클릭 new / interface / ReplyService.java 생성</p>
<p>com.ict.service / 우클릭 new / class / ReplyService.Impl.java생성
<img src="https://velog.velcdn.com/images/one_2s/post/b6b0e7e2-4b86-4204-9955-c5a3d509d65e/image.png" alt="">
ReplyService.java
<img src="https://velog.velcdn.com/images/one_2s/post/9d65bced-48d5-4b75-8d4b-42a326b6ae27/image.png" alt="">
(ReplyService.java는 com.ict.mapper를 복사하면됨.)
ReplyService.Impl.java
<img src="https://velog.velcdn.com/images/one_2s/post/3f747fda-b2de-4cd7-903c-02acef9ecefe/image.png" alt=""></p>
<p>com.ict.controller / 우클릭 / new / class / ReplyController.java 생성
컨트롤러가 기능을 사용할 수 있도록 서비스 객체도 내부에 생성합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/5c0f4d2e-6a64-4ac0-8ee6-7845bdeffed7/image.png" alt="">
상단의 작성해주고 @RequestController(화면단이 없음)</p>
<p>컨트롤러에 대한 rest 방식 요청을 하기위해 크롬창의 메뉴 -&gt; 도구 -&gt; 더보기 -&gt; 확장프로그램에 들어가서 
메뉴바를 열어 좌측하단에 Chrome웹 스토어를 열고 rest client를 검색후 Y.A.R.C를 클릭해 다운받아 줍니다. (고정도 해줌)
<img src="https://velog.velcdn.com/images/one_2s/post/932a9a9b-cecb-4aa5-bdf3-97b3ca326a86/image.png" alt="">
어떤 메서드로 요청할지를 정할수 있어서 기존의 get, post외에도  put/patch,delete요청이 가능합니다. </p>
<p>다시 컨트롤러로 와서 registger를 추가해줍니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/e27a1c7e-3560-4c57-96b1-3f43073de11e/image.png" alt="">
post방식의 글 추가 패턴은 consumes는 전달할 데이터의 형태를 저장하는것으로 json인 경우 위와 같이 적습니다. 
priduce 역시 json 데이터 처리시 위와 같이 작성합니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[rest & 새프로젝트 세팅하는 방법]]></title>
            <link>https://velog.io/@one_2s/rest-%EC%83%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%ED%8C%85%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@one_2s/rest-%EC%83%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%ED%8C%85%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Sun, 17 Apr 2022 12:11:07 GMT</pubDate>
            <description><![CDATA[<p>Rest 는 Representational Transfer의 약어로,
기존의 url에 파라미터를 붙여서 정보를 처리하는 대신
url 자체가 1:1로 어떤 자원인가를 매칭해 나타내도록 설계하는 개념입니다.
원래 웹은 컴퓨터용 웹 브라우저 하나만을 고려해도 되었지만
스마트폰, 태블릿 등의 등장 이후로 어플리케이션, 브라우저와 더불어 여러 종류의 하드웨어까지 고려야해야 하기 때문에 서버에서 모든기기에서 통용될수 있는 자료만 내주자는 흐름이 생겼습니다. </p>
<p>연습용 프로젝트를 만들어 보겠습니다. 
file - new - Spring Legacy Project 클릭
Project name = prj_rest_2 
Spring MVC Project 클릭
<img src="https://velog.velcdn.com/images/one_2s/post/0481091e-7649-4aa2-94df-1983def49415/image.png" alt="">
com.ict.controller 작성하고 finish
<img src="https://velog.velcdn.com/images/one_2s/post/5ee8cc01-5e3d-48a6-a243-163214468cef/image.png" alt="">
pom.xml 내부 수치변경을 진행합니다.
11번 라인
<img src="https://velog.velcdn.com/images/one_2s/post/868d267d-c6ef-4c60-9ee0-ca88bed25011/image.png" alt="">
94번 라인
<img src="https://velog.velcdn.com/images/one_2s/post/c0754d33-9f40-4afb-a68b-5805cfbad310/image.png" alt="">
116번 라인
<img src="https://velog.velcdn.com/images/one_2s/post/129ed12b-bc62-4e40-9820-df2bcc2b7009/image.png" alt="">
139번 라인
<img src="https://velog.velcdn.com/images/one_2s/post/4071454f-635a-4fb7-9cff-929bb2ee00b2/image.png" alt="">
수정 해준다.
그리고
Mvnrepository에서 
spring-test 5.0.7.Release 버전
spring JDBC 5.0.7 Release 버전
spring-tx 5.0.7.Release 버전
hikariCP 4.0.3 버전
mybatis 3.5.6 버전
mybatis-spring 2.0.6 버전
log4jdbc-log4j2-jdbc 1.16 버전
(한 칸 아래 JDBC 4.1과 혼동X)
lombok 1.18.18 버전
ojdbc8 18.15.0.0 버전 
검색해서 복사하고 붙여넣기 해준다. 
<img src="https://velog.velcdn.com/images/one_2s/post/b309989e-6fe2-4cb6-86f3-4b88120257c9/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/5fd9acd8-f111-4097-bd89-f9bf94f78fd8/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/42824894-4a78-4a99-a512-cd1b9555103f/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/26cfe61a-5102-4681-9c21-6fcc38c9c414/image.png" alt=""></p>
<p>프로젝트 파일 우클릭 -&gt; Maver -&gt; Update Project를 클릭해
자바버전을 1.8버전으로 업데이트 합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/7071d1e4-2a96-484b-a5cc-e69a2118f635/image.png" alt=""></p>
<p>프로젝트의  src/main/resources 폴더에 
log4jdbc.log4j2.properties 라는 이름으로 file를 생성하고 내용을 위와 같이 적습니다. 
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
<img src="https://velog.velcdn.com/images/one_2s/post/0b314844-99f3-4551-8a51-0654bf0b229b/image.png" alt=""></p>
<p>Root-context.xml로 이동해 hikariCP 관련 설정과 마이바티스 관련 설정을 진행합니다.
먼저 hikairCP의 HikariConfig와  HikariDataSource 객체를 
bean-container에 넣어줍니다.
<img src="https://velog.velcdn.com/images/one_2s/post/c27b4201-bf6b-4400-b6cd-75c2bda100c4/image.png" alt=""></p>
<p>root-context.xml파일 하단의 Namespaces 탭을 클릭하고 
mybatis-spring, context을 체크합니다. 
<img src="https://velog.velcdn.com/images/one_2s/post/8d82a75d-3138-4de2-84ab-e708eb78d3e5/image.png" alt=""></p>
<p>이후 sqlSessionFactory 객체를 생성한 다음 밑에 마이바티스 스캔을 하고, root-context.xml 하단의 Beans Graph 탭을 클릭해서 제대로 객체들이 들어왔나 체크 합니다.
(또는 S가 붙었는지)
<img src="https://velog.velcdn.com/images/one_2s/post/0ee84aec-6731-4cb1-9f7f-f44d6e73b2f5/image.png" alt="">
<img src="https://velog.velcdn.com/images/one_2s/post/15e253e8-2c3a-46d8-9fea-b50f2c3fe652/image.png" alt=""></p>
<p>한글 인코딩을 처리하기 위해
web.xml 파일의 web-app 태그 사이에 위와 같이 적어넣습니다. 
일부 화면에 표시되는 한글, 그리고 폼에서 POST로 전송되는 한글 처리를 위해 이렇게 세팅해주면 됩니다.
<img src="https://velog.velcdn.com/images/one_2s/post/512bffdb-0892-46cc-b5a9-55e4d0037dfd/image.png" alt=""></p>
<p>src/test/java
com.ict.controller 우클릭 / 패키지
com.ict.persistence 생성</p>
<p>com.ict.persistence 우클릭 / new class / OracleConnectionPoolTest 생성
<img src="https://velog.velcdn.com/images/one_2s/post/f9559146-fa49-4067-923a-20d2a2378459/image.png" alt=""></p>
<p>OracleConnectionPoolTest 
커넥션풀을 하기위해 
<img src="https://velog.velcdn.com/images/one_2s/post/826dd4e4-9aca-4375-856b-0268cc6dbe76/image.png" alt="">
 테스트 하기 위해
 <img src="https://velog.velcdn.com/images/one_2s/post/2e29f7c7-226f-40ce-bb41-c45520206db2/image.png" alt="">
작성</p>
<p>실행하면
<img src="https://velog.velcdn.com/images/one_2s/post/edf6f8bc-056c-472b-9717-d7f619b19fbc/image.png" alt=""></p>
<p>초록불, 마이바티스 연결시작! 나오면 성공!</p>
]]></description>
        </item>
    </channel>
</rss>