먼저, 기본적인 설명은 http://www.mybatis.org/jpetstore-6/ko/에 잘 정리되어 있다.
여기서는 jpetstore와 spring-jpetstore의 차이를
두 가지로 정리하면서 코드를 둘러봤다.
먼저, JPetStore 예제들은 기본적으로
다음 그림과 같이 MVC(Model–View–Controller)를 지키고 있다.
사용자에 의해 Action(Control)이 호출되고,
데이터 가공이 필요하면 서비스를 통해 DBMS를 제어하고
적절한 가공을 해서 JSP(HTML)로 변환해서
클라이언트(웹브라우저)에게 전송하는 구조를 가지고 있다.
이상의 그림은 MVC에 맞춰서 그렸다기 보다는
jpetstore의 구성 클래스가 존재하는 디렉토리 명 중심으로 작성하였다.
예로, 위 그림에 맞추어
jpetstore의 동물에 대한 분류 화면을 대상으로 함수들을 정리했다.
분류의 첫 화면(http://localhost:8080/jpetstore/actions/Catalog.action)은
HTML로 구성되어 서비스와 매퍼가 사용되지 않아서 넘어가고
상세 분류(Catalog.action?viewCategory=&categoryId=FISH)화면을 대상으로 한다.
Stripes로 인해 URL이 다소 특이하지만
Stripes에 대해서는 찾아보길 바라고 여기서는 간단하게 정리한다.
Spring MVC에서는 viewCategory.action으로 호출하게 되는데
viewCategory 컨트롤이 작성된 클래스의 파라메터처럼 호출한다.
쇼핑몰 구조에서 정리한 동물분류와 관련된 모든 기능은
CatalogActionBean.java에 각각의 함수로 구현되고,
상세 분류(viewCategory)처럼 파라메터로 호출된다.
위 그림에 맞추어 실제 코드를 확인해 보길 바라고,
사용자가 동물 분류중 하나를 선택하면
CatalogActionBean.java에 있는 viewCategory Action이 실행된다.
viewCategory Action에서는 파라메터로
사용자가 선택한 동물 분류(categoryId)가 넘어 오고,
이 분류를 파라메터로 분류별 동물 리스트(getProductListByCategory)를
데이터 베이스에서 찾아온다(CatalogService).
(코드에서는 제품-product-로 사용했는데 동물을 제품으로 부르기...)
spring-jpetstore도 위 그림에 맞추어
다음과 같이 정리했다.
spring-jpetstore는 Spring MVC에 맞추어 개발되어
Action이 아닌 Controller란 말을 사용한다.
viewCategory에 흔히 보는 @RequestMapping도 사용되었다.
웹사이트에서 접속된 URL을 확인하면
다음과 같이 직접 호출된다.
http://localhost:8080/spring-jpetstore/catalog/viewCategory?categoryId=FISH
jpetstore와 spring-jpetstore의 두번째 차이는 로그인 처리이다.
jpetstore에서 원하는 동물을 카트에 넣고
결제를 하려고 하면 다음과 같은 로그인 창이 나타난다.
로그인을 하고 결제를 한뒤,
페이지 상단에 있는 Sign Out 버튼을 이용하여 로그아웃한다.
즉, 로그인 되지 않은 상태에서
자신의 정보를 수정하거나(http://localhost:8080/jpetstore/actions/Account.action?editAccountForm=)
주문 내역을(http://localhost:8080/jpetstore/actions/Order.action?listOrders=)
직접 접속할 경우 빈 값이나 오류 페이지를 보게 된다.
jpetstore는로그인 체크를 하지 않은 것이다.
이처럼 사용자가 로그인을 하지 않은 경우 로그인 페이지로 이동하도록 해야 한다.
다음 코드와 같이 결제를 하려고 할때(newOrderForm)에만
로그인 체크를 하고 있다.
public Resolution newOrderForm() {
HttpSession session = context.getRequest().getSession();
AccountActionBean accountBean = (AccountActionBean) session.getAttribute("/actions/Account.action");
CartActionBean cartBean = (CartActionBean) session.getAttribute("/actions/Cart.action");
clear();
if (accountBean == null || !accountBean.isAuthenticated()) {
setMessage("You must sign on before attempting to check out. Please sign on and try checking out again.");
return new ForwardResolution(AccountActionBean.class);
} else if (cartBean != null) {
order.initOrder(accountBean.getAccount(), cartBean.getCart());
return new ForwardResolution(NEW_ORDER);
} else {
setMessage("An order could not be created because a cart could not be found.");
return new ForwardResolution(ERROR);
}
}
반면, spring-jpetstore는 다음 코드에 나타난 것과 같이
로그인 체크를 하고 있지 않다.
@RequestMapping("newOrderForm")
public String newOrderForm(OrderForm orderForm, Model model) {
UserDetails userDetails = (UserDetails) SecurityContextHolder
.getContext().getAuthentication().getPrincipal();
Account account = userDetails.getAccount();
Order order = new Order();
order.initOrder(account, cart);
beanMapper.map(order, orderForm);
model.addAttribute(order);
return "order/NewOrderForm";
}
spring-jpetstore는 Spring Security를 적용하여
spring-security.xml에 로그인이 필요한 페이지를 지정하고 있다.
<sec:http auto-config="true" use-expressions="true">
<sec:form-login login-page="/account/signonForm"
login-processing-url="/account/signon"
authentication-failure-url="/account/signonForm?error=true" />
<sec:logout delete-cookies="JSESSIONID" logout-url="/account/signoff"
logout-success-url="/" />
<sec:intercept-url pattern="/account/editAccount*"
access="isAuthenticated()" />
<sec:intercept-url pattern="/order/**" access="isAuthenticated()" />
</sec:http>
따라서 계정정보 수정(editAccount)이나 주문(order) 등의 페이지를 실행할 때,
로그인을 하지 않은 경우 로그인 창이 실행된다.
이외에 jpetstore에는 JUnit을 이용하여
데이터를 가지고 오는 서비스와 관련된 부분에
단위 테스트가 적용되어 있다.
그림과 같이 테스트할 파일을 선택하고
Run As > JUnit Test로 간단하게 실행해서
정상 실행 되는지 확인해 보자 (그림 중앙 하단).
'Java > JPetStore' 카테고리의 다른 글
1. JPetStore (2) | 2016.11.06 |
---|---|
2. JPetStore 설치 (2) | 2016.11.06 |
3. JPetStore - 쇼핑몰 구조 (0) | 2016.11.06 |