'view'에 해당되는 글 3건

  1. 2020.07.21 [Spring] viewResolver return types...
  2. 2020.04.24 [Thymeleaf] Springboot + Thymeleaf 사용 시 viewResolver 이슈.
  3. 2015.12.09 [Elasticsearch] Tribe Node

[Spring] viewResolver return types...

ITWeb/개발일반 2020. 7. 21. 10:45

[참고문서]

https://docs.spring.io/spring/docs/4.3.12.RELEASE/spring-framework-reference/htmlsingle/#mvc-ann-return-types

https://docs.spring.io/spring/docs/3.0.0.M3/spring-framework-reference/html/ch16s03.html

 

Spring mvc framework 에서 Controller 에서 사용하는 return type 에 따른 viewResolver 적용방법이 다릅니다.

위 문서를 보시면 이해 하실 수 있습니다.

 

가장 많이 사용 하는 몇 개만 뽑아 왔습니다.

 

  • A ModelAndView object, with the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.
  • A Model object, with the view name implicitly determined through a RequestToViewNameTranslator and the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.
  • A Map object for exposing a model, with the view name implicitly determined through a RequestToViewNameTranslator and the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.
  • A View object, with the model implicitly determined through command objects and @ModelAttribute annotated reference data accessor methods. The handler method may also programmatically enrich the model by declaring a Model argument (see above).
  • A String value that is interpreted as the logical view name, with the model implicitly determined through command objects and @ModelAttribute annotated reference data accessor methods. The handler method may also programmatically enrich the model by declaring a Model argument (see above).
  • void if the method handles the response itself (by writing the response content directly, declaring an argument of type ServletResponse / HttpServletResponse for that purpose) or if the view name is supposed to be implicitly determined through a RequestToViewNameTranslator (not declaring a response argument in the handler method signature).
  • If the method is annotated with @ResponseBody, the return type is written to the response HTTP body. The return value will be converted to the declared method argument type using HttpMessageConverters. See the section called “Mapping the response body with the @ResponseBody annotation”.

제가 실수한 부분은 void 로 선언을 해 놓고 template 수정 후 반영이 되지 않아 cache 를 의심 했었는데 역시 원인은 제가 선언을 잘 못 했기 때문 이였습니다.

 

void 로 선언 시 해석은 

@GetMapping("/hello")
public void helloworld() {...}

hello.html 을 template 으로 찾게 됩니다.

 

:

[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"; 

로 작성을 하시면 됩니다.

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

:

[Elasticsearch] Tribe Node

Elastic/Elasticsearch 2015. 12. 9. 12:05

tribe node는 서로 다른 cluster로 구성된 elasticsearch의 데이터에 대해서 질의 또는 색인이 가능 하도록 제공하는 기능 입니다.

RDBMS의 view 와 비슷한 개념이라고 생각 하시면 쉽습니다.


참고문서)

https://www.elastic.co/guide/en/elasticsearch/reference/2.1/modules-tribe.html

https://www.elastic.co/blog/clustering_across_multiple_data_centers

https://www.elastic.co/blog/tribe-node


이제 부터 간단하게 구성하는 방법을 살펴 보겠습니다.

elasticsearch 다운로드와 설치 과정은 아래 링크 참고하세요.

- https://www.elastic.co/guide/en/elasticsearch/reference/current/_installation.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html


1. 노드구성

위에서 이야기 한 것과 같이 서로 다른 Cluster라고 했습니다.

그렇기 때문에 standalone 구성의 cluster 두 개를 준비 하겠습니다.

더불어 tribe node 도 하나 구성을 합니다.

- 총 3개의 노드


2. 노드설정

- Cluster 1

[elasticsearch.yml]

cluster.name: t1-cluster

node.name: t1-node

http.port: 9201

transport.tcp.port: 9301

index.number_of_shards: 1

index.number_of_replicas: 0


- Cluster 2

[elasticsearch.yml]

cluster.name: t2-cluster

node.name: t2-node

http.port: 9202

transport.tcp.port: 9302

index.number_of_shards: 1

index.number_of_replicas: 0


- Tribe Node(cluster)

[elasticsearch.yml]

tribe.t1.cluster.name: "t1-cluster"

tribe.t1.discovery.zen.ping.multicast.enabled: false

tribe.t1.discovery.zen.ping.unicast.hosts: ["localhost:9301"]

tribe.t2.cluster.name: "t2-cluster"

tribe.t2.discovery.zen.ping.multicast.enabled: false

tribe.t2.discovery.zen.ping.unicast.hosts: ["localhost:9302"]

tribe.blocks.write: true

tribe.blocks.metadata: true

cluster.name: "tribe-cluster"

node.name: "tribe-node"

http.port: 9200


3. 클러스터실행

생성한 3개의 클러스터를 실행 합니다.


4. Cluste 1과 Cluster 2에 Index 생성 및 색인

그냥 구성 샘플이라 문서 하나씩만 색인 하겠습니다.


Cluster 1)

- sample1.json

{"index":{"_index":"db", "_type":"tbl"}}

{"number":"1","name":"MALICE MIZER","url":"http://www.last.fm/music/MALICE+MIZER","picture":"http://userserve-ak.last.fm/serve/252/10808.jpg","@timestamp":"2000-10-06T19:20:25.000Z"}


$ curl -XPOST http://localhost:9201/db/tbl/_bulk --data-binary @sample1.json


Cluster 2)

- sample2.json

{"index":{"_index":"db2", "_type":"tbl"}}

{"number":"2","name":"Diary of Dreams","url":"http://www.last.fm/music/Diary+of+Dreams","picture":"http://userserve-ak.last.fm/serve/252/3052066.jpg","@timestamp":"2001-10-06T19:20:25.000Z"}


$ curl -XPOST http://localhost:9202/db2/tbl/_bulk --data-binary @sample2.json


5. Tribe Node(Cluster)를 이용한 질의

질의) Cluster 1

$ curl -XGET "http://localhost:9200/db/_search" -d'

{

    "query": {

        "match_all": {}

    }

}'


결과)

{

   "took": 24,

   "timed_out": false,

   "_shards": {

      "total": 1,

      "successful": 1,

      "failed": 0

   },

   "hits": {

      "total": 1,

      "max_score": 1,

      "hits": [

         {

            "_index": "db",

            "_type": "tbl",

            "_id": "AVFhPAntBw75btupmZWX",

            "_score": 1,

            "_source": {

               "number": "1",

               "name": "MALICE MIZER",

               "url": "http://www.last.fm/music/MALICE+MIZER",

               "picture": "http://userserve-ak.last.fm/serve/252/10808.jpg",

               "@timestamp": "2000-10-06T19:20:25.000Z"

            }

         }

      ]

   }

}


질의) Cluster 2

curl -XGET "http://localhost:9200/db2/_search" -d'

{

    "query": {

        "match_all": {}

    }

}'


결과)

{

   "took": 16,

   "timed_out": false,

   "_shards": {

      "total": 1,

      "successful": 1,

      "failed": 0

   },

   "hits": {

      "total": 1,

      "max_score": 1,

      "hits": [

         {

            "_index": "db2",

            "_type": "tbl",

            "_id": "AVFha2Vz4YXacqLkqH0V",

            "_score": 1,

            "_source": {

               "number": "2",

               "name": "Diary of Dreams",

               "url": "http://www.last.fm/music/Diary+of+Dreams",

               "picture": "http://userserve-ak.last.fm/serve/252/3052066.jpg",

               "@timestamp": "2001-10-06T19:20:25.000Z"

            }

         }

      ]

   }

}


View 질의) Tribe Node(Cluster)

$ curl -XGET "http://localhost:9200/_search" -d'

{

    "query": {

        "match_all": {}

    }

}'


결과)

{

   "took": 12,

   "timed_out": false,

   "_shards": {

      "total": 2,

      "successful": 2,

      "failed": 0

   },

   "hits": {

      "total": 2,

      "max_score": 1,

      "hits": [

         {

            "_index": "db",

            "_type": "tbl",

            "_id": "AVFhPAntBw75btupmZWX",

            "_score": 1,

            "_source": {

               "number": "1",

               "name": "MALICE MIZER",

               "url": "http://www.last.fm/music/MALICE+MIZER",

               "picture": "http://userserve-ak.last.fm/serve/252/10808.jpg",

               "@timestamp": "2000-10-06T19:20:25.000Z"

            }

         },

         {

            "_index": "db2",

            "_type": "tbl",

            "_id": "AVFha2Vz4YXacqLkqH0V",

            "_score": 1,

            "_source": {

               "number": "2",

               "name": "Diary of Dreams",

               "url": "http://www.last.fm/music/Diary+of+Dreams",

               "picture": "http://userserve-ak.last.fm/serve/252/3052066.jpg",

               "@timestamp": "2001-10-06T19:20:25.000Z"

            }

         }

      ]

   }

}


※ 부가적으로 alias 기능과 함께 활용하시면 아주 유용하게 사용하실 수 있습니다.

: