Jini's Blog

Ing...

  • Home
  • Business
    • Internet
    • Market
    • Stock
  • Parent Category
    • Child Category 1
      • Sub Child Category 1
      • Sub Child Category 2
      • Sub Child Category 3
    • Child Category 2
    • Child Category 3
    • Child Category 4
  • Featured
  • Health
    • Childcare
    • Doctors
  • Home
  • Business
    • Internet
    • Market
    • Stock
  • Downloads
    • Dvd
    • Games
    • Software
      • Office
  • Parent Category
    • Child Category 1
      • Sub Child Category 1
      • Sub Child Category 2
      • Sub Child Category 3
    • Child Category 2
    • Child Category 3
    • Child Category 4
  • Featured
  • Health
    • Childcare
    • Doctors
  • Uncategorized

Java 버전별 특징 및 변경사항

 Jini     오후 10:28     JAVA     No comments   

1. Java7

• 타입추론

List<String> list = new ArrayList<>();

• 이진수 리터럴, 숫자 리터럴에 _ 지원

• Switch문 문자열 가능

• try-with-resources 문 : AutoCloseable 인터페이스를 구현하는 클래스에 속하는 경우 다음과 같은 코드 패턴에 대한 단축 기능을 제공한다.

//JAVA 7 이전
//리소스를 연다
try {
    리소스를 이용해 작업한다.
}
finally {
    리소스를 닫는다.
}

//JAVA 7 이후
try (Resource res = ...) {
    res를 이용해 작업한다.
}

//여러 리소스를 지정할 수 있다.
try (Scanner in = new Scanner(Paths.get("/usr/share/dict/words"));
      PrintWriter out = new PrintWriter("/tmp/out.txt")) {
    while (in.hasNext()) {
      out.println(in.next().toLowerCase());
    }
}

• 여러 예외 잡기


try {
  //예외를 던질 수 있는 코드
}
catch (FileNotFoundException | UnknownHostException ex) {
  //파일 누락 및 알려지지 않은 호스트에 대한 긴급 액션
}
catch (IOException ex) {
  //그 외의 모든 I/O 문제에 대한 긴급 액션
}

2. Java8

• 32비트를 지원하는 마지막 공식 버전

• Lambda

• Stream

• Default Method

• LocalDate, LocalTime

• Optional


3. Java9

• default GC : G1GC

• Module System

• Collections of(불변)

List<String> list1 = List.of("a", "b");

• Jshell 추가

• try-with-resources 향상

// try() block 밖에 선언된 변수에 대해서는 try-with-resources 사용불가능했으나 java9부터 가능
// BufferedReader is declared outside try() block
BufferedReader br = new BufferedReader(new FileReader("C://readfile/input.txt"));

// Java 9 make it simple
try (br) {
    String line;
    while (null != (line = br.readLine())) {
        // processing each line of file
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

• 인터페이스에 private 메소드 사용가능


4. Java10

• var 사용가능

• JVM 힙 영역을 시스템 메모리가 아닌 다른 종류의 메모리에도 할당 할 수 있게 되었다.


5. Java11

• 새로운 가비지 컬렉터 등장 : ZGC, Epsilon

Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

WebFlux Error Handling

 Jini     오후 10:07     error, exception, Webflux     No comments   

WebFlux Error Handling

  • doOnError : 예외 발생시 특정행위를 수행한다.
  • onErrorReturn : 예외 발생시 특정 값을 return 한다.
  • onErrorResume : 예외 발생시 다른 Flux형태로 return 한다.
  • onErrorContinue : 예외 발생시 멈추지 않고 해당 영역만 skip 한다(별도 처리 하지 않는 이상 정상 응답을 return한다).
  • onErrorMap : 예외 발생시 다른 Exception으로 변환한다.

doOnError

Source:
@RequestMapping("/error/test")
public Flux<Integer> getNum() {
  return Flux.range(0, 5)
      .map(x -> {
        if (x == 3) {
          throw new IllegalArgumentException("invalid num");
        }
        return x;
      })
      .doOnError(x -> log.error("num generate error"))
      .log();
}
Result:

 INFO 5276 --- [ctor-http-nio-2] reactor.Flux.PeekFuseable.1              : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
 INFO 5276 --- [ctor-http-nio-2] reactor.Flux.PeekFuseable.1              : | request(unbounded)
 INFO 5276 --- [ctor-http-nio-2] reactor.Flux.PeekFuseable.1              : | onNext(0)
 INFO 5276 --- [ctor-http-nio-2] reactor.Flux.PeekFuseable.1              : | onNext(1)
 INFO 5276 --- [ctor-http-nio-2] reactor.Flux.PeekFuseable.1              : | onNext(2)
ERROR 5276 --- [ctor-http-nio-2] c.e.demo.r4.controller.R4Controller      : num generate error
ERROR 5276 --- [ctor-http-nio-2] reactor.Flux.PeekFuseable.1              : | onError(java.lang.IllegalArgumentException: invalid num)
ERROR 5276 --- [ctor-http-nio-2] reactor.Flux.PeekFuseable.1              : 

onErrorReturn

Source:

@RequestMapping("/error/test")
public Flux<Integer> getNum() {
  return Flux.range(0, 5)
      .map(x -> {
        if (x == 3) {
          throw new IllegalArgumentException("invalid num");
        }
        return x;
      })
      .onErrorReturn(99)
      .log();
}
Result:

 INFO 12068 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
 INFO 12068 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : request(unbounded)
 INFO 12068 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(0)
 INFO 12068 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(1)
 INFO 12068 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(2)
 INFO 12068 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(99)
 INFO 12068 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onComplete()

onErrorResume

Source:

@RequestMapping("/error/test")
public Flux<Integer> getNum() {
  return Flux.range(0, 5)
      .map(x -> {
        if (x == 3) {
          throw new IllegalArgumentException("invalid num");
        }
        return x;
      })
      .onErrorResume(exec -> {
        log.error("num generate error");
        return Mono.just(99); //어떤 값으로 return을 할지 상황에 맞게 지정한다.
      })
      .log();
}
Result:

 INFO 8444 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
 INFO 8444 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : request(unbounded)
 INFO 8444 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(0)
 INFO 8444 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(1)
 INFO 8444 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(2)
ERROR 8444 --- [ctor-http-nio-2] c.e.demo.r4.controller.R4Controller      : num generate error
 INFO 8444 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(99)
 INFO 8444 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onComplete()

OnErrorContinue

Source:

@RequestMapping("/error/test")
public Flux<Integer> getNum() {
  return Flux.range(0, 5)
      .map(x -> {
        if (x == 3) {
          throw new IllegalArgumentException("invalid num");
        }
        return x;
      })
      .onErrorContinue((exec, num) ->
          log.error("num generate error, number is : {}, error msg : {}", num, exec.getMessage()))
      .log();
}
Result:

 INFO 9728 --- [ctor-http-nio-2] reactor.Flux.ContextStart.1              : | onSubscribe([Fuseable] FluxContextStart.ContextStartSubscriber)
 INFO 9728 --- [ctor-http-nio-2] reactor.Flux.ContextStart.1              : | request(unbounded)
 INFO 9728 --- [ctor-http-nio-2] reactor.Flux.ContextStart.1              : | onNext(0)
 INFO 9728 --- [ctor-http-nio-2] reactor.Flux.ContextStart.1              : | onNext(1)
 INFO 9728 --- [ctor-http-nio-2] reactor.Flux.ContextStart.1              : | onNext(2)
ERROR 9728 --- [ctor-http-nio-2] c.e.demo.r4.controller.R4Controller      : num generate error, number is : 3, error msg : invalid num
 INFO 9728 --- [ctor-http-nio-2] reactor.Flux.ContextStart.1              : | onNext(4)
 INFO 9728 --- [ctor-http-nio-2] reactor.Flux.ContextStart.1              : | onComplete()

onErrorMap

Source:

@RequestMapping("/error/test")
public Flux<Integer> getNum() {
  return Flux.range(0, 5)
      .map(x -> {
        if (x == 3) {
          throw new IllegalArgumentException("invalid num");
        }
        return x;
      })
      .onErrorMap(exec -> {
        log.error("num generate error, error msg : {}", exec.getMessage());
        throw new RuntimeException("change error type");
      })
      .log();
}
Result:

 INFO 14204 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
 INFO 14204 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : request(unbounded)
 INFO 14204 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(0)
 INFO 14204 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(1)
 INFO 14204 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onNext(2)
ERROR 14204 --- [ctor-http-nio-2] c.e.demo.r4.controller.R4Controller      : num generate error, error msg : invalid num
ERROR 14204 --- [ctor-http-nio-2] reactor.Flux.OnErrorResume.1             : onError(java.lang.RuntimeException: change error type)

[참고링크]
[Webflux Tip] 3. Webflux Error 처리! . (n.d.). https://akageun.github.io/2019/07/26/spring-webflux-tip-3.html.
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

MongoDB Array Query(With MongoTemplate)

 Jini     오후 11:08     mongodb, mongotemplate     No comments   

Mongo Collection 구조

컬렉션명 : bookstore
{
  "_id": "1234567890",
  "books": [
    {
      "bookId": "1",
      "storeList": ["용산", "구로", "신도림A", "신도림B"]
    },
    {
      "bookId": "2",
      "storeList": ["서울역", "영등포A"]
    },
    {
      "bookId": "3",
      "bookNm": "재건축",
      "storeList": ["강남", "개포동"]
    }    
  ]
}

1. books element 추가

Monogo Query:

db.getCollection('bookstore').update(
  { _id: "1234567890" },
  { $push: { books: { bookId: "4", storeList: [ "신사", "대학로", "신촌" ] } } }
)
MongoTemplate:

var query = Query.query(Criteria.where("_id").is("1234567890"));
var update = new Update();
var book = new Book();
book.setBookId("4")
book.setStoreList(Arrays.asList("신사", "대학로", "신촌"));
update.push("books", book);

mongoTemplate.updateFirst(query, update, "bookstore");

2. books element 삭제

Monogo Query:

db.getCollection('bookstore').update(
  { _id: "1234567890" },
  { $pull: { books: { bookId: "4" } } }
)
MongoTemplate:

var query = Query.query(Criteria.where("_id").is("1234567890"));
var pullQuery = new Query();
pullQuery.addCriteria(Criteria.where("bookId").is("4"));
var update = new Update();
update.pull("books", pullQuery);

mongoTemplate.updateFirst(query, update, "bookstore");

3. storeList의 element 추가 - 값이 없는 경우에만

Monogo Query:

db.getCollection('bookstore').update(
  { _id: "1234567890", books: { $elemMatch: { bookId: "3" } } },
  { $addToSet: { "books.$.storeList": "신사동" } }
)
MongoTemplate:

var query = new Query();
var criteria = Criteria.where("_id").is("1234567890")
                  .and("books").elemMatch(Criteria.where("bookId").is("3"));
query.addCriteria(criteria);
var update = new Update();
update.addToSet("books.$.storeList", "신사동");

mongoTemplate.updateFirst(query, update, "bookstore");

4. storeList의 element 삭제

Monogo Query:

db.getCollection('bookstore').update(
  { _id: "1234567890", books: { $elemMatch: { bookId: "3" } } },
  { $pull: { "books.$.storeList": "신사동" } }
)
MongoTemplate:

var query = new Query();
var criteria = Criteria.where("_id").is("1234567890")
                  .and("books").elemMatch(Criteria.where("bookId").is("3"));
query.addCriteria(criteria);
var update = new Update();
update.pull("books.$.storeList", "신사동");

mongoTemplate.updateFirst(query, update, "bookstore");

5. storeList의 element 변경

Monogo Query:

db.getCollection('bookstore').updateOne(
    {_id: "1234567890", books: {$elemMatch:{bookId: "3"}}},
    {$set: {"books.$.bookNm": "재개발"}}
)
MongoTemplate:

var query = new Query();
var criteria = Criteria.where("_id").is("1234567890")
                  .and("books").elemMatch(Criteria.where("bookId").is("3"));
query.addCriteria(criteria);
var update = new Update();
update.set("books.$.bookNm", "재개발");

mongoTemplate.updateFirst(query, update, "bookstore");
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Kafka session.timeout.ms와 max.poll.interval.ms의 차이

 Jini     오후 10:52     kafka     No comments   

session.timeout.ms

컨슈머가 GroupCoordinator에게 해당시간내에 하트비트를 전송하지 않으면 리밸런싱이 일어난다. 컨슈머가 죽었으나 연결이 정상적으로 끊어지지 않는 상황이 발생하면 해당 값에 의해서 인지가 가능하다.
group.min.session.timeout.ms와 group.max.session.timeout.ms 범위 값만 설정가능
default : 10000(10초)

max.poll.interval.ms

다음 poll까지 대기하는 시간. 값이 300000ms인데 poll 내부로직이 300000ms가 넘어가는 경우 리밸런싱이 일어난다.
default : 300000(5분)

아래 코드 참고

@KafkaListener(topics = "xx", groupId = "yy")
public void kafkaListen(String message) throws InterruptedException {
    for (int x = 0; x < 10_000; x++) {
        Thread.sleep(15_000);
    }
}
컨슈머가 GroupCoordinator에게 하트비트는 전송하지만 실제로 아무일도 하지 않는 경우 컨슈머에 문제가 있는 것으로 판단하고 해당 파티션을 제외처리한다.

  • 카프카 0.10.1 버전부터 폴링 간에도 하트비트를 전송할 수 있도록 별도의 하트비트 스레드가 추가되었다고 알고 있음
  • 그래서 poll 내부로직이 오래 걸리더라도 하트비트는 계속 보내기 때문에 리밸런싱이 당연히 발생하지 않을 것으로 예상
  • 하지만 poll 내부로직이 오래 걸리자 리밸런싱이 발생함
  • 의아하게 생각하고 session.timeout.ms를 늘려봤지만 동일한 문제가 발생함
  • 원인을 찾다보니 max.poll.interval.ms 시간을 초과했기 때문이였음
  • poll 내부로직이 오래 걸리면 max.poll.interval.ms 시간을 늘리자
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Blog Template

 Jini     오후 10:30     blogspot     No comments   


  • 지금 적용중인 구글 블로그 Template
    • http://gooyaabitemplates.com/livepreview/the-funk/
  • 페이징 수정
  • stackedit로 작성한 글 변경


Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

구글 블로그 페이지 네비게이션 변경

 Jini     오후 9:24     blogspot     No comments   

3단계로 진행


1. CSS추가
2. Script 추가
3. Label 선택 페이지 설정

1. Adding The CSS

]]></b:skin> 상단에 css 붙여넣기.
아래는 현재 적용된 css. 다른 샘플은 출처페이지 참고

#blog-pager{clear:both;margin:30px auto;text-align:center; padding: 7px; }
.blog-pager {background: none;}
.displaypageNum a,.showpage a,.pagecurrent{font-size: 12px;padding: 5px 12px;margin-right:5px; color: #222; background-color:#eee; border: 1px solid #EEEEEE;}
.displaypageNum a:hover,.showpage a:hover, .pagecurrent{background:#E5E5E5;text-decoration:none;color: #222;}
#blog-pager .pagecurrent{font-weight:bold;color: #fff;background:#DB4920;}
.showpageOf{display:none!important}
#blog-pager .pages{border:none;}
"First", "Last" 버튼을 숨기고 싶은 경우 아래 코드를 추가한다.

.firstpage, .lastpage {display: none;}

2. Adding The Script

</body> 상단에 아래 script추가

<b:if cond='data:blog.pageType != &quot;item&quot;'>  
<b:if cond='data:blog.pageType != &quot;static_page&quot;'>  
<script type='text/javascript'>  
/*<![CDATA[*/  
var perPage=3;  
var numPages=3;  
var firstText ='First';  
var lastText ='Last';  
var prevText ='« Previous';  
var nextText ='Next »';  
var urlactivepage=location.href;  
var home_page="/";  
  
if(typeof firstText=="undefined")firstText="First";if(typeof lastText=="undefined")lastText="Last";var noPage;var currentPage;var currentPageNo;var postLabel;pagecurrentg();function looppagecurrentg(pageInfo){var html='';pageNumber=parseInt(numPages / 2);if(pageNumber==numPages-pageNumber){numPages=pageNumber*2+1}  
pageStart=currentPageNo-pageNumber;if(pageStart<1)pageStart=1;lastPageNo=parseInt(pageInfo / perPage)+1;if(lastPageNo-1==pageInfo / perPage)lastPageNo=lastPageNo-1;pageEnd=pageStart+numPages-1;if(pageEnd>lastPageNo)pageEnd=lastPageNo;html+="<span class='showpageOf'>Page "+currentPageNo+' of '+lastPageNo+"</span>";var prevNumber=parseInt(currentPageNo)-1;if(currentPageNo>1){if(currentPage=="page"){html+='<span class="showpage firstpage"><a href="'+home_page+'">'+firstText+'</a></span>'}else{html+='<span class="displaypageNum firstpage"><a href="/search/label/'+postLabel+'?&max-results='+perPage+'">'+firstText+'</a></span>'}}  
if(currentPageNo>2){if(currentPageNo==3){if(currentPage=="page"){html+='<span class="showpage"><a href="'+home_page+'">'+prevText+'</a></span>'}else{html+='<span class="displaypageNum"><a href="/search/label/'+postLabel+'?&max-results='+perPage+'">'+prevText+'</a></span>'}}else{if(currentPage=="page"){html+='<span class="displaypageNum"><a href="#" onclick="redirectpage('+prevNumber+');return false">'+prevText+'</a></span>'}else{html+='<span class="displaypageNum"><a href="#" onclick="redirectlabel('+prevNumber+');return false">'+prevText+'</a></span>'}}}  
if(pageStart>1){if(currentPage=="page"){html+='<span class="displaypageNum"><a href="'+home_page+'">1</a></span>'}else{html+='<span class="displaypageNum"><a href="/search/label/'+postLabel+'?&max-results='+perPage+'">1</a></span>'}}  
if(pageStart>2){html+=' ... '}  
for(var jj=pageStart;jj<=pageEnd;jj++){if(currentPageNo==jj){html+='<span class="pagecurrent">'+jj+'</span>'}else if(jj==1){if(currentPage=="page"){html+='<span class="displaypageNum"><a href="'+home_page+'">1</a></span>'}else{html+='<span class="displaypageNum"><a href="/search/label/'+postLabel+'?&max-results='+perPage+'">1</a></span>'}}else{if(currentPage=="page"){html+='<span class="displaypageNum"><a href="#" onclick="redirectpage('+jj+');return false">'+jj+'</a></span>'}else{html+='<span class="displaypageNum"><a href="#" onclick="redirectlabel('+jj+');return false">'+jj+'</a></span>'}}}  
if(pageEnd<lastPageNo-1){html+='...'}  
if(pageEnd<lastPageNo){if(currentPage=="page"){html+='<span class="displaypageNum"><a href="#" onclick="redirectpage('+lastPageNo+');return false">'+lastPageNo+'</a></span>'}else{html+='<span class="displaypageNum"><a href="#" onclick="redirectlabel('+lastPageNo+');return false">'+lastPageNo+'</a></span>'}}  
var nextnumber=parseInt(currentPageNo)+1;if(currentPageNo<(lastPageNo-1)){if(currentPage=="page"){html+='<span class="displaypageNum"><a href="#" onclick="redirectpage('+nextnumber+');return false">'+nextText+'</a></span>'}else{html+='<span class="displaypageNum"><a href="#" onclick="redirectlabel('+nextnumber+');return false">'+nextText+'</a></span>'}}  
if(currentPageNo<lastPageNo){if(currentPage=="page"){html+='<span class="displaypageNum lastpage"><a href="#" onclick="redirectpage('+lastPageNo+');return false">'+lastText+'</a></span>'}else{html+='<span class="displaypageNum lastpage"><a href="#" onclick="redirectlabel('+lastPageNo+');return false">'+lastText+'</a></span>'}}  
var pageArea=document.getElementsByName("pageArea");var blogPager=document.getElementById("blog-pager");for(var p=0;p<pageArea.length;p++){pageArea[p].innerHTML=html}  
if(pageArea&&pageArea.length>0){html=''}  
if(blogPager){blogPager.innerHTML=html}}  
function totalcountdata(root){var feed=root.feed;var totaldata=parseInt(feed.openSearch$totalResults.$t,10);looppagecurrentg(totaldata)}  
function pagecurrentg(){var thisUrl=urlactivepage;if(thisUrl.indexOf("/search/label/")!=-1){if(thisUrl.indexOf("?updated-max")!=-1){postLabel=thisUrl.substring(thisUrl.indexOf("/search/label/")+14,thisUrl.indexOf("?updated-max"))}else{postLabel=thisUrl.substring(thisUrl.indexOf("/search/label/")+14,thisUrl.indexOf("?&max"))}}  
if(thisUrl.indexOf("?q=")==-1&&thisUrl.indexOf(".html")==-1){if(thisUrl.indexOf("/search/label/")==-1){currentPage="page";if(urlactivepage.indexOf("#PageNo=")!=-1){currentPageNo=urlactivepage.substring(urlactivepage.indexOf("#PageNo=")+8,urlactivepage.length)}else{currentPageNo=1}  
document.write("<script src=\""+home_page+"feeds/posts/summary?max-results=1&alt=json-in-script&callback=totalcountdata\"><\/script>")}else{currentPage="label";if(thisUrl.indexOf("&max-results=")==-1){perPage=20}  
if(urlactivepage.indexOf("#PageNo=")!=-1){currentPageNo=urlactivepage.substring(urlactivepage.indexOf("#PageNo=")+8,urlactivepage.length)}else{currentPageNo=1}  
document.write('<script src="'+home_page+'feeds/posts/summary/-/'+postLabel+'?alt=json-in-script&callback=totalcountdata&max-results=1" ><\/script>')}}}  
function redirectpage(numberpage){jsonstart=(numberpage-1)*perPage;noPage=numberpage;var nameBody=document.getElementsByTagName('head')[0];var newInclude=document.createElement('script');newInclude.type='text/javascript';newInclude.setAttribute("src",home_page+"feeds/posts/summary?start-index="+jsonstart+"&max-results=1&alt=json-in-script&callback=finddatepost");nameBody.appendChild(newInclude)}  
function redirectlabel(numberpage){jsonstart=(numberpage-1)*perPage;noPage=numberpage;var nameBody=document.getElementsByTagName('head')[0];var newInclude=document.createElement('script');newInclude.type='text/javascript';newInclude.setAttribute("src",home_page+"feeds/posts/summary/-/"+postLabel+"?start-index="+jsonstart+"&max-results=1&alt=json-in-script&callback=finddatepost");nameBody.appendChild(newInclude)}  
function finddatepost(root){post=root.feed.entry[0];var timestamp1=post.published.$t.substring(0,19)+post.published.$t.substring(23,29);var timestamp=encodeURIComponent(timestamp1);if(currentPage=="page"){var pAddress="/search?updated-max="+timestamp+"&max-results="+perPage+"#PageNo="+noPage}else{var pAddress="/search/label/"+postLabel+"?updated-max="+timestamp+"&max-results="+perPage+"#PageNo="+noPage}  
location.href=pAddress}  
/*]]>*/  
</script>  
</b:if>  
</b:if>
perPage : 한 페이지당 노출할 post개수, 메인 페이지의 글수와 동일해야 한다.
numPages : 네비게이션 영역에 표시할 페이지 번호 범위(7인 경우 아래와 같이 표시된다.)

3. Labels fix

라벨 선택화면은 위에 적용한 페이지 네비게이션이 적용되지 않는다. 라벨 선택화면에도 페이지 네비게션을 적용하기 위해서는 아래 코드를

expr:href='data:label.url'
아래 코드로 변경한다.

expr:href='data:label.url + "?&max-results=7"'
max-results값은 라벨 선택 페이지에서 노출할 포스트의 개수

4. 추가

필자의 경우 페이징당 노출 포스팅 수를 7로 했는데도 불구하고 첫페이지가 계속 3개만 노출되는 문제가 발생했었다.
두 번째 페이지 부터는 정상적으로 7개씩 노출되었는데 이게 문제가 되는 것이 페이징이 꼬이다보니 노출되지 않는 글이 발생했다.
찾아보니 구글에서 페이지 최적화를 위해 내용이 긴 포스팅 있으면 자동으로 페이지당 노출 글자수를 줄인다고 한다.
그래서 내용이 긴 포스팅(기준은 모르겠다) 때문에 발생하는 문제라면 해당 포스팅에 점프브레이크()를 넣어서 해결하면 된다.


[참고링크]
https://helplogger.blogspot.com/2014/04/how-to-add-numbered-page-navigation-widget-for-blogger.html
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

26 Reasons Why Using Optional Correctly Is Not Optional

 Jini     오후 2:04     JAVA, optional     No comments   

1. Never Assign Null to an Optional Variable

Avoid:


// AVOID
public Optional<Cart> fetchCart() {
 Optional<Cart> emptyCart = null;
 ...
}

Prefer:


// PREFER
public Optional<Cart> fetchCart() {
 Optional<Cart> emptyCart = Optional.empty();
 ...
}

Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Why should one use Objects.requireNonNull()?

 Jini     오후 11:12     No comments   

public class Foo {
  private final Bar bar;

  public Foo(Bar bar) {
    Objects.requireNonNull(bar, "bar must not be null");
    this.bar = bar;
  }
}
The major advantages are:
  • as said, controlled behavior
  • easier debugging - because you throw up in the context of the object creation. At a point in time where you have a certain chance that your logs/traces tell you what went wrong!
  • and as shown above: the true power of this idea unfolds in conjunction with final fields. Because now any other code in your class can safely assume that bar isn’t null - and thus you do not need any if (bar == null) checks in other places!
개인적으로 세 번째가 가장 큰 장점이라 생각된다.

[출처]
Why should one use Objects.requireNonNull()?
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
최근 게시물 이전 게시물 홈

Popular Posts

  • Redmine Text Format
    1. 글자색상 변경 %{color:red}dev% 2. 음영색상 변경 %{background:lightgreen} lightgreen% 3. 문단 넘버링(띄어쓰기 주의) # 큰 제목 ## 큰제목의 하위 제목 # 두번째 큰 제목 # ...
  • 오라클 한글깨짐 현상해결
    1. 레지스트리 편집기 실행 : 시작 -> 실행 -> regedit 2. HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE 하위 경로 폴더중 이름이 "NLS_LANG"인 속성의 데이터 확인 3. "...
  • 오브젝트 : 코드로 이해하는 객체지향 설계
    오브젝트 - 코드로 이해하는 객체지향 설계 / 조영호 지음 / 위키북스 객체지향에 대해 그 동안 잊고 있었던 것들을 상기시켜주고 새로운 인사이트를 줬으며 그 동안의 설계에 대해 돌이켜 보게 해준 유익한 책. 객체 사이의 의존성을 완전히 없애는 것이 정...
  • New Features Java 1.7(JDK 1.7)
    ■ The New Objects Class   1) Objects.requireNonNull(T), Objects.requireNonNull(T, String)     #. 아래 Person 객체 생성시 newLastName이나 newFirstNa...
  • MongoDB Array Query(With MongoTemplate)
    Mongo Collection 구조 컬렉션명 : bookstore { "_id": "1234567890", "books": [ { "bookId": ...

Recent Posts

Recent Posts Widget

Blog Archive

  • ►  2023 (4)
    • ►  3월 (1)
    • ►  2월 (1)
    • ►  1월 (2)
  • ►  2022 (1)
    • ►  2월 (1)
  • ▼  2020 (8)
    • ▼  7월 (1)
      • Java 버전별 특징 및 변경사항
    • ►  4월 (3)
      • WebFlux Error Handling
      • MongoDB Array Query(With MongoTemplate)
      • Kafka session.timeout.ms와 max.poll.interval.ms의 차이
    • ►  3월 (4)
      • Blog Template
      • 구글 블로그 페이지 네비게이션 변경
      • 26 Reasons Why Using Optional Correctly Is Not Opt...
      • Why should one use Objects.requireNonNull()?
  • ►  2018 (1)
    • ►  7월 (1)
  • ►  2015 (1)
    • ►  5월 (1)
  • ►  2014 (5)
    • ►  8월 (1)
    • ►  7월 (1)
    • ►  6월 (1)
    • ►  5월 (1)
    • ►  1월 (1)
  • ►  2013 (10)
    • ►  12월 (1)
    • ►  11월 (1)
    • ►  9월 (2)
    • ►  8월 (3)
    • ►  7월 (3)
  • ►  2012 (1)
    • ►  3월 (1)

Categories

  • 객체지향 (1)
  • 도서요약 (1)
  • 문법에서 문장까지 (2)
  • 일상 (1)
  • 자기계발 (1)
  • 책 (1)
  • 키보드 (1)
  • 키크론 (1)
  • blogspot (2)
  • error (1)
  • exception (1)
  • GIT (1)
  • JAVA (6)
  • JUNIT (1)
  • K8 PRO RGB (1)
  • kafka (1)
  • markdown (1)
  • mongodb (2)
  • mongotemplate (1)
  • optional (1)
  • Oracle (4)
  • Redmine (1)
  • spring (1)
  • stackedit (1)
  • troubleshooting (1)
  • Visual Studio (1)
  • Webflux (1)

Unordered List

Pages

  • 홈

Text Widget

Categories

Tags

Facebook

  • Home
  • Features
  • _Multi DropDown
  • __DropDown 1
  • __DropDown 2
  • __DropDown 3
  • _ShortCodes
  • _SiteMap
  • _Error Page
  • Documentation
  • Video Documentation
  • Download This Template

Footer Menu Widget

  • Home
  • About
  • Contact Us

Social Plugin

JINI. Powered by Blogger.

Copyright © Jini's Blog | Powered by Blogger
Design by Hardeep Asrani | Blogger Theme by NewBloggerThemes.com | Distributed By Gooyaabi Templates