http://springmvc.egloos.com/535572 



@ModelAttribute

 - controller로 접근시 항상  해당항목은 자동으로 생성/세팅이 되는 자동세팅 필드이다. 


@SessionAttributes

 - 동일한 이름의 모델객체를 발견하면 자동으로 세션값으로 변환하여 가지고 있는다.  




@ExceptionHandler

  - Controller 내에 정의해 놓으면, 그 controller내에서 발생하는 해당 Exception을 다 잡아준다.

    따라서, 함수안에서 catch를 할 필요가 없어진다.


@ControllerAdvice 

  - 위의 ExceptionHandler같은 것들을, 해당 controller뿐 아니라, 전체 어플리케이션에서 동작하도록 해준다.
    (@RequestMapping을 보고 찾음)


  여기에 영향받는 어노테이션은 

   @ExceptionHandler

   @InitBinder

   @ModelAttribute

  이다. 


Posted by yongary
,

REF:Mkong.com

 

 

[Stream:  one Group ]

.stream().collet(  Collectors.groupingBy(Function.identity(),  Collectors.count() ),

 

Grouping

 Map<BigDecimal, List<Item>> groupByPriceMap = 			items.stream().collect(Collectors.groupingBy(Item::getPrice)); 
 Map<BigDecimal, Set<String>> result =                 items.stream().collect(                         Collectors.groupingBy(Item::getPrice,                                 Collectors.mapping(Item::getName, Collectors.toSet())                         )                 );
[List -> Map]
Map<String, Choice> result =     choices.stream().collect(Collectors.toMap(Choice::getName,                                               Function.identity()));
 

[2 field Grouping]

Map<String, Map<String, Long>> multipleFieldsMap = employeesList.stream()
				.collect(
					Collectors.groupingBy(Employee::getDesignation, 
                                   Collectors.groupingBy(Employee::getGender, Collectors.counting())
                 ));

 

===========================O======================

<생성>
 Optional.of(v)
 Optional.ofNullable(v or null)
 Optional.empty()
 
 

.orElse(blabla)  empty일때 값지정.

 

.map( function)  존재할때 함수실행.

 

-boolean isPresent()

내부객체가 null이 아닌지 확인한다. null이면 false를 반환한다.

 

-void ifPresent(Consumer<T>)

Consumer<T>는 함수형 인터페이스 포스팅에서 봤듯 void 추상메서드를 갖고있다. null이 아닐때만 실행된다.

 

-Optional<T> filter(Predicate<T>)

스트림은 여러 데이터를 들고있는 객체다보니 filter로 걸러지는 데이터들이 반환됐지만, Optional은 내부객체가 단일객체인만큼 해당 조건을 만족하는지만 확인하는 정도로 사용할 수 있을 것 같다.

 

-Optional<U> map(Function<T, U>)

스트림과 같다. 내부 객체를 변환하는 용도로 사용한다.

 

-T get()

내부 객체를 반환한다. 다만 내부 객체가 null이면 NPE가 발생한다. null이 아니라는 확실한 경우에만 사용을 권장한다.

 

-T orElse(T)

내부 객체를 반환한다. 내부 객체가 null이면 인자로 들어간 기본값을 반환한다.

 

-T orElseGet(Supplier<T>)

orElse()와 동일한데 orElse()가 기본값 레퍼런스를 인자로 받는다면 orElseGet()은 내부 객체가 null일때 기본값을 반환할 객체를 인자로 받는다.

 

-T orElseThrow(Supplier<U>)



출처: http://multifrontgarden.tistory.com/131 [우리집앞마당]

Posted by yongary
,

docker

IT 2017. 6. 13. 17:05

REF:slideshare


Docker는 이미지 파일과 linux프로세서 형태로 실행하는 container로 이루어져있다.

immutable 이미지를 이용하기 때문에, 가상화머신보다 설정과 배포가 용이하다.


이미지와 이미지의 차이만 diff로 관리하기 때문에, github처럼 dockerhub에서 이미지 관리가 가능하다.


그리고 

boot2docker는 가상머신안에 docker를 실행하는 것이라서, host ip로  nginx등의 웹서버에 바로 접속할 수 없다.


이 때, ip를 알 고 싶으면 boot2docker ip를 이용하면 된다.

참고로 boot2docker up 으로 실행을 한다.



Posted by yongary
,

 sed 로  치환's/4.5.0-SNAPSHOT/4.7.0-SNAPSHOT/g' 

     명령을 써서 다른 파일에 저장하는 건 간단하지만


같은 파일에 저장하고 싶을때는 -i 옵션을 써야 한다.


하지만 맥에서는 -i 옵션 뒤에 항상 파라미터가 필요해서 '' 를 넣어주면 잘 동작한다.


예) sed -i '' 's/4.5.0-SNAPSHOT/4.7.0-SNAPSHOT/g' pom.xml


Posted by yongary
,

jQueryAutoComplete API Doc



suggestion (구글 검색창 처럼, 한 글자를 입력하면 자동으로 추천해주는 기능)

을 구현하기 위해서는 text box와 그 밑에 div를 이용해서 복잡하게 하는게 좋긴 한데


jQuery의 AutoComplete라는 기능을 이용해서 간단하게 할 수 있다. REF  (value만 있는 autoComplete)


label, value가 있는 autocomplete 예제는 여기: REF  - 별로 이쁘지 않고, 키로 값이 선택되지도 않음


약간 발전된 예제: REF -test중.


위 예제들에서 javascript 변수에 값 설정만 잘하면 된다.



추가로,  만약 Themeleaf를 사용하고 있다면..

<script th:inline="javascript">
    /*<![CDATA[*/
    var query = [[${query}]];
    console.log(message);
    /*]]>*/
</script>

방식으로 간단히 themeleaf변수를 javascript에 넣을 수 있다.




복잡한 변수의 경우 themeleaf파싱이 필요한데..  REF1

다음과 같이 themeleaf와 value, label을 조합해 사용할 수 있다.

<script type="text/javascript" th:inline="javascript">
/*<![CDATA[*/
$(function () {
var suggestionData = [[${javaData}]];
$('#users').autocomplete({
source: suggestionData,
select: function (event, ui) {
//prevent .val(value) to input_text
event.preventDefault();
//.val(label) and store selected Value
$('#users').val(ui.item.label);
$('#userSelected').val(ui.item.value);
},
focus: function (event, ui) {
//prevent .val(value) to input_text
event.preventDefault();
}
});
});
/*]]>*/
</script>

단, java에서는 Array혹은 ArrayList로 label,value를 멤버로 가지고 있는 class의 list를 넘겨야 한다.

Posted by yongary
,


하나의 html페이지로 Listing과 Editing을 동시에 수행하는 페이지는 다음과 만들 수 있다.

(참고:  jQuery와 themeleaf이용)

 

포인트: flag(isEditMode)를 두어서 list인지 Edit인지를 구분하고, 

 그에 따라 필요한 버튼을 hide/show

 input을 readonly or not 으로 세팅한다. 


<script type="text/javascript" th:inline="javascript">
/*<![CDATA[*/
$(function () {
allReload();

//list-edit Mode switch
function allReload() {
if ($('#isEditMode').val() == 'true'){
$('.form-control').prop('readonly', false);
$('.form-control').css('border', '1px solid #ccc');
$('#editBtn').hide();
$('#storeBtn').show();
$('#cancelBtn').show();
} else {
$('.form-control').prop('readonly', true);
$('.form-control').css('border', 'none');
$('#editBtn').show();
$('#storeBtn').hide();
$('#cancelBtn').hide();
}
}

$('#editBtn').click(function () {
$('#isEditMode').val('true');
allReload();
});

$('#cancelBtn').click(function () {
$('#isEditMode').val('false');
allReload();
});
//Button process


});
/*]]>*/
</script>
<input type="hidden" id="isEditMode" th:value="${isEditMode}"/>

<form id="form" method="post" enctype="multipart/form-data" th:object="${chatRankingCoefficientForm}"
action="/app/chat/ranking/constant">
<table class="table table-hover table-bordered"
style="word-break: break-all;word-wrap: break-word;" border="1">
<tr>
<th style="text-align:center">ranking</th>
<th style="text-align:center">Value</th>
</tr>
<tr>
<td>Days of Evaluation</td>
<td>
<input class="form-control" readonly="true" style="border:none;background-color:transparent;"
type="number" th:field="*{daysOfEvaluation}"/>
<div th:classappend="${#fields.hasErrors('daysOfEvaluation')} ? 'has-error'">
<span th:if="${#fields.hasErrors('daysOfEvaluation')}" th:errors="*{daysOfEvaluation}"
class="help-block">error!</span>
</div>
</td>
</tr> ..중략

<p> <!-- BUTTONS -->
<a class="btn btn-primary" id="editBtn">edit</a>
<input type="submit" class="btn btn-primary" id="storeBtn" value="save" />
<a th:href="@{/app/chat/ranking/constant}" class="btn btn-secondary" id="cancelBtn">cancel</a>
</p>
</form>


Posted by yongary
,

개발의 편의상 spring-boot-devtools라는 걸 사용하는게 좋다. REF

아래와 같은 5가지 기능이 지원된다.



Automatic Restart


LiveReload 

  - 특히 이부분은 개발을 할 때는 편하나, cache(@Cacheable)가 바뀌어도 자동 reload해주는 등 편하지만

    개발환경에서 ClassCastException이 발생할 수 있다.

    즉, cache에서 복원된 Object가 Class로 변환이 잘 안되는 문제가 있다.


   그래서 Cache를 테스트할 때는, 이부분을 pom.xml등에서  코멘트아웃을 하고 하는게 좋다.



Remote Debug Tunneling


Remote update and restart


Video Privew


Posted by yongary
,

cookie 와 JSESSIONID

FRONT-END 2017. 5. 18. 12:11

브라우저에서 쿠키를 이러저러 여러가지 값으로 설정할 수 있는데 REF

 
Tomcat의 경우는 

JSESSIONID 변수를 쿠키로 주고받으면서 세션을 유지한다.  REF


웹서버마다 방식이나 변수명이 다르므로 확인이 필요하다. 

nginx웹서버의 경우 cc변수로 보인다. 



현재쿠키는 javascirpt:document.cookie  를 주소창에 치면 쉽게 확인할 수 있다.


쿠키를 조작해서 테스트하고 싶을때는 postman , 그 중에서도 postman intercepter를 크롬에 설치하면 가능하다. 

Posted by yongary
,

mysql 원격copy

BACK-END 2017. 5. 17. 12:09

옆동료에게 나의 db를 그대로 복사해주고 싶은 경우,


일단 원격 접속을 해야하기 때문에

1.  mysql> grant all privileges on *.* to 'root'@'10.33.%';   동료pc에서 이런식으로 접속 허용을 해준다.


2. $ mysqldump -u root databaseName > temp.sql

3. 동료 mysql에 접속한 후 ( $mysql -h 동료pc_IP  -u root ) 아래명령 실행.

   mysql> create database databaseName

   mysql> use dataBaseName

   mysql> source temp.sql




Posted by yongary
,

Builder 와 Factory

java core 2017. 5. 9. 23:20

Builder는 간단히 말하면 setter가 다 끝나고 생성자를 호출해 주는 패턴이다. 

개념은 간단한데 왜 필요한가에 대한 답은 :  복잡한 생성자와 복잡한 setter가 섞여있는 경우 유용하다. REF 

예) PersonInfo personInfo = new Builder("Mommoo").setAge(12).setPhonNumber(119).build( );

 

Factory는 여러개의 subClass가 있을경우 생성자가 각각 생기는 복잡한 문제가 있는데..

이를 하나의 생성자로 통일해 주는 큰 장접이 있다.   REF

 

 

Posted by yongary
,