'2020/04'에 해당되는 글 29건

  1. 2020.04.28 [Thymeleaf] <a> onclick 및 modal 에 변수 전달 하기.
  2. 2020.04.27 [Bootstrap] Radio button toggle/collapse 예제
  3. 2020.04.24 [Bootstrap] Collapse 예제
  4. 2020.04.24 [Thymeleaf] Springboot + Thymeleaf 사용 시 viewResolver 이슈.
  5. 2020.04.23 [Bootstrap] Modal 예제
  6. 2020.04.22 [Bootstrap] Text Wrapping and Overflow 처리.
  7. 2020.04.21 [Spring] spring security + javax api 사용에 따른 JDK 버전 문제.
  8. 2020.04.21 [Spring] Spring Cloud Config Client 구성 시 주의점
  9. 2020.04.20 [Bash] Bash function, array parameters, str replace 등
  10. 2020.04.20 [Gradle] Task Tutorial

[Thymeleaf] <a> onclick 및 modal 에 변수 전달 하기.

ITWeb/개발일반 2020. 4. 28. 21:25

알면 쉽고 모르면 고생하는...

 

<a class="dropdown-item" th:attr="onclick=|alert('${thingCertificate.certificateId}')|">상세정보</a>

<a class="dropdown-item" th:attr="onclick=|alert('${thingCertificate.certificateId}')|">상세정보</a>

 

<a class="dropdown-item"

  data-toggle="modal"

  href="#deleteThingCertificateModal"

  th:data-certid="${thingCertificate.certificateId}"

  th:data-certname="${thingCertificate.certificateInfo == null ? '인증서명이 존재 하지 않습니다.' : thingCertificate.certificateInfo.certName}">

인증서 삭제

</a>

...중략...

<th:block layout:fragment="script">
<script type="text/javascript">
$('#deleteThingCertificateModal').on('show.bs.modal', function (e) {
var certId = $(e.relatedTarget).data('certid');
var certName = $(e.relatedTarget).data('certname'); console.log(certId);
console.log(certName);
}
);
</script>
</th:block>

 

<a class="dropdown-item" 
  data-toggle="modal" 
  href="#deleteThingCertificateModal" 
  th:data-certid="${thingCertificate.certificateId}" 
  th:data-certname="${thingCertificate.certificateInfo == null ? '인증서명이 존재 하지 않습니다.' : thingCertificate.certificateInfo.certName}">
인증서 삭제
</a>

...중략...

<th:block layout:fragment="script">
<script type="text/javascript">
$('#deleteThingCertificateModal').on('show.bs.modal', function (e) {
    var certId = $(e.relatedTarget).data('certid');
    var certName = $(e.relatedTarget).data('certname');
    console.log(certId);
    console.log(certName);
  }
);
</script>
</th:block>

기본 전체는 Modal 창을 띄울 수 있어야 합니다.

그럼 위 내용이 쉽게 이해가 됩니다.

 

 

:

[Bootstrap] Radio button toggle/collapse 예제

ITWeb/개발일반 2020. 4. 27. 15:57

 

보통 <a>, <button>으로  collapse 기능 구현을 합니다.

 

[참고문서]

https://getbootstrap.com/docs/4.0/components/collapse/

<p>
  <a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" 
  role="button" aria-expanded="false" aria-controls="collapseExample">
    Link with href
  </a>
  <button class="btn btn-primary" type="button" data-toggle="collapse"
  data-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
    Button with data-target
  </button>
</p>
<div class="collapse" id="collapseExample">
  <div class="card card-body">
    Anim pariatur cliche reprehenderit......
  </div>
</div>

이 예제 코드는 어떤 걸 클릭 하던 toggle 형태로 동작 하게 됩니다.

하지만 저는

  • 버튼 1은 "hide"
  • 버튼 2는 "show"

로 동작 하게 하고 싶었습니다.

 

이와 같이 동작 하게 하려면 아래와 같이 코드를 수정 하면 됩니다.

 

  1. data-toggle="collpase" 코드를 삭제 합니다.
  2. hide 기능만 동작 하도록 아래 코드 추가
    onchange="$('#thingRegisterInfoDiv').collapse('hide')"
  3. show 기능만 동작 하도록 아래 코드 추가
    onchange="$('#thingRegisterInfoDiv').collapse('show')"

    이렇게 작성 하시면, radio button 에 특정 기능으로만 동작 하도록 해줄 수 있습니다.
<div class="form-check">
  <input class="form-check-input" type="radio" name="thingCertInfos" id="thingCertInfoNone" value="none" 
  data-target="#thingRegisterInfoDiv" onchange="$('#thingRegisterInfoDiv').collapse('hide')" checked>
  <label class="form-check-label" for="thingCertInfos">
    <span class="font-weight-bold">기기 정보 없음</span>
  </label>
</div>
<div class="form-check">
  <input class="form-check-input" type="radio" name="thingCertInfos" id="thingCertInfoRegister" value="register" 
  data-target="#thingRegisterInfoDiv" onchange="$('#thingRegisterInfoDiv').collapse('show')">
  <label class="form-check-label" for="thingCertInfos">
    <span class="font-weight-bold">기기 정보 입력</span></label>(생성할 인증서에 기기 정보 등록)
</div>

<div class="collapse" id="thingRegisterInfoDiv">
  <div class="card card-body">
  ...중략...
  </div>
</div>

이 정도로 마무리 합니다.

:

[Bootstrap] Collapse 예제

ITWeb/개발일반 2020. 4. 24. 14:05

[bootstrap collapse]
https://getbootstrap.com/docs/4.0/components/collapse/

- 처음에 <div class="collpase show" id="exCollapseDiv"> 를 열어 놓고 싶을 때

<a class="btn btn-primary" data-toggle="collapse" href="#exCollapseDiv" 
role="button" aria-expanded="true" aria-controls="exCollapseDiv">클릭</a>


오픈 된 상태로 화면에 출력 됩니다.

- 처음에 <div class="collpase" id="exCollapseDiv"> 를 닫아 놓고 싶을 때

<a class="btn btn-primary" data-toggle="collapse" href="#exCollapseDiv" 
role="button" aria-expanded="false" aria-controls="exCollapseDiv">클릭</a>​


닫힌 상태로 화면에 출력 됩니다.


- div class 에서 collpase 만 있을 경우 닫힌 상태로 show 를 추가 하면 열린 상태로 동작 합니다.

 

:

[Thymeleaf] Springboot + Thymeleaf 사용 시 viewResolver 이슈.

ITWeb/개발일반 2020. 4. 24. 08:17

이전 글 참고)

https://jjeong.tistory.com/1386

 

controller 단에서 viewName 작성 시 "/" 를 제거 하고 작성을 하셔야 합니다.

 

Spring framework 의 UrlBasedViewResolver.java 내 코드를 보면,

protected AbstractUrlBasedView buildView(String viewName) throws Exception {
   Class<?> viewClass = getViewClass();
   Assert.state(viewClass != null, "No view class");
   AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(viewClass);
   view.setUrl(getPrefix() + viewName + getSuffix());
   
   ...중략...
}

Thymeleaf 기본 설정을 보면,

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

...중략...

 

로컬에서는 되는 viewName 그러나 서버에서 안되는 ...)

    @GetMapping("/list")
    public String list(Model model) {
        return "/list";
    }

 

서버에서 되는 viewName)

    @GetMapping("/list")
    public String list(Model model) {
        return "list";
    }

둘 다 resources/templates/list.html 을 찾습니다.

만약, templates/thing/list.html 로 설정을 해야 한다면,

 

return "thing/list"; 

로 작성을 하시면 됩니다.

로컬에서만 테스트 하다 보면 이런 내용도 왜 안되지 하고 있을 때가 있어서 기록 합니다.

:

[Bootstrap] Modal 예제

ITWeb/개발일반 2020. 4. 23. 18:12

아래 공식 문서에 잘 나와 있습니다.

<!-- Buttons -->
<button type="button" data-toggle="modal" data-target="#myModal">Open Modal</button>

<!-- Links -->
<a data-toggle="modal" href="#myModal">Open Modal</a>

<!-- Other elements -->
<p data-toggle="modal" data-target="#myModal">Open Modal</p>
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter">
  Launch demo modal
</button>

<!-- Modal -->
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

 

:

[Bootstrap] Text Wrapping and Overflow 처리.

ITWeb/개발일반 2020. 4. 22. 14:24

[공식문서]

https://getbootstrap.com/docs/4.0/utilities/text/#text-wrapping-and-overflow

 

bootstrap 4.x 사용 하면서 inline css 나 별의 별 짓을 다 해봤으나 적용이 안되다가 위 문서 보고 처리 했습니다.

<div class="container-fluid">
  <div class="card">
    <div class="card-body">
      <div class="table-responsive">
        <table class="table">
          <thead>
          <tr>
            <th scope="col">#</th>
            <th scope="col">장치 인증서 ID</th>
            <th scope="col">장치 인증서 ARN</th>
            <th scope="col">상태</th>
            <th scope="col">생성일</th>
          </tr>
          </thead>
          <tbody>
          <tr>
            <th scope="row">1</th>
            <td>
              <span class="d-inline-block text-truncate" style="max-width: 150px;">
              262a1ac8a7d8aa72f6e96e365480f7313aa9db74b8339ec65d34dc3074e1c31e
              </span>
            </td>
            <td>
              <span class="d-inline-block text-truncate" style="max-width: 150px;">
                arn:aws:iot:us-west-2:123456789012:cert/262a1ac8a7d8aa72f6e96e365480f7313aa9db74b8339ec65d34dc3074e1c31e
              </span>
            </td>
            <td>ACTIVE</td>
            <td>1546447050.885</td>
            </td>
          </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>

 

예제)

<!-- Block level -->
<div class="row">
  <div class="col-2 text-truncate">
    Praeterea iter est quasdam res quas ex communi.
  </div>
</div>

<!-- Inline level -->
<span class="d-inline-block text-truncate" style="max-width: 150px;">
  Praeterea iter est quasdam res quas ex communi.
</span>

 

:

[Spring] spring security + javax api 사용에 따른 JDK 버전 문제.

ITWeb/개발일반 2020. 4. 21. 17:56

구글링 하면 많이 나옵니다.

 

spring security 사용 시 JDK 를 11 사용 하게 되면 아래와 같은 오류가 발생 할 떄가 있습니다.

 

에러)

 

Class Not Found javax/xml/bind/DatatypeConverter

 

해당 API 는 JDK 11 에서 삭제 되었기 때문에 그렇습니다.

그래서 해결을 하기 위해서는 두 가지 방법이 있습니다.

 

1. JDK 1.8 을 사용 하거나

2. javax-api dependency 를 잡아 주시면 됩니다.

compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'

 

:

[Spring] Spring Cloud Config Client 구성 시 주의점

ITWeb/개발일반 2020. 4. 21. 16:35

주의점 이라기 보다 그냥 설정을 잘 못 하는 경우가 있어서 기록 합니다.

 

Client 쪽 Dependency 등록)

implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.boot:spring-boot-starter-actuator'

 

Client 쪽 bootstrap.yml 등록)

spring:
  cloud:
    config:
      uri: http://${CONFIG_SERVER_HOST}:${PORT}

management:
  endpoints:
    web:
      exposure:
        include: refresh

 

Refresh 호출)

- HTTP Method : POST

- http://${CONFIG_CLIENT_HOST}:${PORT}/actuator/refresh

 

bootstrap.yml 에 등록 하지 않게 되면 client 가 config server 를 localhost:8888 로 찾는 오류가 발생 할 수 있습니다.

또한 refresh 등록을 해줘야 actuator/refresh 사용이 가능 합니다.

 

:

[Bash] Bash function, array parameters, str replace 등

ITWeb/개발일반 2020. 4. 20. 11:18

bash script 에서 function 사용은 호출 위치 보다 위에 function 선언이 되어 있어야 합니다.

#!/usr/bin/env bash

function 함수명() {
...
}

## 예제

#!/usr/bin/env bash

function helloWorld() {
  echo 'Hello World!!'
}

helloWorld

 

function  에 다중 array paramters 를 넘기는 예제는 아래와 같습니다.

#!/usr/bin/env bash

function deployElasticStack() {
  local instances=($1)
  local targets=($2)

  for instance in ${instances[@]}
  do

    local hostIpUser=($(echo $instance | tr ":" "\n"))

    for target in ${targets[@]}
    do
...중략...
    done
  done
}

selfHost=$(hostname -I|cut -f1 -d ' ')

instanceArr=("xxx.xxx.xxx.xxx:ubuntu" "xxx.xxx.xxx.xxx:ec2-user" "xxx.xxx.xxx.xxx:ubuntu")
metricbeatArr=("xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx")

deployElasticStack "${instanceArr[*]}" "${metricbeatArr[*]}" "$selfHost" "metricbeat"

 

해당 장비의 IP 정보를 가져 오는 예제는 아래와 같습니다.

$ hostname -I

$ hostname -I|cut -f1 -d ' '

$ ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'

 

file 내 특정 문자열을 치환 하는 예제는 아래와 같습니다.

$ sed -i "s/소스문자열/치환문자열/g" configuration.yml

# osx 에서는 아래와 같이 합니다.
$ sed -i "" "s/소스문자열/치환문자열/g" configuration.yml

 

:

[Gradle] Task Tutorial

ITWeb/개발일반 2020. 4. 20. 10:34

Gradle 을 이용한 build.gradle 작성 시 튜토리얼을 한번 보고 해보면 좋습니다.

 

[공식문서]

https://docs.gradle.org/current/userguide/tutorial_using_tasks.html

https://docs.gradle.org/current/dsl/org.gradle.api.Task.html

 

Task 의 실행 단계는 

- Task 본문의 Configuration

- doFirst

- doLast

단계로 실행 됩니다.

 

이 실행 단계를 이해 하기 위해서는 아래 문서를 참고 하세요.

 

[공식문서]

https://docs.gradle.org/current/userguide/build_lifecycle.html

Initialization

Gradle supports single and multi-project builds. 
During the initialization phase, Gradle determines 
which projects are going to take part in the build, 
and creates a Project instance for each of these projects.

Configuration

During this phase the project objects are configured. 
The build scripts of all projects which are part of the build are executed.

Execution

Gradle determines the subset of the tasks, 
created and configured during the configuration phase, to be executed. 
The subset is determined by the task name arguments passed to the gradle command 
and the current directory. 
Gradle then executes each of the selected tasks.

settings.gradle > build.gradle > task configured > task internal configuration > task

 

더불어서 task 가 실행 되지 않는 경우가 있는데 이 경우는 아래의 경우 실행 되지 않습니다.

 

- SKIPPED

Task did not execute its actions.

- NO-SOURCE

Task did not need to execute its actions.

  • Task has inputs and outputs, but no sources. For example, source files are .java files for JavaCompile.

: