개요

Swagger 설정 중 아래와 같은 에러가 났다.

UnsatisfiedDependencyException: Error creating bean with name '...' defined in URL

UnsatisfiedDependencyException 관련해서 8개의 에러가 나타났다.

 

원인

spring context와 관련된 설정이 중복되어 발생한 에러이다.

 

해결 방법

@EnableWebMvc(@EnableSwagger2)를 사용하는 파일에서 @Configuration를 삭제한다.

반응형

오류 원인

JDBC dependency가 추가된 상태에서 dataasource를 설정해주지 않았을 때 발생

Spring의 다양한 기본 환경 설정을 완료한 프로젝트 zip 파일을 제공하는

https://start.spring.io/

사이트에서 프로젝트를 생성하여 실행한 결과

Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dataSource' defined in class path resource 
[org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: 
Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: 
Factory method 'dataSource' threw exception with message: 
Failed to determine a suitable driver class

이러한 오류를 마주하였다.

 

해결 방법

1. DB를 구축한다

2. application.properties에 DB 설정 정보를 아래와 같이 추가해준다.

# DB
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/csv_data?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&requireSSL=false&serverTimezone=Asia/Seoul&allowMultiQueries=true
spring.datasource.username=[데이터베이스 유저 이름]
spring.datasource.password=[데이터베이스 암호]

3. BUILD SUCCESSFUL 메시지와 함께 미소를 짓는다.

 

참고

위 datasource 설정의 spring.datasource.driver-class-name 부분을 보면

com.mysql.cj.jdbc.Driver로 설정되어있다.

기존에는 com.mysql.jdbc.Driver를 썼으나 mysql-connector-java 6 이후로 deprecated 됐다

com.mysql.cj.jdbc.Driver를 쓰게 되면 다음과 같은 오류 메시지를 받는다.

The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

com.mysql.cj.jdbc.Driver를 쓰도록 한다.

반응형

 

개요

 

서버 API를 구현하다 보면 GET과 POST를 볼 수 있다.

필자는 이 둘의 차이가 Parameter가 URL에 표시되는지 정도 차이인 줄 알았다.

이 둘의 정확한 차이점과 사용이유를 알아보자.

 

GET과 POST의 차이점

 

흔히들 DB로부터 데이터 리스트를 불러올 때는 GET

생성, 수정, 삭제 등 데이터 변경 시 POST를 사용한다고 알고 있다. 왜 그럴까?

GET과 POST의 특징

GET POST
GET 요청은 실패 시 될 때까지 반복한다. POST 요청은 실패 시 반복하지 않는다.
캐시 가능하다. 캐시 불가능하다.
히트토리에 남는다. 히스토리에 남지 않는다.
북마크 될 수 있다. 북마크 될 수 없다.
파라미터가 노출된다. 파라미터가 노출되지 않는다.

 

필자가 알았던 건 맨 밑 사항이고

제일 중요한 사항은 맨 위 사항이다.

GET 요청은 실패 시 요청이 성공할 때까지 반복하여 요청한다.

인터넷 비연결 시 웹 페이지를 로드하면 웹 페이지가 뜨지 않다가

인터넷이 연결됐을 때 웹 페이지가 새로고침 되면서

화면에 나타나는 경우를 보았을 것이다. 이는 GET의 특성 때문이다.

 

하지만 POST가 같은 동작을 한다면 실패 시 요청이 계속 들어가고

혹여나 데이터 변형이 중복으로 적용될 수 있다. 이는 오류 발생으로 직결된다.

따라서 POST는 설계 상 실패 시 반복 요청하지 않게 설계돼있다.

이러한 차이가 있어서 리스트와 업데이트에 GET과 POST를 쓰는 것이다.  

 

반응형

 

데이터 베이스 구축은 해당 게시물을 참조한다.

2021.06.28 - [Database] - [Database] 유저별로 메뉴 다르게 보이기

 

[Database] 유저별로 메뉴 다르게 보이기

개요 유저 별로 사이트의 메뉴가 다르게 나오기 위해 데이터베이스를 구축한다. 해당 프로그램에선 2 depth의 메뉴 리스트를 만들 예정이다. 구현 테이블은 2개가 필요하다. 1. 메뉴 테이블 2. 유저

gomgomkim.tistory.com

 

Spring을 활용하여 구축한 데이터베이스를 활용하여

프런트에 유저별 접근 가능한 메뉴 정보를 줄 것이다.

 

0. Mybatis generator를 활용하여 Menu에 관한 mapper java, mapper xml, data를 생성한다. 

 

1. 데이터를 다룰 DTO를 생성한다.

유저 정보, Menu 정보, 서브메뉴 정보를 담는다.

@Data
public class AdminAuthMenuResponse {
	private Integer idx;

	private Integer adminUserIdx;
	
	private String name;
	
	private String nameKr;
	
	private String path;
	
	private Integer parentIdx;
	
	private Byte auth;
	
	private List<Menu> subMenu;
}

 

2. Mapper.java에 사용할 메서드를 정의한다.

파라미터로 유저 idx를 넘겨 해당 유저가 사용 가능한 메뉴를 리턴할 메서드이다.

List<AdminAuthMenuResponse> getAllAdminAuthMenu(Integer idx);

 

3. Mapper.xml에 쿼리를 작성한다.

3-1. 리턴할 결과 데이터를 담을 resultMap을 생성한다.

collection을 통해 서브메뉴를 불러올 예정이다.

메뉴 IDX유저 IDX를 파라미터로 넘겨 해당 메뉴의 서브메뉴 중 유저가 사용 가능한 메뉴를 불러온다.

서브 쿼리는 3-3 참고

collection 작성법은 해당 게시글 참고

2021.06.18 - [Spring] - [Spring] MyBatis resultMap collection 사용법

 

[Spring] MyBatis resultMap collection 사용법

개요 mybatis에서 테이블 간의 1:N 관계를 select 할 때 resultMap의 collection을 활용하여 서브쿼리 형식으로 데이터를 가져올 수 있다. 서브 쿼리를 직접 구현하지 않아도 되는 점에서 편리했다. 배달대

gomgomkim.tistory.com

 <resultMap id="AdminAuthMenuMap" type="[경로].AdminAuthMenuResponse">
    <id column="IDX" jdbcType="INTEGER" property="idx" />
    <id column="ADMIN_USER_IDX" jdbcType="INTEGER" property="adminUserIdx" />
    <result column="NAME" jdbcType="VARCHAR" property="name" />
    <result column="NAME_KR" jdbcType="VARCHAR" property="nameKr" />
    <result column="PATH" jdbcType="VARCHAR" property="path" />
    <result column="PARENT_IDX" jdbcType="INTEGER" property="parentIdx" />
    <result column="AUTH" jdbcType="TINYINT" property="auth" />
    <collection property="subMenu" column="{idx=IDX, adminUserIdx=ADMIN_USER_IDX}" javaType="java.util.ArrayList" select="selectSubMenu" 
          ofType="[경로].Menu"/>
  </resultMap>

 

3-2. Mapper.java에 정의된 메서드 이름으로 SQL 구문을 구현한다.

<select id="getAllAdminAuthMenu" parameterType="java.lang.Integer" resultMap="AdminAuthMenuMap">
    select M.IDX, M.`NAME`, M.NAME_KR, M.PATH, M.PARENT_IDX, AUA.AUTH, AUA.ADMIN_USER_IDX
    from admin_user_auth AUA 
      join menu M on AUA.MENU_IDX = M.IDX
    where AUA.ADMIN_USER_IDX = #{adminUserIdx,jdbcType=INTEGER} AND AUA.AUTH = 1 AND M.PARENT_IDX = 0
</select>

 

3-2-1. 유저와 메뉴 테이블을 JOIN 하여 유저별 사용 가능 메뉴를 부른다.

3-2-2. 유저 IDX를 파라미터로 받아 유저별로 불러온다.

3-2-3. AUTH = 1을 통해 사용 가능한 메뉴만 불러온다.

3-2-4. PARENT_IDX = 0을 통해 루트 메뉴만 불러온다.

 

3-3. 서브 메뉴를 불러올 서브 쿼리를 작성한다. collection에 선언한 함수명으로 이름을 지정한다.

메뉴 테이블의 SELF JOIN을 통해 파라미터로 받은 메뉴의 서브 메뉴를 불러온다.

<select id="selectSubMenu" parameterType="java.util.Map" resultMap="BaseResultMap">
    select m2.IDX, m2.NAME, m2.NAME_KR, m2.PATH, m2.PARENT_IDX
    from admin_user_auth aua 
      inner join menu m on aua.MENU_IDX = m.IDX
      inner join menu m2 on m.IDX = m2.PARENT_IDX
    where m.IDX = #{idx} 
      and aua.ADMIN_USER_IDX = #{adminUserIdx}
      and aua.AUTH = 1
 </select>

 

4. Service.java에서 작성한 mapper 호출 후 유저 별 사용 가능 테이블 정보를 받아서

유저 클래스에 세팅해준다. (유저 관련 데이터 및 메서드는 다른 분야라 해당 게시글에서는 생략)

List<AdminAuthMenuResponse> userMenuAuthes = menuMapper.getAllAdminAuthMenu(authenticationToken.getAdminUser().getIdx());
adminUser.setAdminAuth(userMenuAuthes);
반응형

+ Recent posts