๐Ÿ›๏ธ HONGIKINGAN CMS Developer Manual

Version 202506 | Updated 2025-06-12
๐ŸŒ Language: ๐Ÿ‡ฐ๐Ÿ‡ท ํ•œ๊ตญ์–ด ๐Ÿ‡ฒ๐Ÿ‡ณ ะœะพะฝะณะพะป ๐Ÿ‡บ๐Ÿ‡ธ English

5. ๐Ÿ“ Code Structure & Patterns

5.1 MVC Pattern Implementation

HONGIKINGAN CMS is implemented based on the Spring MVC pattern, with each layer clearly separated.

5.1.1 Controller Structure

Controllers receive client requests, call appropriate services, and pass results to views.

Main Features

Controller Example (Actual Code)

[Code Location] humanframe.backoffice.controller.bbs.AdminBbsController

@Controller
@RequestMapping("/${humanframe.admin.path}/bbs")
public class AdminBbsController extends HumanAbstractController {

    @Resource(name="bbsSettingService")
    private BbsSettingService bbsSettingService;

    @Resource(name="siteService")
    private SiteService siteService;

    @Autowired
    private MngrSession mngrSession;

    @SuppressWarnings("unchecked")
    @RequestMapping("list")
    public String list(HttpServletRequest request, Model model) throws Exception {
        HumanListVO listVO = new HumanListVO(request);
        if(mngrSession.getAuthorTy().equals("2") || mngrSession.getAuthorTy().equals("3")){//Admin
            listVO.setParam("siteNos", mngrSession.getSiteNos().length > 0?mngrSession.getSiteNos():new String[]{"0"});
            listVO.setParam("crtrId",mngrSession.getMngrId());
            if(mngrSession.getAuthorTy().equals("2")) {
                listVO.setParam("bbsNos", "");
            }else {
                if(mngrSession.getSiteMenus() != null) {
                    listVO.setParam("bbsNos", mngrSession.getBbsNos().length > 0?mngrSession.getBbsNos():new String[]{"0"});
                }else {
                    listVO.setParam("bbsNos", new String[] {"0"});
                }
            }
        }
        listVO = bbsSettingService.boardListVo(listVO);

        List<BbsCtgryVO> bbsCtgryList = bbsSettingService.listCtgry(0, null, "BBS");

        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("useAt", "Y");
        List<SiteVO> siteList = siteService.selectSiteListAll(paramMap);

        model.addAttribute("listVO", listVO);
        model.addAttribute("useAt", CodeMap.USE_AT);
        model.addAttribute("bbsTyCode", CommCodeMap.BBS_TY);
        model.addAttribute("siteList", siteList);
        model.addAttribute("bbsCtgryList", bbsCtgryList);

        return "/admin/bbs/list";
    }
    
    // Other methods...
}

5.1.2 Service Layer

The service layer handles business logic and manages transactions.

Main Features

Service Interface Example (Actual Code)

[Code Location] humanframe.backoffice.service.BbsSettingService

@SuppressWarnings("rawtypes")
public interface BbsSettingService {
    
    /**
     * Retrieve board list.
     * 
     * @param listVO Search conditions
     * @return Board list
     */
    public HumanListVO boardListVo(HumanListVO listVO) throws Exception;
    
    /**
     * Retrieve board information.
     * 
     * @param bbsNo Board number
     * @return Board information
     */
    public BbsSettingVO retrieveBoardSetting(int bbsNo) throws Exception;
    
    /**
     * Retrieve board category list.
     * 
     * @param bbsNo Board number
     * @param prefix Prefix
     * @param type Type
     * @return Category list
     */
    public List<BbsCtgryVO> listCtgry(int bbsNo, String prefix, String useTy) throws Exception;
    
    // Other methods...
}
Service Implementation Example (Actual Code)

[Code Location] humanframe.backoffice.service.impl.BbsSettingServiceImpl

@SuppressWarnings("rawtypes")
@Service("bbsSettingService")
public class BbsSettingServiceImpl extends EgovAbstractServiceImpl implements BbsSettingService {

    @Resource(name="bbsSettingDAO")
    private BbsSettingDAO bbsSettingDAO;
    
    @Resource(name="bbsScrtyDAO")
    private BbsScrtyDAO bbsScrtyDAO;
    
    @Override
    public HumanListVO boardListVo(HumanListVO listVO) throws Exception {
        return bbsSettingDAO.selectBoardListVO(listVO);
    }
    
    @Override
    public BbsSettingVO retrieveBoardSetting(int bbsNo) throws Exception {
        BbsSettingVO bbsSettingVO = bbsSettingDAO.selectBoardSetting(bbsNo, 0);

        if(bbsSettingVO.getCtgryUseAt().equals("Y")) {
            List<BbsCtgryVO> ctgryList = bbsSettingDAO.listCtgry(bbsNo, "L", "NTT");
            bbsSettingVO.setCtgryList(ctgryList);
        }
        
        // ... Omitted (security configuration logic) ...
        
        return bbsSettingVO;
    }
    
    @Override
    public List<BbsCtgryVO> listCtgry(int bbsNo, String prefix, String useTy) throws Exception {
        return bbsSettingDAO.listCtgry(bbsNo, prefix, useTy);
    }
    
    // Other methods...
}

5.1.3 DAO and MyBatis Utilization

DAO (Data Access Object) handles database interactions and uses MyBatis to manage SQL queries.

Main Features

DAO Example (Actual Code)

[Code Location] humanframe.backoffice.dao.BbsSettingDAO

@Repository("bbsSettingDAO")
public class BbsSettingDAO extends HumanAbstractMapper {

    public HumanListVO selectBoardListVO(HumanListVO listVO) throws Exception {
        return selectListVO(setDomain("boardSetting.selectBoardCount"), setDomain("boardSetting.selectBoardListVO"), listVO);
    }
    
    public BbsSettingVO selectBoardSetting(int bbsNo, int siteNo) throws Exception {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("bbsNo", bbsNo);
        if(siteNo > 0){
            paramMap.put("siteNo", siteNo);
        }
        BbsSettingVO bbsSettingVO = (BbsSettingVO)selectOne(setDomain("boardSetting.selectBoardSetting"), paramMap);
        return bbsSettingVO;
    }
    
    public List<BbsCtgryVO> listCtgry(int bbsNo, String prefix, String useTy) throws Exception {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("bbsNo", bbsNo);
        paramMap.put("prefix", prefix);
        paramMap.put("ctgryUseTy", useTy);
        return selectList(setDomain("boardCtgry.listCtgry"), paramMap);
    }
    
    // Other methods...
}
MyBatis Mapper XML Example (Actual Code)

[Code Location] humanframe/sqlmap/mappers/mysql/human-bbs-ctgry.xml

<?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="humanframe.boardCtgry">

    <resultMap type="bbsCtgryVO" id="bbsCtgryMap">
        <result property="bbsNo"       column="bbs_no" />
        <result property="ctgryNo"     column="ctgry_no" />
        <result property="ctgryValue"  column="ctgry_value" />
        <result property="ctgryNm"     column="ctgry_nm" />
    </resultMap>

    <select id="listCtgry" parameterType="hashmap" resultMap="bbsCtgryMap">
    SELECT
          bbs_no
        , ctgry_no
        <choose>
            <when test="prefix != null">
            , CONCAT('${prefix}-' , ctgry_no) AS ctgry_value
            </when>
            <otherwise>
            , '' AS ctgry_value
            </otherwise>
        </choose>
        , ctgry_nm
    FROM tn_bbs_ctgry
    WHERE bbs_no = #{bbsNo}
        AND use_at = 'Y'
    </select>

    <!-- Other queries... -->
</mapper>

5.2 MVC Architecture Structure

The MVC architecture of HONGIKINGAN CMS complies with the eGovFrame standard architecture and has the following characteristics:

๐ŸŽฎController Layer

  • Complies with eGovFrame standard architecture
  • Implemented by inheriting HumanAbstractController
  • Controller classes cannot directly call DAO class methods
  • Business logic processing through Service layer

๐Ÿ‘๏ธView Layer

  • Screen composition using JSP and Tiles
  • Data representation using JSTL and EL
  • Utilization of custom tag libraries

๐Ÿ“ŠModel Layer

  • Data transfer through VO (Value Object) classes
  • Return results after business logic processing in Service layer

5.3 Service Architecture Structure

The service architecture of HONGIKINGAN CMS has the following characteristics:

๐Ÿ”ŒService Interface

  • All services are defined as interfaces
  • Interfaces located in "service" package

โš™๏ธService Implementation

  • Implemented by extending EgovAbstractServiceImpl
  • Implementations located in "service/impl" package
  • Bean registration through @Service annotation

๐Ÿ”„Transaction Management

  • Transaction management through @Transactional annotation
  • Declarative transaction management approach applied

5.4 Data Access Architecture Structure

The data access architecture of HONGIKINGAN CMS has the following characteristics:

๐Ÿ—„๏ธDAO Classes

  • Complies with eGovFrame standard architecture
  • Implemented by inheriting HumanAbstractMapper which extends EgovAbstractMapper
  • Bean registration through @Repository annotation

๐Ÿ—บ๏ธMyBatis Mapper

  • XML-based SQL management
  • Dynamic query support
  • Support for various databases (CUBRID, Oracle, MySQL, MS-SQL, Tibero)

๐Ÿ”—Database Connection

  • JNDI-based datasource configuration
  • Profile-specific datasource configuration (local, dev, prd)

5.5 AOP Utilization

HONGIKINGAN CMS utilizes Aspect-Oriented Programming (AOP) to modularize cross-cutting concerns such as logging and permission verification.

5.5.1 Logging

AOP is utilized to record system logs and user activity logs.

Main Features

Logging AOP Example (Actual Code)

[Code Location] humanframe.backoffice.aop.aspect.admin.AdminLogAspect

@Aspect
@Order(2)
@Component
public class AdminLogAspect {

    @Resource(name = "mngLogService")
    private MngLogService mngLogService;

    // Admin permission check
    @Pointcut("execution(* humanframe.backoffice..Admin*Controller.form(..))"
            + "|| execution(* humanframe.backoffice..Admin*Controller.list(..))"
            + "|| execution(* humanframe.backoffice..Admin*Controller.view(..))"
            + "|| execution(* humanframe.backoffice..Admin*Controller.action(..))"
            + "|| execution(* humanframe.backoffice..Admin*Controller.logout(..))")
    private void checkAdminLog() {}

    @Before(value = "checkAdminLog()")
    private void beforecheckAdminLog(
            JoinPoint joinPoint)throws Exception {
        // ... Omitted (admin log storage logic) ...
    }
}

5.5.2 Permission Verification

AOP is utilized to verify access permissions for menus and functions.

Main Features

Permission Verification AOP Example (Actual Code)

[Code Location] humanframe.backoffice.aop.aspect.admin.AdminBbsAspect

@Aspect
@Order(1)
@Component
public class AdminBbsAspect {

    @Autowired
    private BbsSettingService bbsSettingService;

    @Autowired
    private MngrSession mngrSession;

    // Admin permission check
    @Pointcut("execution(* humanframe.backoffice..AdminBbsType*Controller.form(..))"
            + "|| execution(* humanframe.backoffice..AdminBbsType*Controller.list(..))"
            + "|| execution(* humanframe.backoffice..AdminBbsType*Controller.view(..))"
            + "|| execution(* humanframe.backoffice..AdminBbsType*Controller.action(..))"
            + "|| execution(* humanframe.backoffice..AdminBbsType*Controller.answer(..))")
    private void checkAdminBbsAuth() {}

    @Before(value = "checkAdminBbsAuth()")
    private void beforeCheckAdminBbsAuth(
            JoinPoint joinPoint)throws Exception {
        // ... Omitted (permission verification logic) ...
    }
}

5.6 Interceptors and Filters

HONGIKINGAN CMS utilizes interceptors and filters to perform common tasks before and after request processing. This section explains the structural aspects of interceptors and filters. For detailed security-related content, please refer to the 07 Security Guide document.

5.6.1 Filter Structure

HONGIKINGAN CMS uses various filters registered in web.xml to enhance security and data preprocessing.
Filters operate at the servlet container level in a chain manner for all HTTP requests in the order defined in web.xml.

Main Filters and Application Paths

Filter Name Applied URL Role/Description
CharacterEncodingFilter /* Unify character encoding of all requests/responses to UTF-8
HTMLTagFilter /* Remove dangerous HTML tags from input parameters
CrossUrlScriptingFilter (XSS) /* Prevent Cross-Site Scripting (XSS) attacks
XSSWebFilter /* Additional XSS security filter (filter HTML and JS risk elements according to policy)
MberLoginFilter /* Spring Security (DelegatingFilterProxy) based login processing
HumanFilter /humanmst/* Admin page exclusive: Access control, authentication/authorization verification

Filter Chain Structure

Filter Execution Order
Client Request
โ†“
[CharacterEncodingFilter]
โ†“
[HTMLTagFilter]
โ†“
[CrossUrlScriptingFilter]
โ†“
[XSSWebFilter]
โ†“
[MberLoginFilter]
โ†“
[HumanFilter] (โ€ป Only for admin page (/humanmst/*) requests)
โ†“
Servlet (DispatcherServlet, etc.)
โš ๏ธ

Operational Reference

  • Most filters are applied to all paths (/*), while HumanFilter is applied only to admin page (/humanmst/*) paths.
  • Filter execution order operates in the same order as registered in web.xml.
  • HTML/XSS filters are applied hierarchically to maximize input value security.
  • Login/authentication filters are placed at lower priority for security reasons.

5.6.2 Interceptor Structure

HONGIKINGAN CMS uses Spring MVC interceptors to apply common logic before/after HTTP request processing.
Main interceptors are registered in dispatcher-servlet.xml and have different paths and roles as follows.

Main Interceptors and Application Paths

Interceptor Name Applied Path Role/Description
CMSUriInterceptor Global (/), admin and some exceptions Site URI access control, unnecessary request blocking, etc.
CMSAdminInterceptor Admin exclusive (/humanmst/, etc.) Admin page access exclusive, authentication and authorization check
DeviceResolverHandlerInterceptor Global (Spring Mobile) Device type (mobile/PC) identification

Interceptor Chain Structure

Interceptor Execution Order
Client Request
โ†“
[DeviceResolverHandlerInterceptor] (Mobile/PC distinction)
โ†“
[CMSUriInterceptor] (Site URI access management, excluding admin)
โ†“
[CMSAdminInterceptor] (โ€ป Only for admin (/humanmst/, etc.) requests)
โ†“
Controller
โ„น๏ธ

Operational Reference

The application/exclusion paths of interceptors depend on the <mvc:interceptor> configuration in dispatcher-servlet.xml.