반응형

Rs232 통신을 위해, 라이브러리 추가 중 아래와 같이 에러가 발생했다.

 

IntelliJ 에러

 

Gradle에 아래와 같이 추가했더니 문제가 해결되었다.

 

configurations {
    all*.exclude group: 'org.rxtx'
}

dependencies {

    // https://mvnrepository.com/artifact/org.rxtx/rxtx
    implementation group: 'org.rxtx', name: 'rxtx', version: '2.1.7'

    // https://mvnrepository.com/artifact/org.bidib.jbidib/bidib-rxtx-binaries
    implementation group: 'org.bidib.jbidib', name: 'bidib-rxtx-binaries', version: '2.2'

    // https://mvnrepository.com/artifact/org.bidib.jbidib/jbidibc-rxtx-2.2
    implementation group: 'org.bidib.jbidib', name: 'jbidibc-rxtx-2.2', version: '1.6.0'

}

 

반응형

[Node.js/AdminBro] Admin Page panel + MongoDB

Programming/Node.js 2021. 10. 27. 11:33 Posted by 생각하는로뎅
반응형

1. 심플하고 빠른 개발을 위한 Admin 페이지를 찾기로 했다. 

 

   기존에 쓰던 laravel(라라벨, php) 어드민(admin) 페이지도 매우 강력했지만, 서버 세팅까지 빠르게 끝낼 수 있는 것을 찾아보기로 했다.

 

Laravel Admin Panel 소개 영상

 

  그래서 찾은 것이 Node.js 였고, 어드민 페이지를 찾다보니 대표적인 Adminbro라는 어드민 페이지를 알게 되었다.

 

 

An Auto-generated Admin Panel for your Node.js Application

You, as a developer, provide database models, and AdminBro generates ReactJS UI which allows you (or other trusted users) to manage content.

adminbro.com

 

  Node.js 는 서버 세팅도 빠르게 끝낼 수 있고, 가벼우며 빠른 개발이 가능했기에 선택하게 되었다. Node.js를 많이 사용하고 있다고 하니, 학습해 놓는 것도 좋다고 생각한다.

 

심플하게 만든 Adminbro 페이지

 

 

 

Ⅰ. 기본 Adminbro 페이지


 

2. 사용 툴 visual studio code

 

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

 

  많은 툴이 있겠지만, 필자는 Visual Studio Code가 설치되어 있어서 그대로 사용해보았다. 툴에 대해서 이해가 많지 않아서 불편한 감이 있었지만 개발하는 데는 문제가 없었다.

 

 

 

3. Node.js 설치

 

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

  Node.js를 다운로드하여 설치 후, cmd에서 node를 입력해서 실행된다면 준비가 된 것이다.

 

Node,js 설치 후 cmd 실행

 

 

 

4. MongoDB 설치

 

 

MongoDB Enterprise Server Download

Download MongoDB Enterprise Server, which provides advanced security and performance options for the most demanding apps. Use for free for development.

www.mongodb.com

 

  adminbro는 MongoDB를 사용하고 있었기 때문에 설치하도록 한다.

 

  설치 후, MongoDB Compass Tool이 설치되는데, 정상적으로 Connection이 이루어지면 설치가 된 것이다.

 

MongoDB Compass

 

 

 

5. cmd 창을 열고 아래와 같이 한 줄씩 설치하도록 한다. (프로젝트가 생성될 폴더이다.)

npm install admin-bro @admin-bro/express
npm install admin-bro-expressjs
npm install mongoose
npm install express
npm install @admin-bro/mongoose
npm install tslib
npm install express-session
npm install express-formidable

 

 

 

6. 프로젝트 생성할 폴더를 ROOT로 가정하겠다.

 

 

 

7. ROOT/index.js 파일을 만들고 아래와 같이 입력한다.

 

var express = require('express');
const User = require('./Models/User')
const AdminBro = require('admin-bro')
const AdminBroMongoose = require('@admin-bro/mongoose')
const AdminBroExpressjs = require('@admin-bro/express')

var app = express();
const mongoose = require('mongoose');//Routes
app.get('/', function (req, res) {
    res.send('Hello World!');
});

//Database
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
mongoose.connection.once('open',function(){
    console.log('Database connected Successfully');
}).on('error',function(err){
    console.log('Error', err);
})

//Admin Bro
AdminBro.registerAdapter(AdminBroMongoose)

const AdminBroOptions = {
  resources: [User],
}

const adminBro = new AdminBro(AdminBroOptions)
const router = AdminBroExpressjs.buildRouter(adminBro)

app.use(adminBro.options.rootPath, router)
app.listen(3000, function () {
    console.log('Listening to Port 3000');
});

 

 

  1) 아래 코드는 test 이름으로 database가 생성된다.

mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});

 

test database가 생성된 모습

 

  2) 아래 코드는 포트 번호 3000을 사용하겠다는 의미이다.

app.listen(3000, function () {
    console.log('Listening to Port 3000');
});

 

 

 

 

8. ROOT/Models 폴더를 생성 후, User.js 파일을 만들고 아래와 같이 입력한다.

 

const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
  email: {
    type: String,
    required: true,
  },
  encryptedPassword: {
    type: String,
    required: true,
  },
  role: {
    type: String,
    enum: ['admin', 'member'],
    required: true
  }
})
module.exports = mongoose.model('User',UserSchema)

 

 

  1) 아래 코드는 database test에 Users와 맵핑이 된다. 이름 뒤에 s가 붙어서 Users라고 보인다.

module.exports = mongoose.model('User',UserSchema)

 

users가 생성된 모습

 

 

 

 

9.  cmd 창에서 ROOT 폴더로 이동 후, 아래와 같이 입력한다. 그러면 서버가 실행된다.

 

node index.js

 

cmd 성공 모습

 

 

 

10. 아래 URL으로 진입 후, 정상적으로 페이지가 구동되는지 확인한다.

 

http://localhost:3000/admin

 

정상적으로 페이지가 구동된 모습

 

 

 

 

Ⅱ. 로그인 기능 페이지


 

11. Admin 페이지에 관리자 로그인 기능이 없으면 이빨 빠진 것처럼 이상하기에 추가해본다.

 

 

 

12. Adminbro 페이지에서 User -> Create new -> 아래 그림과 같이 입력 후, Save를 누른다. 그러면 MongoDB에 데이터가 삽입되어 있는 것을 볼 수 있다.

 

Admin 계정 생성

 

 

MongoDB Compass 에서 admin 계정이 생성된 모습

 

 

 

13. ROOT/index.js 파일을 아래와 같이 수정한다.

 

var express = require('express');
const User = require('./Models/User')
const AdminBro = require('admin-bro')
const AdminBroMongoose = require('@admin-bro/mongoose')
const AdminBroExpressjs = require('@admin-bro/express')
const canEditEmp = ({ currentAdmin, record }) => {
    return currentAdmin && (
      currentAdmin.role === 'admin'
    )
  }

var app = express();
const mongoose = require('mongoose');//Routes
app.get('/', function (req, res) {
    res.send('Hello World!');
});

//Database
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
mongoose.connection.once('open',function(){
    console.log('Database connected Successfully');
}).on('error',function(err){
    console.log('Error', err);
})

//Admin Bro
const canModifyUsers = ({ currentAdmin }) => currentAdmin && currentAdmin.role === 'admin'
AdminBro.registerAdapter(AdminBroMongoose)

const AdminBroOptions = {
  resources: 
  [{
    resource: User,  
    options: {
      properties: {
        encryptedPassword: { isVisible: true },
        password: {
          type: 'string',
          isVisible: {
            list: false, edit: true, filter: false, show: false,
          },
        },
      },
      actions: {
        new: {
          before: async (request) => {
            if(request.payload.record.password) {
              request.payload.record = {
                ...request.payload.record,
                encryptedPassword: await bcrypt.hash(request.payload.record.password, 10),
                password: undefined,
              }
            }
            return request
          },
        },
        edit: { isAccessible: canModifyUsers },
        delete: { isAccessible: canModifyUsers },
        new: { isAccessible: canModifyUsers },
      }
    }
  }],
}

const adminBro = new AdminBro(AdminBroOptions)
const router = AdminBroExpressjs.buildAuthenticatedRouter(adminBro, {
    authenticate: async (email, password) => {
      const user = await User.findOne({ email })
      console.log(user)
        if (user) {
          if (password === user.encryptedPassword) {
            return user
          }
        }
      return false
    },
    cookiePassword: 'session Key',
  })

app.use(adminBro.options.rootPath, router)
app.listen(3000, function () {
    console.log('Listening to Port 3000');
});

 

 

 

 

14. 수정 후, 서버를 구동한다.

서버가 정상적으로 구동된 모습

 

 

 

15. admin 페이지에 진입하면, 아래와 같이 로그인 페이지를 볼 수 있다.

 

http://localhost:3000/admin

 

adminbro 로그인 페이지가 구동된 모습

 

 

 

 

16. email과 password를 admin으로 채워 넣은 후, Login 버튼을 누르면 정상적으로 로그인되는 것을 확인할 수 있다.

 

정상적으로 로그인된 모습, 우측 상단에 로그인했다는 표시를 확인 할 수 있다.

 

 

반응형

[javaFX] JavaFX 17 IntelliJ IDEA 튜토리얼 With Gradle

Programming/javaFX 2021. 10. 20. 16:43 Posted by 생각하는로뎅
반응형

  JavaFX 공식 홈페이지에서 튜토리얼이 존재하지만, 정상적으로 동작하지 않아서 별도로 재정리를 했다.

 

  Eclips 보다는 IntelliJ IDEA 가 깔끔하고 jlink으로 런타임 이미지를 만들기에도 수월했기에 차후 헤매지 않기 위해서, 튜토리얼을 정리해본다.

  

 jlink 란 쉽게 말해서 배포용으로 만든다고 생각하면 된다.

 

 

 

 

0. 필자가 테스트에 수행한 Intellij IDEA 버전은 아래와 같다.

IntelliJ IDEA 2020.2.4 (Community Edition)
Build #IC-202.8194.7, built on November 24, 2020
Runtime version: 11.0.9+11-b944.49 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: 1981M
Cores: 8
Non-Bundled Plugins: org.jetbrains.kotlin

 

 

IntelliJ IDEA 버전

 

 

 

 

1. JavaFX 17 은 JDK 11 이상부터 지원하기 때문에, JDK 11 이상을 다운로드 받고 환경 설정을 해준다.

 

   CMD 에서 java -version을 입력했을 때, 아래와 비슷하게 출력이 되어야 완료가 된 것이다.

 

필자는 Java version 15.0.2 이다.

 

 

 

2. IntelliJ IDEA를 실행하고, New Project를 누른다.

 

 

 

 

3. Gradle -> Project SDK는 1번에서 JDK 설정해준 버전으로 맞춰준다. 

 

   Java로 체크 후, Next

 

 

 

4. 만약 설치한 JDK 버전이 보이지 않는다면, 아래와 같이 Add JDK으로 설치한 JDK 경로를 설정해주도록 한다.

 

 

 

만약 PC JDK 환경 설정 버전과 프로젝트 JDK 버전이 다르다면, 아래와 같이 오류가 발생하므로 꼭 맞춰 줘야 한다.
Execution failed for task ':run'.
> Process 'command 'C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.4\jbr\bin\java.exe'' finished with non-zero exit value 1

 

 

 

 

5. 프로젝트 이름을 helloWoldFx으로 입력 후, Finish 버튼을 누른다.

 

 

 

 

 

6. 프로젝트가 생성되면 빌드가 되기까지 시간이 걸리므로, 조금 기다리도록 한다.

   빌드가 완료되면 아래와 같이 java 패키지와 resources 폴더를 만들어준다.

 

 

  폴더 구조는 아래와 같다. 참고해서 생성해주도록 한다.

폴더 구조

 

 

 

 

7. build.gradle 파일을 열고, 아래와 같이 입력해준다.

 

  여기서 name과 mainClassName을 주의해서 입력해주도록 한다. 위 글과 동일하게 왔다면, 변경이 불필요하다.

 

mainClassName은 패키지명.메인 Class 이름
launcher name은 프로젝트 이름을 의미한다.

 

 

plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.9'
    id 'org.beryx.jlink' version '2.24.4'
}

repositories {
    mavenCentral()
}

javafx {
    version = "17"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

mainClassName = "$moduleName/kr.thinker.MainApp"

jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'helloFx'
    }
}

 

 

8. Gradle 빌드 버튼을 누르면 아래와 같이 오류가 발생한다.

 

 

> Could not get unknown property 'moduleName' for root project 'helloWoldFx' of type org.gradle.api.Project.

 

빌드 에러 메세지

 

 

 

 

9. 공식 페이지에서는 "$moduleName"을 입력하라고 안내되어 있지만, $moduleName을 입력을 하면 오류가 발생했다. 때문에 제외하고 다시 빌드 버튼을 누른다.

 

$moduleName 을 제외한 모습

 

 

빌드가 완료되면 External Libraries에 javafx 17 라이브러리가 받아졌는 것을 확인할 수 있다.

javaFX 17 라이브러리를 받은 모습

 

 

 

 

10. kr.thinker 패키지 아래에 MainApp.java 메인 클래스를 만들고 코드를 입력한다.

 

MainApp Class와 소스 코드를 넣은 모습

 

 

package kr.thinker;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class MainApp extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception{

        Parent root = FXMLLoader.load(getClass().getResource("scene.fxml"));

        Scene scene = new Scene(root);
        scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());

        primaryStage.setTitle("JavaFX and Gradle");
        primaryStage.setScene(scene);
        primaryStage.show();

    }
}

 

 

 

 

11. resources 밑에 kr > thinker 폴더 아래에 scene.fxml과 styles.css 파일을 만들고 코드를 입력한다.

 

resources에 파일을 만든 모습

 

  1) scene.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>


<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17.0.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kr.thinker.FXMLController">
    <children>
        <Label fx:id="label" text="Label" />
    </children>
</StackPane>

 

  2) styles.css

.label {
    -fx-text-fill: blue;
}

 

 

 

 

12. kr.thinker 패키지 아래에 FXMLController.java 클래스를 만들고 코드를 입력한다.

 

     scene.fxml을 제어하는 java Class가 FXMLController.java 이기 때문에, 생성해야 한다.

 

FXMLController Class와 소스 코드를 넣은 모습

 

package kr.thinker;

import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class FXMLController {

    @FXML
    private Label label;

    public void initialize() {
        String javaVersion = System.getProperty("java.version");
        String javafxVersion = System.getProperty("javafx.version");
        label.setText("Hello, JavaFX " + javafxVersion + "\nRunning on Java " + javaVersion + ".");
    }
}

 

 

 

 

13. Gradle에 build를 누르고 완료가 되면, run을 눌러서 Application을 실행한다.

 

Gradle 실행 위치

 

 

 

 

14. JavaFX 가 정상적으로 실행되는 것을 확인할 수 있다.

 

Application이 실행된 모습

 

 

 

 

15. JavaFX 공식 홈페이지에서는 module-info.java를 생성해야 한다고 나와있지만, 생성하지 않아도 기본 실행은 가능했다.

 

 

 

 

16. 하지만, Jlink를 이용해서 런타임 이미지를 만들려면 moudle-info.java가 필요하다.

 

 

 

 

17. java > 오른쪽 마우스 클릭 > New > module-info.java을 선택해서, module-info.java를 들고, 코드를 입력한다.

 

마우스 오른쪽 클릭 후,  module-info.java 위치

 

module helloWoldFx.main {

    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.graphics;

    opens kr.thinker to javafx.fxml;
    exports kr.thinker;

}

 

module-info.java 에 코드가 입력된 모습

 

 

 

 

18. build.gradle에 $moduleName을 추가한다.

 

...

mainClassName = "$moduleName/kr.thinker.MainApp"

...

 

 

build.gradle 에 moudleName이 삽입된 모습

 

 

 

 

19. Gradle에 build -> jlink를 실행한다.

 

jlink 실행 위치와 jlink 성공하는 모습

 

 

 

 

20. jlink 성공 후, 프로젝트 경로 -> build -> image -> bin 으로 이동해서, 프로젝트명. bat을 실행한다.

 

런타임 이미지 생성된 경로 폴더 구조
bin 폴더에서 application 실행할 수 있는 파일

 

 

 

 

21. 프로젝트명.bat 을 실행하면 아래와 같이 Application이 실행되는 것을 볼 수 있다.

 

 

 

 

 

 

 

P.S 국내 사이트에는 JavaFX 관련 자료가 매우 적은 것 같다. 많이 활성화되었으면 한다.

반응형