1. ~서비스명.do 요청하기
// functionNav -> javascript 객체로 구현
<a onclick="functionNav.fnGoto('/testpath/testView.do');">
const functionNav = {
fnGoto(url){
Call.fnGotoUrl(Util.makeUrl(url))
},
...
}
const Util = {
makeUrl : function(url){
url = url.startsWith('/') ? url.substring(1) : url;
// `(back accent) 사이에 넣으면 변수(${변수명}) + 문자열을 표현할 수 있다
return `${Common.contextPath}/${url}`
},
...
}
const Call = {
fnGotoUrl : function(path, params){
const a = document.createElement('a');
if(params 파라미터가 있는 경우){
const searchParams = new URLSearchParams();
path += '?';
for(const key in params){
searchParams.append(key, params[key]);
}
} // end if
// a태그의 href 속성에 값을 부여(path 경로)
a.href = path;
document.body.appendChild(a);
a.click();
}
}
- href 속성(hypertext reference)으로 이동할 url 전달
2. Interceptor 인터셉터로 세션 체크
@Component
public class ComInterceptor extends HandlerInterceptorAdapter {
// .do 실행하기 전 실행
public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler){
log.debug("preHandler 실행");
Device device = this.deviceResolver.resolveDevice(request);
request.setAttribute("currentDvice", device);
return true
}
// .do 실행한 후 실행
public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView){
log.debug("postHandler 실행");
if(modelAndView.getViewName().startsWith("redirect:")){
...
}
}
}
HandlerInterceptorAdapter
: org.springframework.web.servlet.handler- 추상클래스 (implements org.springframework.web.servlet.AsyncHandlerInterceptor
- 인터셉터로 요청을 보내는 중간에 처리해야할 작업이나, 이전/후에 처리해야할 작업(세션처리 등)을 끼워넣어주는 듯 하다
3. ~서비스명.do 실행
@Controller
@RequiredArgsConstructor
@RequestMapping("/testpath")
public class TestController {
@Value("${kras.api.url}")
private String apiUrl;
@GetMapping("/testView.do")
public String testView(final Device device, final Model model) {
// 망 분리 - 서버로 api 통신하여 출력 리스트값 가져오기
model.addAttribute("testList", this.getTestList("param값"));
model.addAttribute("속성명", "속성값");
// 페이지 로드
return "testPage/testList.pub";
}
}
- 보안을 위해, 요청을 보내거나 화면에 뿌리는 역할만 하는 WAS서버와(인터넷망(외부망)) 서버에서 요청을 받아 비즈니스 로직을 실행하거나 DB서버에 붙어서 데이터 처리만을 담당하는 WAS서버(내부망)로 나누어져있었다.
- 따라서 데이터를 받아오기 위해 api 요청을 보내는 함수가 따로 있음. 예시에서는
getTestList
가 그 역할
- 따라서 데이터를 받아오기 위해 api 요청을 보내는 함수가 따로 있음. 예시에서는
4. api 통신으로 데이터 받아오기
@Value(${test.api.url})
private String apiUrl;
...
private List<Map<String, String>> getTestList(String params){
HttpHeaders headers = new HttpHeaders() {{
// HTTP 헤더의 Content-type 값을 설정하는 부분인 것 같다
setContentType(MediaType.APPLICATION_JSON);
}};
Map<String, String> params = new HashMap<String, String>() {{
put("params", params);
}};
HttpEntity<String> entity = new HttpEntity<>(new JSONObject(params).toJSONString(), headers);
URI url = UriComponentsBuilder
.fromUriString(apiUrl)
.path("testApiService/selectTestList.do")
.build()
.encode()
.toUri();
// Body 리턴
// config -> RestTemplateConfiguration에 대한 설정객체인 듯 하다(사용자지정함수)
return config.restTemplate().exchange(url, HttpMethod.POST, entity, new ParameterizedTypeReference<List<Map<String, String>>>() {}).getBody();
}
5. api 호출부 처리
- 비즈니스 로직을 수행하는 서버에서 처리 (데이터만을 넘겨주는 역할)
@Service("testApiService") public class testApiServiceImpl extends TestAbstractServiceImpl implements TestService{ @Resource(name = "testDAO") private TestDAO testDAO; // test리스트 조회 public List selectTestList(TestVO testVO) throws Exception { return testDAO.selectTestList(testVO); }
}
### 5-1. 추가 : DAO 처리 부분 간단하게 파악하기
1. query 실행하는 부분 공통함수로 빼놓음 (extends TestAbstractDAO 부분에 구현)
2. ~sql.xml 파일에서 쿼리문 정의해놓고 실행
```java
// DAO 소스
@Repository("testDAO")
public class TestDAO extends TestAbstractDAO {
protected Log log = LogFactory.getLog(this.getClass());
// test리스트 조회 쿼리부분
public List selectTestList(TestVO testVO) throws Exception {
return list("testDAO.selectTestListQuery", testVO);
}
}
// list() 부분 구현된 부분 -> extends TestAbstractDAO 부분에 공통함수로 구현되어 있음
public abstract class TestAbstractDAO {
// base class로만 사용되며, 해당 인스턴스를 직접 생성할 수 없도록 protected constructor로 선언
protected TestAbstractDAO() {
}
...
// 리스트 조회 처리를 하는 SQL mapping 실행 공통함수 (ibatis)
public List<?> list(String queryId, Object parameterObj){
return getSqlMapClientTemplate().queryForList(queryId, parameterObj);
}
}
<!-- ibatis 쿼리문 xml -->
<select id="testDAO.selectTestListQuery" parameterClass="testVO" resultClass="testMap">
~쿼리문 작성~
</select>
6. .jsp 출력 (feat. apache tiles)
- 복습 : 페이지 출력하는 Controller단
@GetMapping("/testView.do") public String testView(final Device device, final Model model) { // 망 분리 - 서버로 api 통신하여 출력 리스트값 가져오기 model.addAttribute("testList", this.getTestList("param값")); model.addAttribute("속성명", "속성값"); // 페이지 로드 return "testPage/testList.pub"; }
model
객체의 'testList' 속성값으로 넘긴 객체값을 사용하여 화면에 데이터를 뿌려줄 수 있음${testList}
// 모델 객체 'tsetList' 활용예시 정리
<c:forEach var="testVar" items="${testList}" varStatus="status">
${status.count}
${testVar.key1}
${testVar.key2}
<c:choose>
<c:when test="${testVar.key1 eq null or testVar.key2 eq ''}">
</c:when>
<c:otherwise>
</c:otherwise>
</c:choose>
</c:forEach>
추가
- 구조를 다시 살펴보면
WAS서버 A
,WAS서버 B
,DB서버
이렇게 있고A
는 화면을 담당B
는 비즈니스 로직을 담당DB
는 데이터를 담당한다
A
는B
에게 화면을 요청하고,B
는DB
서버 혹은api
요청으로 데이터를 불러와서A
에게 넘겨줌B
에서 api 조회를 하기 위해DB
에서 필요한 파라미터 값을 가져오기도 함
A
는B
에게서 받은 값으로 화면을 그린다 (apache tiles 사용)
'실무기반 공부' 카테고리의 다른 글
api 조회페이지 목록 추출하기 (feat. endpoint, CXF) (2) | 2023.11.21 |
---|