[SpringBoot + Nexacro] Nexacro 설치 및 프로젝트 생성과 연동

2026. 6. 15. 16:13·SpringBoot

Nexacro 공부를 위해 SpringBoot + Oracle + Nexacro 토이 프로젝트를 진행하기로 함

재고 및 물품 관리 시스템으로, 현재 재고 상태를 보여주는 대시보드를 제작할 예정

 

기술 스택

Frontend Nexacro N
Backend SpringBoot 3.2.5 + MyBatis
DB Oracle XE 21c (Docker)
빌드 Gradle

 

❗JPA가 아닌 MyBatis를 선택한 이유
MyBatis는 직접 SQL문을 작성할 수 있고, DBMS별 문법을 세밀하게 제어할 수 있음
또한 Oracle과의 궁합도 좋기 때문에 Oracle 공부도 더 할겸 MyBatis를 선택함

 

💡 Nexacro 핵심 개념

Form
화면 하나 = Form 하나

React의 Page 컴포넌트와 비슷한 개념

 

Dataset
화면에서 데이터를 담는 그릇

SpringBoot API 응답을 받아서 저장하고, Grid 같은 컴포넌트에 연결

Dataset ← API 응답 데이터 저장
   ↓
Grid    ← Dataset 바라보며 화면에 표시

 

Transaction
Nexacro에서 SpringBoot API를 호출하는 방식

일반적인 fetch/axios 대신 Nexacro 전용 통신 방식을 사용함

// Nexacro 방식
this.transaction(
    "조회",                        // 트랜잭션 ID
    "SVC::getDashboard.do",        // 호출할 서비스 URL
    "",                            // 전송할 Dataset (없으면 빈칸)
    "dsDashboard=output",          // 응답 받을 Dataset
    "",                            // 파라미터
    "fn_callBack"                  // 콜백 함수명
);

 

📌 Nexacro 설치

먼저 아래 링크에서 Nexacro 체험판과 라이선스를 다운 받음

https://www.tobesoft.com/product/nexacro

 

투비소프트

DEV.TOOL 비즈니스용 UI·UX 개발 소프트웨어의 공급부터 안정적 구축, 유지보수 수행까지 기업을 위한 서비스를 제공합니다.

www.tobesoft.com

 

설치 과정은 다른 거 건드릴 필요 없이 기본 세팅된 대로 설치하면 됨

 

Nexacro 라이브러리 다운로드

xapi 라이브러리와 uiadapter 라이브러리가 필요함

  • xapi는 클라이언트(화면)와 서버 간의 데이터를 송수신하고 처리하기 위해 필요한 자바 기반 서버 모듈
  • uiadapter는 넥사크로와 서버 간 데이터 구조 차이를 보완해주는 모듈

 

아래 링크에서 com/nexacro 폴더로 이동 후 xapi 라이브러리와 uiadapter 라이브러리 다운

https://mangosteen.tobesoft.co.kr/nexus/#browse/browse:maven-public

 

Nexus Repository Manager

 

mangosteen.tobesoft.co.kr

 

❗이때 SpringBoot 3로 프로젝트를 설정했다면 Nexacro 라이브러리는 반드시 jakarta 버전으로 다운받아야 함

jakarta 버전이 아닌 라이브러리를 다운 받으면 해당 라이브러리는 javax를 사용하기 때문에 java.lang.NoClassDefFoundError: javax/servlet/ServletOutputStream 오류가 발생함

 

📌 Nexacro 프로젝트 설정

상단 메뉴에서 새 프로젝트 생성

 

넥사크로 프로젝트와 스프링부트 프로젝트를 같은 폴더에 두지 않고 분리할 것이기 때문에 프로젝트 위치는 본인이 편한 경로로 지정하면 됨

프로젝트 이름 설정하고 Next 클릭

 

이후 설정은 본인이 만들고 싶은 화면대로 설정하면 됨

나는 간단한 개인 공부용 프로젝트기 때문에 Screen은 Desktop, 템플릿은 Full로 지정함

 

이후 Finish 눌러 프로젝트 생성

 

TypeDefinition 경로 설정

nexacro에서 script를 작성할 때마다 일일이 모든 경로를 작성하기 어려우므로, 자주 쓰는 경로의 경우 별칭을 지정하면 편함

 

TypeDefinition - Services 클릭

 

User Service에서 아래 내용 등록

  • SVC - 백엔드 API 호출용. 본인의 로컬호스트 주소 e.g.) http://localhost:8080/
  • nexacrolib - 넥사크로 엔진 라이브러리

prefixID의 경우 본인이 편한대로 작성해도 됨

 

📌 SpringBoot 프로젝트 설정

앞서 다운 받았던 nexacro 관련 라이브러리를 스프링부트 프로젝트에 직접 추가해야 함

본인은 루트 폴더에 libs 폴더 생성 후 필요한 jar 파일들을 넣어두었음

 

의존성 추가

build.gradle에 로컬 jar 의존성 추가 및 라이브러리 관련 추가 의존성 추가

관련 내용은 https://naahy0co.tistory.com/83 참고

dependencies {
    // 기존 의존성들 ...

    // Nexacro 라이브러리 (로컬 jar)
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    
    // Nexacro XAPI 의존성
    implementation 'jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.1.1'
    implementation 'commons-lang:commons-lang:2.6'
}

 

로컬 jar에 대한 의존성을 새로 추가했으므로 gradle 빌드를 새로 해줘야 함

 

📌 SpringBoot - Nexacro 연동

SpringBoot CORS 설정 추가

Nexacro Studio에서 localhost로 API를 호출할 때 CORS 에러가 나기 때문에 미리 열어둬야 함

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

 

Nexacro Config 작성

Spring MVC의 기본 JSON 기반 요청/응답 처리 체계를 Nexacro Dataset/XML 기반 처리 체계로 교체하는 설정 클래스

import com.nexacro.java.xapi.tx.PlatformType;
import com.nexacro.uiadapter.jakarta.core.context.ApplicationContextProvider;
import com.nexacro.uiadapter.jakarta.core.resolve.NexacroHandlerMethodReturnValueHandler;
import com.nexacro.uiadapter.jakarta.core.resolve.NexacroMappingExceptionResolver;
import com.nexacro.uiadapter.jakarta.core.resolve.NexacroMethodArgumentResolver;
import com.nexacro.uiadapter.jakarta.core.resolve.NexacroRequestMappingHandlerAdapter;
import com.nexacro.uiadapter.jakarta.core.view.NexacroFileView;
import com.nexacro.uiadapter.jakarta.core.view.NexacroView;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import java.util.List;

@Configuration
public class NexacroConfig extends WebConfig implements WebMvcRegistrations {

    /**
     * Spring Bean들을 Nexacro 내부에서도 참조할 수 있게 함
     */
    @Bean
    @Lazy(false)
    public ApplicationContextProvider applicationContextProvider() {
        return new ApplicationContextProvider();
    }

    /**
     * SpringAdapter를 NexacroAdapter로 교체
     * Spring MVC를 Nexacro용으로 교체
     */
    @Override
    public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
        return new NexacroRequestMappingHandlerAdapter();
    }

    /**
     * Controller 파라미터 해석기 등록
     * Dataset --> Java 객체 변환기
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        NexacroMethodArgumentResolver nexacroResolver = new NexacroMethodArgumentResolver();
        resolvers.add(nexacroResolver);
        super.addArgumentResolvers(resolvers);
    }

    /**
     * 응답 처리기
     * Controller 반환값(NexacroResult)을 Nexacro Dataset/XML 응답으로 변환
     */
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
        NexacroHandlerMethodReturnValueHandler returnValueHandler = new NexacroHandlerMethodReturnValueHandler();

        // 실제 응답 생성기
        NexacroView nexacroView = new NexacroView();
        nexacroView.setDefaultContentType(PlatformType.CONTENT_TYPE_XML);
        nexacroView.setDefaultCharset("UTF-8");
        returnValueHandler.setView(nexacroView);

        // 파일 다운로드 전용
        NexacroFileView nexacroFileView = new NexacroFileView();
        returnValueHandler.setFileView(nexacroFileView);

        handlers.add(0, returnValueHandler);    // 핸들러 순서 명시

        super.addReturnValueHandlers(handlers);
    }

    /**
     * 넥사크로플랫폼 에러 처리 ExceptionResolver 등록
     * Exception → Nexacro 에러 응답
     */
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {

        NexacroView nexacroView = new NexacroView();
        nexacroView.setDefaultContentType(PlatformType.CONTENT_TYPE_XML);
        nexacroView.setDefaultCharset("UTF-8");

        NexacroMappingExceptionResolver nexacroException = new NexacroMappingExceptionResolver();

        nexacroException.setView(nexacroView);
        nexacroException.setShouldLogStackTrace(true);  // 서버 로그 출력
        nexacroException.setShouldSendStackTrace(true); // 클라이언트(Nexacro)에도 스택트레이스 전달
        nexacroException.setOrder(1);
        resolvers.add(nexacroException);

        super.configureHandlerExceptionResolvers(resolvers);
    }

}

 

Nexacro 전용 Controller 추가

Nexacro는 JSON이 아닌 자체 포맷으로 통신함

기존 REST API Controller와 별도로 Nexacro 전용 Controller를 만들어야 한다

-> 컨트롤러가 NexacroResult를 반환하도록 작성

import com.example.inventory.domain.DashboardDto;
import com.example.inventory.mapper.DashboardNexacroMapper;
import com.example.inventory.service.DashboardService;
import com.nexacro.uiadapter.jakarta.core.data.NexacroResult;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

// 매핑용 URL은 원하는 내용으로 작성. 추후 nexacro script에 작성해야 하는 것만 알면 됨
@Controller
@ResponseBody
@RequestMapping("/nexacro")
@RequiredArgsConstructor
public class NexacroDashboardController {

    private final DashboardService dashboardService;

    @GetMapping("/dashboard")
    public NexacroResult getDashboard() {
    	// 1.
        DashboardDto dashboard = dashboardService.getDashboard();
        
        // 2.
        return DashboardNexacroMapper.toResult(dashboard);	// DTO를 NexacroResult로 변환
    }
}
  1. service에서 대시보드 정보를 받아와 DTO에 저장 (각 service와 DTO는 본인 프로젝트에 맞게 작성)
  2. 해당 DTO를 NexacroResult로 변환하는 Mapper 클래스

 

DashboardNexacroMapper

DTO를 Dataset으로 변환하여 NexacroResult에 해당 데이터셋 추가 후 반환하는 클래스

Nexacro는 Dataset 단위로 데이터를 주고받으므로, 각각의 데이터셋 정보는 분리해서 넘겨주는 것이 좋음

import com.example.inventory.domain.DashboardDto;
import com.example.inventory.domain.DashboardSummary;
import com.nexacro.uiadapter.jakarta.core.data.NexacroResult;

import java.util.List;

public class DashboardNexacroMapper {

    public static NexacroResult toResult(DashboardDto dashboardDto) {
        NexacroResult result = new NexacroResult();

        // 요약 카드 - DataSet
        // DashboardSummary는 아래 내용을 담은 DTO
        DashboardSummary summary = new DashboardSummary(
                dashboardDto.getTotalItemCount(),
                dashboardDto.getTotalStockQty(),
                dashboardDto.getLowStockCount(),
                dashboardDto.getCategoryCount()
        );

        result.addDataSet("dsSummary", List.of(summary));
        
        /**
          * summary DTO를 새로 만들지 않고
          * 아래처럼 직접 데이터셋 생성 후 일일이 붙이는 방법도 있음
          * 관련 코드가 너무 길어지기 때문에 따로 DTO를 새로 선언한 것
        DataSet dsSummary = new DataSet("dsSummary");
        dsSummary.addColumn("totalItemCount", "INT");
        dsSummary.addColumn("totalStockQty",  "INT");
        dsSummary.addColumn("lowStockCount",  "INT");
        dsSummary.addColumn("categoryCount",  "INT");
        int row = dsSummary.newRow();
        dsSummary.set(row, "totalItemCount", dashboardDto.getTotalItemCount());
        dsSummary.set(row, "totalStockQty",  dashboardDto.getTotalStockQty());
        dsSummary.set(row, "lowStockCount",  dashboardDto.getLowStockCount());
        dsSummary.set(row, "categoryCount",  dashboardDto.getCategoryCount());
        outData.addDataSet(dsSummary);
        */

        // 카테고리별 재고
        result.addDataSet(
                "dsCategoryStock",
                dashboardDto.getCategoryStocks()
        );

        ...	// 이후 위와 같이 필요한 Dataset을 각각 추가

        return result;
    }

}

 

모두 작성 후 실행했을 때 문제 없이 실행 되면 연동이 잘 된 것

 

📌 Nexacro 화면 작성

좌측 메뉴에서 FrameBase - Form_Work 클릭

 

프로젝트 생성 시 템플릿을 Full로 선택했기 때문에 빈 화면일 것

상단 메뉴에서 각 요소를 골라 화면을 꾸밀 수 있음

컴포넌트와 버튼 등을 추가하여 화면을 꾸미자

노란 원으로 표시된 것이 왼쪽부터 button, static, grid

 

데이터 연동이 잘 이루어지는지만 먼저 확인할 것이기 때문에 간단하게 static 4개와 grid 1개만 화면에 배치함

이때 각각의 static은 dsSummary의 내용을, grid는 dsCategoryStock 내용을 저장할 것 -> 위의 DashboardNexacroMapper에서 nexacroResult에 추가한 dataset 정보가 표시되는 것

 

각 컴포넌트의 아이디를 다음처럼 바꾼다. (static 컴포넌트의 경우 화면에 표시될 text도 아래처럼 변경)

ID 컴포넌트 text
stTotalItem Static 0 개
stTotalStock Static 0 개
stLowStock Static 0 개
stCategory Static 0 개
grdCategory Grid  

 

 

상단 메뉴에서 Dataset 클릭 후, 페이지 아무 곳이나 클릭하면 하단에 dataset이 추가됨

 

dataset을 더블 클릭하여 id와 열 정보를 아래처럼 입력

 

이후 dataset을 마우스로 드래그하여 grid 컴포넌트에 놓으면 해당 ds가 grid 컴포넌트에 바인딩 됨

데이터셋이 바인딩 된 grid 컴포넌트를 더블 클릭하여, 표시될 텍스트를 아래처럼 변경해보자

 

Script 작성

페이지 하단을 보면 script 메뉴가 있을 것이다

해당 메뉴를 클릭하면 빈 화면이 뜰 건데, 그 화면에 아래 내용을 입력하면 됨

springBoot에서 받아온 정보를 form의 컴포넌트와 연결하는 것

// 화면 로드 시 자동 실행
this.Dashboard_onload = function(obj, e) {
    this.fn_getDashboard();
}

// 대시보드 조회
this.fn_getDashboard = function() {
    this.transaction(
        "getDashboard",                          // 트랜잭션 ID
        "SVC::nexacro/dashboard",          // 서비스 URL - SpringBoot Controller
        "",                                      // 전송 Dataset (없음)
        "dsSummary=dsSummary "
        + "dsCategoryStock=dsCategoryStock "
        + "추가 데이터셋 있으면 작성 ",           // 수신 Dataset
        "",                                      // 파라미터
        "fn_getDashboardCallBack"                // 콜백 함수
    );
}

// 조회 완료 콜백
this.fn_getDashboardCallBack = function(svcId, errorCode, errorMsg) {
    if (errorCode < 0) {
        alert("오류 발생: " + errorMsg);
        return;
    }

    // 요약 카드 수치 업데이트
    this.stTotalItem.set_text(this.dsSummary.getColumn(0, "totalItemCount") + " 개");
    this.stTotalStock.set_text(this.dsSummary.getColumn(0, "totalStockQty") + " 개");
    this.stLowStock.set_text(this.dsSummary.getColumn(0, "lowStockCount") + " 개");
    this.stCategory.set_text(this.dsSummary.getColumn(0, "categoryCount") + " 개");

    // Grid는 Dataset에 바인딩되어 있으면 자동으로 표시
}

 

📌 실행

상단의 launch 버튼을 눌러 화면을 실행해보자

해당 버튼을 누르면 어떤 화면이 뜰 건데, 뭐 건드릴 필요 없이 Run 실행하면 됨

 

연동이 잘 된 것을 확인할 수 있다.

일단 데이터가 잘 주고받아지는지 확인하려 했던 것이기 때문에 나머지 화면 구현은 나중에...

 


참고

https://123okk2.tistory.com/538#google_vignette

 

[Nexacro + Spring Boot] 넥사크로(1/3) - 프로젝트 생성 및 설정

다음 프로젝트에서 프론트엔드로 넥사크로를 사용하기로 결정했다. 처음 사용해보는 개발툴이라 열심히 연습하며 느낀 점은... 이번에야 이미 결정된 일이라 어쩔 수 없다지만 솔직히 이걸 두

123okk2.tistory.com

https://blog.naver.com/goodee0205/224071956196

 

[개발자국비교육]Mybatis vs JPA 어떤걸 선택하지?

웹 백엔드 개발을 하다 보면 데이터베이스와 연결하는 방식으로 MyBatis 또는 JPA를 많이 접하게 됩니...

blog.naver.com

 

저작자표시 (새창열림)

'SpringBoot' 카테고리의 다른 글

[SpringBoot] Flyway로 DB 마이그레이션 및 DDL 작성  (1) 2026.06.08
[SpringBoot] Swagger를 이용한 API 문서 자동화  (0) 2026.05.31
[AWS] SpringBoot + AWS EC2 Ubuntu 서버 생성 및 배포  (0) 2026.04.07
[AWS] RDS DB 인스턴스 생성(PostgreSQL) 및 SpringBoot 연동  (0) 2026.04.07
[SpringBoot] Spring Secutiry + JWT 기반 로그인 구현  (0) 2026.01.22
'SpringBoot' 카테고리의 다른 글
  • [SpringBoot] Flyway로 DB 마이그레이션 및 DDL 작성
  • [SpringBoot] Swagger를 이용한 API 문서 자동화
  • [AWS] SpringBoot + AWS EC2 Ubuntu 서버 생성 및 배포
  • [AWS] RDS DB 인스턴스 생성(PostgreSQL) 및 SpringBoot 연동
naahy
naahy
  • naahy
    종합장
    naahy
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Java
      • SpringBoot
      • Git
      • 트러블슈팅
      • Vue.js
      • Kotlin
      • Node.js
      • 코딩테스트
        • 백준
        • 프로그래머스
      • 스터디
        • CS
        • 알고리즘
      • -
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 인기 글

  • 태그

    github
    Nexacro
    bfs
    API
    node.js
    Java
    백준
    Kotlin
    이분탐색
    mongodb
    SpringBoot
    코틀린
    트러블슈팅
    자바
    cs
    투포인터
    브루트포스
    프로그래머스
    React
    백트래킹
  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
naahy
[SpringBoot + Nexacro] Nexacro 설치 및 프로젝트 생성과 연동
상단으로

티스토리툴바