아래 코드처럼 파라미터로 넘어오는 2개의 클래스가 있고 해당 클래스에는 id 라는 변수가 둘다 존재합니다. 이럴 때

source = 해당클래스.id 이런식으로도 매핑이 가능합니다.

@Mapper(componentModel = "spring")
interface QuestionMapper {

    fun toEntity(request: RequestSaveQuestion, member: Member): Question

    @Mapping(source = "question.id", target = "question_id")
    fun toResponse(question: Question, member: Member): QuestionResponse
}

 

이번에 여러 문제를 담을 table을 개발하고 쿼리스트링으로 여러 조건을 건내받기를 원했다. 이번에 선택한 방법은 하나의 파라미터에

difficulty=HARD-NORMAL 이런식으로 담겨오면 -값을 기준으로 스플릿하여 배열처럼 사용하였지만 id =1, id=2, id=3 이런식으로 하여서 배열처럼 받아올 수도 있는 것 같다 해당 방식은 아래 블로그를 참조하였다.

 

https://webisfree.com/2017-03-28/쿼리스트링-파라미터를-배열로-전달하는-방법은-어떤게-있을까요

 

쿼리스트링 파라미터를 배열로 전달하는 방법은 어떤게 있을까요?

자바스크립트에서 서버에 쿼리스트링(querystring)으로 파라미터 값을 전달하려고 합니다. 이때 전달 할 값이 하나가 아닌 여러 개인 경우 어떻게 하면 배열로 전달하는지 알아봅니다.

webisfree.com

 

Database Navigator -> DB선택 후 우클릭 -> Connection view -> Advanced 클릭

Internet gateway(IGW)

 - 인터넷으로 나가는 통로이다. 스타크래프트의 게이트웨이를 통해 외계에서 질럿이 소환되는 것과 비슷한 원리이다.

 - Private subnet은 IGW로 연결되어 있지 않다.

 

Route table

  - 트래픽이 어디로 가야 할지 알려주는 테이블

  - VPC 생성 시 자동으로 만들어줌

 

NACL(Network Access Control List)/Security Group

  - 보안 검문소

  - NACL -> Stateless, SG -> Stateful

  - Access Block은 NACL에서만 가능

  

NAT(Network Address Translation) instance/gateway

  - Private VPC subnet 인터넷 게이트웨이 밖으로 연결되기 위해서 사용된다.

  - Public Subnet을 거처서 Private 으로 연결된다.

  - NAT instance는 ec2를 사용해서 구현된다.

  - Net instance/ Net Gateway는 Public Subnet에 있어야 한다.

 

Bastion host

  - 인터넷에서 private subnet에 접근하기 위해서 사용된다.

  - Public subnet 내에 위치하는 EC2

 

VPC endpoint

  - 서비스에 비공개로 연결, 퍼블릭 IP 주소를 필요로 하지 않는다.

  - Aws의 여러 서비스들과 VPC를 연결시켜주는 중간 매개체

  - Route Table을 통해 외부로 나가지못하는 Private VPC Subnt을 위해서 밖에 몰래 나가도록 도와준다.

 

 

 

크롬 드라이버의 find_element_by_css_selector 를 통해서 element를 python으로 가져와서 사용할 수 있다.

 

카카오맵 엘레먼트 찾기

  1. 원하는 엘레먼트를 찾은 후 우클릭하여 검사한다.
  2. 해당 엘레먼트를 검사 창에서 다시 우클릭한 후 Copy > Copy selector 를 선택한다.
  3. 해당 값을 find_element_by_css_selector 의 매게변수로 전달한다.

 

travis-ci를 더이상 무료로 사용할 수 없기에 수동으로 제배포 하기로 했다.

우선 프로젝트가 8080포트를 사용하기에 8080포트를 사용중인 프로젝트를 죽인다.

 

8080포트 사용중인 프로세스 종료 시키기

lsof -i tcp:8080
kill $(lsof -t -i:8080)

 

8080포트를 사용중인 프로젝트를 죽였다면 

프로젝트 경로로 이동후 프로젝트 제거

프로젝트 폴더와 해당 내부의 파일을 동시에 제거하기 위한 명령어는 아래와 같다

rm -rf 폴더이름

일반적으로 rm만으로는 폴더에 프로젝트가 존재하면 제거할 수 없다.

빈 폴더면 rmdir로 제거하면 된다.

깃 클론을 이용해서 다시 프로젝트를 받는다.

 

gradlew를 사용하기 위해서 권한 설정을 한다.

chmod +x ./gradlew

 

다음으로 테스트를 수행한다.

./gradlew test

 

다 되었으면 작성해둔 deploy.sh를 실행시킨다.

./deploy.sh

<맞는 코드>

List<Article> findTop4ByCategoryNotOrderByViewCountDesc(String category);

 

<틀린 코드>

List<Article> findTop4ByCategoryNotAndOrderByViewCountDesc(String category);

ORDERBY중간에 AND를 사용하면 안 된다.

ORDERBY의 경우 WHERE 절의 조건이 아님으로 AND를 사용할 필요 없다.

나의 경우 ORDERBY 앞에 AND로 연결하고 조금 헤매게 되었다.

오늘 게시글이나 버튼을 중앙에 배치하고 싶어서 여러 가지 찾아보게 되었다.

우선 버튼을 중앙에 배치하는 방법이다. 이 방법은 div 같은 태그 안의 요소들을 중앙에 배치할 때 유용하다.

style="justify-content:center; display:flex;

bootstrap을 사용한 중앙에 게시글 수정 요소를 나타낼 때 사용했던 방법이다.

<div class="row">
	<div class="col"></div>
	<div class="col-md-6"></div>
	<div class="col"></div>
</div>

위와 같이 html을 작성하면 부트스트랩이 중앙에 정렬을 원하는 요소를 정렬해준다.

 

이번에는 JPA 페이지 사용법을 정리하겠다.

 

Repository

 List<Article> findByCategory(String category, Pageable pageable);

Service

    @Transactional(readOnly = true)
    public List<ArticleListResponseDto> findByCategory(String category, Pageable pageable) {
        return articleRepository.findByCategory(category, pageable).stream()
                .map(ArticleListResponseDto::new)
                .collect(Collectors.toList());
    }

Controller

    @GetMapping("/majorBoard")
    public String majorBoard(Model model, @LoginUser SessionUser user, @AuthenticationPrincipal User user_s,
                            @PageableDefault(sort="id", direction=Sort.Direction.ASC) Pageable pageable)
    {
        List<ArticleListResponseDto> lst = articleService.findByCategory("major", pageable);

        return "article-select";
    }

기본적으로 위와 같이 Repository와 Service 그리고 Controller에 Pageable을 매개변수로 주고받으면 된다.

Controller에서 처음에 Pageable 객체를 받을 때는 @PageableDefault 어노테이션을 사용한다.

어떤 컬럼을 기준으로 정렬을 할지 정렬은 어떤 방식으로 할지 정할 수 있다. 

기본적으로 page 몇 개를 나타낼지 설정하지 않았다면 10개의 행만 나타낸다.

'Today I Learned' 카테고리의 다른 글

수동으로 프로젝트 제배포하기  (0) 2022.03.06
JPA를 사용하며 ORDERBY 주의점  (0) 2022.03.06
mustache로 권한 체크하기  (0) 2022.02.20
MockMvc  (0) 2022.02.03
orm, ibatis, Spring Data JPA  (0) 2022.01.31

오늘 관리자 화면 버튼을 유저가 관리자 권한을 가졌을 때만 나타나게끔 만들기로 했다.

하지만 mustache에는 Thymeleaf처럼 아래와 같은 로직을 구현하는 사용할 수 있는 방도를 찾진 못했다.

                        <a
                                class="nav-link active"
                                sec:authorize="hasAnyRole('ROLE_USER')"
                                th:href="@{/note}"
                        >

github에 mustache로 spring security 관련 코드를 찾아봤다.

해당 정보는 찾았지만 해당 코드를 사용하기 위해서는 maven 기반 프로젝트여야 했다. 나의 경우 gradle 기반이기 때문에 임포트 하는 방법에서 방법을 찾기 힘들었다.

그래서 다른 방식으로 권한을 체크하게 되었다.

 

    @GetMapping("/")
    public String main(Model model, @LoginUser SessionUser user, @AuthenticationPrincipal User user_s) {
        checkUser(model, user, user_s);
        return "main";
    }

 

    static public void checkUser(Model model, SessionUser user, User user_s){
        if (user != null) {
            model.addAttribute("nickname", user.getName());
            if(user.getRole().getKey().equals("ROLE_ADMIN"))
                model.addAttribute("isAdmin", user.getRole().getKey());
        }
        if (user_s != null) {
            model.addAttribute("nickname", user_s.getName());
            if(user.getRole().getKey().equals("ROLE_ADMIN"))
                model.addAttribute("isAdmin", user_s.getRole().getKey());
        }
    }

나의 경우 위와같은 방식으로 문제를 해결하였다. 

컨트롤러가 호출될때 유저 권한을 받아서 만약 ADMIN 권한을 가졌다면 isAdmin이라는 값을 model에 넣는 것이다. 

그렇게 하여 mustahce에서는 아래와 같이 구현하였다.

        {{#isAdmin}}
        <!-- Nav Item - Tables -->
        <li class="nav-item" sec:authorize="hasRole('ROLE_ADMIN')">
            <a class="nav-link" href="tables.html">
                <i class="fas fa-fw fa-table"></i>
                <span>관리자 화면</span></a>
        </li>
        {{/isAdmin}}

관리자의 권한을 가졌다면 자연스럽게 관리자 화면 버튼 클릭 버튼이 생성될 것이고 아니라면 생성되지 않을 것이다.

MockMvc

 

perform

요청을 전송하는 역할을 합니다. 결과로 ResultActions 를 반환합니다.

get, post, put, delete

perform() 안에 넣어서 요철할 http method를 정합니다. 

ex)perform(get("/hello"))

params

Key value 파라미터를 전달할수 있습니다.

여러 개일 때는 params, 한개면 param을 사용합니다.

 

andExpect

응답을 검증합니다.

ex) andExpect(status().isBadRequest())

satatus() 상태를 검증합니다. isOk(200), isNotFound(404)

view() 응답으로 받은 뷰 이름을 검증합니다.

redirect() 응답으로 받은 redirect를 검증합니다.

content() 응답 body를 검증합니다.

 

andDo

일반적으로 해야할 일을 표현합니다.

andDO(print()) 하면 결과를 print합니다.

 

스프링 시큐리티의 테스트는 일반적인 컨트롤러 테스트와 약간 다릅니다.

그 이유는 유저가 로그인을 한 상태로 서비스를 이용했다는 가정하에

테스트를 진행할 수 있어야 하기 때문입니다.

시큐리티 테스트를 사용하면 테스트를 시행 전에 원하는 유저를 마치 로그인한 것 처럼 설정할 수 있습니다.

 

가짜 유저를 세팅하는 방법중 3가지 방법을 소개합니다.

@WithMockUser

특정 사용자가 존재하는 것처럼 테스트 진행할 수 있습니다.

@WithUserDetails

사용자 가짜 로그인 가능

~.with

직접 사용자를 mockMvc에 지정하는 방식입니다. 

+ Recent posts