개요
- 편성표 방송 알림 Count를 알려주는 API를 개발한다.
- 1) 이게 무슨 일을 하는 지, 현업에서 어떻게 활용할 지에 관한 설명
- 은 듣고 이해했지만 내 개인 블로그에 기록으로 남기기는 귀찮다.
- 내가 알아야 할 것!
- 주어진 변수로 호출하면 주어진 정보들을 Return하면 된다.
- 2) 흔한 API개발을 기록으로 남기는 이유
- 업무적으로 내쪽 업무가 아니다.
- 업무 협의(내가한거 아님) 과정에서 다 쳐내다보니 이 정도는 해주자 해서 넘어온 업무
- 기존 Application과 성격도 다르고 언제 없어져도 이상하지 않기 때문에 별도의 Directory구조로 관리를 하는 것이 좋다고 판단
- Spring Setting들을 다시 잡아줘야 했고 그 과정을 기록으로 남기고자 함
- 업무적으로 내쪽 업무가 아니다.
- 1) 이게 무슨 일을 하는 지, 현업에서 어떻게 활용할 지에 관한 설명
Log
- 1. 영혼이 시키는 대로 디렉토리 및 파일 생성
+---java
| \---iceberg
| +---admin [기존소스]
| +---common [기존소스]
| \---external [New 디렉토리]
| +---controller
| | ExternalAPIController.java [New source]
| |
| +---domain
| | BrodAlarmInfo.java [New source]
| |
| +---repository
| | \---webdb
| | WebDbExternalAPISqlMapRepository.java [New source]
| |
| \---service
| ExternalAPIService.java [New source]
|
+---resources
| +---config
| | +---log
| | +---message
| | +---properties
| | +---spring
| | | admin-datacontext.xml
| | | admin-mapper-datacontext.xml
| | | admin-servicecontext.xml
| | | admin-webcontext.xml
| | \---sqlmap
| | | sqlmap-config.xml
| | +---mysqldb
| | +---odsdb
| | +---schedule
| | +---smtcdb
| | \---webdb
| | +---deal
| | +---external [New 디렉토리]
| | | WebDbExternalAPISqlMapRepository-sql.xml [New source]
| | +---monitor
| | +---navigation
\---webapp
- 2. Controller/호출 URL작성
- ExternalAPIController.java
-
123456789101112131415161718@Controller@RequestMapping(value = "/□□□□")public class ExternalAPIController {private ExternalAPIService externalAPIService;@Autowiredpublic void setExternalAPIService(ExternalAPIService externalAPIService){this.externalAPIService = externalAPIService;}@ResponseBody@RequestMapping(value = "/□□□□-□□□□-□□□□", method = RequestMethod.GET)public List<BrodAlarmInfo> getBrodAlarmCount(@RequestParam(value="broadType", required = true) String broadType) {BrodAlarmInfo paramMap = new BrodAlarmInfo(broadType);return externalAPIService.getBrodAlarmCount(paramMap);}}
cs
-
- ExternalAPIController.java
- URL
- http://localhost:8080/□□□□/□□□□?broadType=DATA
- http://localhost:8080/□□□□/□□□□?broadType=TV
- webContext.xml : Exception pattern에 호출 URL 등록
- URL
- Postman으로 일단 Call (될리가 없을걸 알지만)
- Postman기능들 나중에 좀더 살펴보기
- 2-1. 오류
1
2
3
4
5
6
|
org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:196)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:284)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:231)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:56)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:297)
|
cs |
-
- 오류내용
- 해당 URL로 호출 되는 Contoller를 찾지 못함
- 새로 만든 Controller가 기존의 ComponentScan하는 Directory 외부에 있어 @Controller tag를 읽어서 Bean으로 등록하지 못함
- 해결 : 기존 webContext.xml - Componet Scan 부분에 새로만든 Directory 추가
- 오류내용
1
2
3
4
|
<context:component-scan base-package="iceberg.admin, iceberg.external" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
|
cs |
- 3. Domain(DTO) 및 서비스 생성
- Domain 생성 : 정의서 보고 대충만들면 된다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package iceberg.external.domain;
import java.io.Serializable;
public class BrodAlarmInfo implements Serializable{
private static final long serialVersionUID = 1L;
private String broadType;
private String broadDate;
private String closingDate;
private String onair;
private int prdCd;
private String prdNm;
private int alarmCnt;
public BrodAlarmInfo(){
}
public BrodAlarmInfo(String broadType){
this.broadType=broadType;
}
/* Getter & Setter */
}
|
cs |
-
-
- lombok도 마음대로 추가 못하는 내 처지ㅎㅎ
- 서비스도 영혼이 시키는 대로 만들기
-
-
123456789101112131415@Servicepublic class ExternalAPIService {private final WebDbExternalAPISqlMapRepository webDbExternalAPISqlMapRepository;@AutowiredExternalAPIService(WebDbExternalAPISqlMapRepository webDbExternalAPISqlMapRepository){this.webDbExternalAPISqlMapRepository = webDbExternalAPISqlMapRepository;}public List<BrodAlarmInfo> getBrodAlarmCount(BrodAlarmInfo paramMap){return webDbExternalAPISqlMapRepository.getBrodAlarmCount(paramMap);}}
cs -
-
- 3-1. 오류 (2)
123servlet.DispatcherServlet.initServletBean(470) - Context initialization failedorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'externalAPIController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void iceberg.external.controller.ExternalAPIController.setExternalAPIService(iceberg.external.service.ExternalAPIService); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [iceberg.external.service.ExternalAPIService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)cs -
-
- 오류내용 Controller에서 호출하는 Service bean을 Bean factory에서 찾을 수 없음
- 새로 만든 Service가 기존의 Component-Scan하는 Directory 외부에 있어 @Service tag를 읽어서 Bean으로 등록하지 못함
- 해결 : 기존 webContext.xml - Componet Scan 부분에 새로만든 Directory 추가
-
1234567<context:component-scan base-package="iceberg.admin, iceberg.external" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Service" /><context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" /><context:include-filter type="annotation" expression="iceberg.admin.common.annotation.Processor" /><context:include-filter type="annotation" expression="iceberg.admin.common.annotation.Factory" /><context:include-filter type="annotation" expression="iceberg.admin.common.annotation.AopProcessor" /></context:component-scan>
cs
-
- 오류내용 Controller에서 호출하는 Service bean을 Bean factory에서 찾을 수 없음
- 3-2 Service ------[DTO]-----> Repository
- Iceberg Framework에서 세팅하는 부분들이 있다.
- Iceberg에 SimpleSqlMapRepository를 구현해서 사용하는데 따라가보니 SimpleJPARepository도 있다. 여기서는 JPA를 사용하지 않지만 사용할 수 있게 프레임워크에서 제공하는 걸로 보인다. 나중에 써봐야겠다.
- 오류들을 잘 읽어서 해결
- Iceberg Framework에서 세팅하는 부분들이 있다.
-
-
3-2. 기타등등 Setting
- WebDbExternalAPISqlMapRepository.java
1
2
3
4
5
|
public interface WebDbExternalAPISqlMapRepository extends SimpleSqlMapRepository<String, String> {
List<BrodAlarmInfo> getBrodAlarmCount(BrodAlarmInfo param);
}
|
cs |
- WebDbExternalAPISqlMapRepository-sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="iceberg.external.repository.webdb.WebDbExternalAPISqlMapRepository">
<resultMap type="brodAlarmInfo" id="brodAlarmInfoMap">
<result column="BROAD_TYPE" property="broadType"/>
<result column="BROAD_DATE" property="broadDate"/>
<result column="CLOSING_DATE" property="closingDate"/>
<result column="ONAIR" property="onair"/>
<result column="PRD_CD" property="prdCd"/>
<result column="PRD_NM" property="prdNm"/>
<result column="ALARM_CNT" property="alarmCnt"/>
</resultMap>
<select id="getBrodAlarmCount" resultMap="brodAlarmInfoMap" parameterType="brodAlarmInfo">
SELECT
FROM
WHERE
</mapper>
|
cs |
- sqlmap-config.xml
1
2
3
|
<typeAliases>
<package name="iceberg.external.domain" />
</typeAliases>
|
cs |
mapper-datacontext.xml
1
2
3
4
5
|
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="iceberg.external.repository.webdb" />
<property name="markerInterface" value="iceberg.framework.core.repository.sqlmap.SimpleSqlMapRepository" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
|
cs |
[마무리]
- Domain - Service - Controller 까지 전부 다 만들어 본 적은 오랜만이었다. 회사일은 보통 누군가 만들어놓은 구조에 맞춰서 하다보면 원리도 모르고 그냥 되는 경우가 대부분이다. 이번 업무를 통해서 이 어플리케이션의 전체적인 동작 구조를 더 잘 알 수 있었다.
- 포스팅 쓰다보니 귀찮고 내용도 뭔가 깔끔하지가 않아서 짜증난다. 오늘은 이 정도에서 마무리하자 하다보면 요령이 생기겠지뭐...
'70. 회사일 > 72. Back-End일까?' 카테고리의 다른 글
API작성을 하다보면 필요한 HTTP STATUS CODE (0) | 2023.07.14 |
---|