<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2489048893687165335</id><updated>2024-10-25T04:54:45.441+09:00</updated><category term="Oracle"/><category term="java"/><category term="groovy"/><category term="coffeescript"/><category term="euler"/><category term="intellij"/><category term="ruby"/><category term="JavaScript"/><category term="scala"/><category term="jQuery"/><category term="Jackson"/><category term="PostgreSQL"/><category term="java7"/><category term="Oracle12"/><category term="Kotlin"/><category term="html5"/><category term="JPA"/><category term="css3"/><category term="idea"/><category term="Java8"/><category term="Maven"/><category term="Hibernate"/><category term="MySql"/><category term="Spring Boot"/><category term="Vim"/><category term="rails"/><category term="本"/><category term="AngularJS"/><category term="Gradle"/><category term="H2"/><category term="JMockit"/><category term="Windows"/><category term="JDBC"/><category term="JPA2.1"/><category term="SQL Server"/><category term="elasticsearch"/><category term="mvn"/><category term="tomcat"/><category term="CSV"/><category term="JPA2"/><category term="SQL*Loader"/><category term="Spring"/><category term="assertj"/><category term="thymeleaf"/><category term="tomcat8"/><category term="Activiti"/><category term="AngularJS1.3"/><category term="Concourse"/><category term="Flyway"/><category term="Fuel"/><category term="Go"/><category term="Hibernate5"/><category term="IME"/><category term="JMockit1.13"/><category term="JMockit1.23"/><category term="JUnit"/><category term="JUnit-Rule"/><category term="JUnit4"/><category term="JUnit5"/><category term="Java9"/><category term="Javadoc"/><category term="Jenkins"/><category term="Oracle Maven Repository"/><category term="Oracle NoSQL"/><category term="Pipeline Utility Steps"/><category term="Semantic-UI"/><category term="Semantic-UI-Calendar"/><category term="Spring Boot 2.0.2.RELEASE"/><category term="Spring Security"/><category term="Spring data JPA"/><category term="VBA"/><category term="assertj-db"/><category term="docker-compose"/><category term="eclipselink"/><category term="elasticsearch 6.5"/><category term="git"/><category term="maven-surefire-plugin"/><category term="mdl"/><category term="nio2"/><category term="play"/><category term="psql"/><category term="rails4"/><category term="readlink"/><category term="svn"/><category term="tomcat 8.0.45"/><category term="tomcat9"/><category term="ubuntu"/><category term="xml"/><category term="zsh"/><category term="数値"/><title type='text'>備忘録的なblog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://se-bikou.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>317</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-7712481269040601743</id><published>2019-07-15T06:59:00.002+09:00</published><updated>2019-07-15T06:59:46.787+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Fuel"/><category scheme="http://www.blogger.com/atom/ns#" term="Kotlin"/><title type='text'>KotlinのHttp ClientのFuelでレスポンスをJacksonでデシリアライズする</title><content type='html'>FuelでレスポンスのjsonをJacksonでデシリアライズする方法&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;依存ライブラリ&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;groovy&quot;&gt;  implementation(&quot;com.github.kittinunf.fuel:fuel:2.1.0&quot;)
  implementation(&quot;com.github.kittinunf.fuel:fuel-coroutines:2.1.0&quot;)
  implementation(&quot;com.github.kittinunf.fuel:fuel-jackson:2.1.0&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;サンプル&lt;/h3&gt;responseObjectにjacksonDeserializerOfを指定する子でJacksonを使ったデシリアライズが行われる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;fun main() {
    &quot;https://jsonplaceholder.typicode.com/todos/1&quot;
            .httpGet()
            .responseObject(jacksonDeserializerOf&lt;Result&gt;()) { request, response, result -&gt;
                println(&quot;response.statusCode = ${response.statusCode}&quot;)
                println(&quot;result.component1() = ${result.component1()}&quot;)
                println(&quot;result.component2() = ${result.component2()}&quot;)
            }
            .join()
}

data class Result(
        val userId:Int,
        val id: Int,
        val title: String,
        val completed: Boolean
)
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7712481269040601743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7712481269040601743'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2019/07/kotlinhttp-clientfueljackson.html' title='KotlinのHttp ClientのFuelでレスポンスをJacksonでデシリアライズする'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-8365964458732670141</id><published>2019-06-15T06:46:00.002+09:00</published><updated>2019-06-15T06:46:53.438+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Spring data JPA"/><title type='text'>Spring data JPAで範囲指定の検索</title><content type='html'>範囲指定で検索したい場合は、検索メソッドにPageableを渡してあげると良い。&lt;br /&gt;
ロジックで、Pageableを生成したい場合は、以下のようにPageRequest.ofを使う。&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;val pageRequest = PageRequest.of(0, 5)
val result = testRepository.findAll(pageRequest)
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/8365964458732670141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/8365964458732670141'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2019/06/spring-data-jpa.html' title='Spring data JPAで範囲指定の検索'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-3251285539601027933</id><published>2019-04-13T07:26:00.002+09:00</published><updated>2019-04-13T07:26:49.434+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="elasticsearch"/><title type='text'>Elasticsearchのインデックス内の全データの削除</title><content type='html'>&lt;h1&gt;削除対象のインデックスの内容&lt;/h1&gt;&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;curl -H &#39;Content-Type: application/json&#39; http://localhost:9200/test/_search\?pretty -d &#39;{&quot;query&quot;:{&quot;match_all&quot;:{}},&quot;size&quot;:0}&#39;
{
  &quot;took&quot; : 6,
  &quot;timed_out&quot; : false,
  &quot;_shards&quot; : {
    &quot;total&quot; : 5,
    &quot;successful&quot; : 5,
    &quot;skipped&quot; : 0,
    &quot;failed&quot; : 0
  },
  &quot;hits&quot; : {
    &quot;total&quot; : 101,
    &quot;max_score&quot; : 0.0,
    &quot;hits&quot; : [ ]
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h1&gt;データの削除&lt;/h1&gt;_delete_by_queryを使ってデータを削除する。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;curl -X POST -H &#39;Content-Type: application/json&#39; http://localhost:9200/test/_delete_by_query?pretty -d &#39;{&quot;query&quot;:{&quot;match_all&quot;:{}}}&#39;
{
  &quot;took&quot; : 106,
  &quot;timed_out&quot; : false,
  &quot;total&quot; : 101,
  &quot;deleted&quot; : 101,
  &quot;batches&quot; : 1,
  &quot;version_conflicts&quot; : 0,
  &quot;noops&quot; : 0,
  &quot;retries&quot; : {
    &quot;bulk&quot; : 0,
    &quot;search&quot; : 0
  },
  &quot;throttled_millis&quot; : 0,
  &quot;requests_per_second&quot; : -1.0,
  &quot;throttled_until_millis&quot; : 0,
  &quot;failures&quot; : [ ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h1&gt;削除確認&lt;/h1&gt;&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;curl -H &#39;Content-Type: application/json&#39; http://localhost:9200/test/_search\?pretty -d &#39;{&quot;query&quot;:{&quot;match_all&quot;:{}},&quot;size&quot;:0}&#39;
{
  &quot;took&quot; : 6,
  &quot;timed_out&quot; : false,
  &quot;_shards&quot; : {
    &quot;total&quot; : 5,
    &quot;successful&quot; : 5,
    &quot;skipped&quot; : 0,
    &quot;failed&quot; : 0
  },
  &quot;hits&quot; : {
    &quot;total&quot; : 0,
    &quot;max_score&quot; : 0.0,
    &quot;hits&quot; : [ ]
  }
}
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/3251285539601027933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/3251285539601027933'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2019/04/elasticsearch.html' title='Elasticsearchのインデックス内の全データの削除'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-649865716085697083</id><published>2019-03-17T07:09:00.000+09:00</published><updated>2019-03-17T07:09:09.320+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CSV"/><category scheme="http://www.blogger.com/atom/ns#" term="Jackson"/><title type='text'>JacksonでCSVの読み込み</title><content type='html'>&lt;h2&gt;ヘッダなしCSVファイルの読み込み&lt;/h2&gt;CsvSchemaでカラムを定義してBeanとマッピングする。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;kotlin&quot;&gt;fun main(args: Array&lt;String&gt;) {
    val csvSchema = CsvSchema.builder()
            .addColumn(&quot;id&quot;)
            .addColumn(&quot;name&quot;)
            .build()
    val csvMapper = CsvMapper()
    csvMapper.registerModule(KotlinModule())

    val csvFile = csvMapper.readerFor(CsvFile::class.java)
            .with(csvSchema)
            .readValues&lt;CsvFile&gt;(&quot;&quot;&quot;
                1,test
                2,test2
                3,test3
            &quot;&quot;&quot;.trimIndent())
    
    csvFile.forEach {
        println(&quot;it = ${it}&quot;)
    }
    
}

data class CsvFile(
        val id:Long,
        val name:String
)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;ヘッダありCSVファイルの読み込み&lt;/h2&gt;Schemaに対して、useHeaderを設定するとヘッダありファイルを読み込める。&lt;br /&gt;
ヘッダの内容をもとにプロパティとのマッピングが行われるので、ヘッダなしのときのようなSchemaでのカラム定義が必要なくなる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;kotlin&quot;&gt;fun main(args: Array&lt;String&gt;) {
    val csvSchema = CsvSchema.builder()
            .setUseHeader(true)
            .build()
    val csvMapper = CsvMapper()
    csvMapper.registerModule(KotlinModule())

    val csvFile = csvMapper.readerFor(CsvFile::class.java)
            .with(csvSchema)
            .readValues&lt;CsvFile&gt;(&quot;&quot;&quot;
                id,name
                1,test
                2,test2
                3,test3
            &quot;&quot;&quot;.trimIndent())
    
    csvFile.forEach {
        println(&quot;it = ${it}&quot;)
    }
    
}

data class CsvFile(
        val id:Long,
        val name:String
)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;ヘッダ名とプロパティ名が一致しない場合の読み込み&lt;/h2&gt;ヘッダなしのファイルと読み込む場合と同じように、カラム定義が必要となる。&lt;br /&gt;
カラム定義を行わず、対象のプロパティに対して@JsonProperty(&quot;なまえ&quot;)とすることでもマッピングができる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;kotlin&quot;&gt;fun main(args: Array&lt;String&gt;) {
    val csvSchema = CsvSchema.builder()
            .addColumn(&quot;id&quot;)
            .addColumn(&quot;name&quot;)
            .setUseHeader(true)
            .build()
    val csvMapper = CsvMapper()
    csvMapper.registerModule(KotlinModule())

    val csvFile = csvMapper.readerFor(CsvFile::class.java)
            .with(csvSchema)
            .readValues&lt;CsvFile&gt;(&quot;&quot;&quot;
                id,なまえ
                1,test
                2,test2
                3,test3
            &quot;&quot;&quot;.trimIndent())
    
    csvFile.forEach {
        println(&quot;it = ${it}&quot;)
    }
    
}

data class CsvFile(
        val id:Long,
        val name:String
)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;クォートで囲まれている要素の読み込み&lt;/h2&gt;QuoteCharでクォート文字を設定することで、その文字で囲まれている要素を読み込める。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;kotlin&quot;&gt;fun main(args: Array&lt;String&gt;) {
    val csvSchema = CsvSchema.builder()
            .setUseHeader(true)
            .setQuoteChar(&#39;&quot;&#39;)
            .build()
    val csvMapper = CsvMapper()
    csvMapper.registerModule(KotlinModule())

    val csvFile = csvMapper.readerFor(CsvFile::class.java)
            .with(csvSchema)
            .readValues&lt;CsvFile&gt;(&quot;&quot;&quot;
                id,なまえ
                1,&quot;test&quot;
                2,&quot;te&quot;&quot;st2&quot;
                3,&quot;test3&quot;
            &quot;&quot;&quot;.trimIndent())
    
    csvFile.forEach {
        println(&quot;it = ${it}&quot;)
    }
    
}

data class CsvFile(
        val id:Long,
        @JsonProperty(&quot;なまえ&quot;)
        val name:String
)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;Beanに定義されていないカラムを無視して読み込む&lt;/h2&gt;FAIL_ON_UNKNOWN_PROPERTIESをfalseにすることで、未定義のプロパティがあったときでも無視して読み込みが行われる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;kotlin&quot;&gt;fun main(args: Array&lt;String&gt;) {
    val csvSchema = CsvSchema.builder()
            .setUseHeader(true)
            .setQuoteChar(&#39;&quot;&#39;)
            .build()
    val csvMapper = CsvMapper().apply {
        registerModule(KotlinModule())
        configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    }

    val csvFile = csvMapper.readerFor(CsvFile::class.java)
            .with(csvSchema)
            .readValues&lt;CsvFile&gt;(&quot;&quot;&quot;
                id,なまえ,そのた
                1,&quot;test&quot;,hoge
                2,&quot;tes2&quot;,fuga
                3,&quot;test3&quot;,piyo
            &quot;&quot;&quot;.trimIndent())
    
    csvFile.forEach {
        println(&quot;it = ${it}&quot;)
    }
    
}

data class CsvFile(
        val id:Long,
        @JsonProperty(&quot;なまえ&quot;)
        val name:String
)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/649865716085697083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/649865716085697083'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2019/03/jacksoncsv.html' title='JacksonでCSVの読み込み'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-2200325660057207718</id><published>2019-02-03T07:42:00.000+09:00</published><updated>2019-02-03T07:42:19.395+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="elasticsearch"/><category scheme="http://www.blogger.com/atom/ns#" term="elasticsearch 6.5"/><title type='text'>ElasticsearchのクエリDSLでand検索</title><content type='html'>ElasticsearchのクエリDSLでのand検索&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;インデクスの内容&lt;/h3&gt;&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;
 curl -H &#39;Content-Type:application/json&#39; http://localhost:9200/test_index/_search -d &#39;{&quot;query&quot;: {&quot;match_all&quot;:{}}}&#39; | jq &#39;.hits.hits&#39;
[
  {
    &quot;_index&quot;: &quot;test_index&quot;,
    &quot;_type&quot;: &quot;test&quot;,
    &quot;_id&quot;: &quot;1&quot;,
    &quot;_score&quot;: 1,
    &quot;_source&quot;: {
      &quot;user_name&quot;: &quot;test user1&quot;
    }
  },
  {
    &quot;_index&quot;: &quot;test_index&quot;,
    &quot;_type&quot;: &quot;test&quot;,
    &quot;_id&quot;: &quot;2&quot;,
    &quot;_score&quot;: 1,
    &quot;_source&quot;: {
      &quot;user_name&quot;: &quot;test user2&quot;
    }
  }
]
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;デフォルトでのmatchクエリ&lt;/h3&gt;デフォルトでは、検索条件で指定した&lt;b&gt;user&lt;/b&gt;と&lt;b&gt;test1&lt;/b&gt;のOR検索になるので、&lt;b&gt;test user2&lt;/b&gt;もヒットする。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;
curl -H &#39;Content-Type:application/json&#39; http://localhost:9200/test_index/_search -d &#39;{&quot;query&quot;: {&quot;match&quot;:{&quot;user_name&quot;: &quot;test user1&quot;}}}&#39; | jq &#39;.hits.hits&#39;
[
  {
    &quot;_index&quot;: &quot;test_index&quot;,
    &quot;_type&quot;: &quot;test&quot;,
    &quot;_id&quot;: &quot;1&quot;,
    &quot;_score&quot;: 0.87546873,
    &quot;_source&quot;: {
      &quot;user_name&quot;: &quot;test user1&quot;
    }
  },
  {
    &quot;_index&quot;: &quot;test_index&quot;,
    &quot;_type&quot;: &quot;test&quot;,
    &quot;_id&quot;: &quot;2&quot;,
    &quot;_score&quot;: 0.18232156,
    &quot;_source&quot;: {
      &quot;user_name&quot;: &quot;test user2&quot;
    }
  }
]
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;AND検索&lt;/h3&gt;operatorにandを指定するとAND条件に変更でき、検索結果からuser2のデータが消える。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;
curl -H &#39;Content-Type:application/json&#39; http://localhost:9200/test_index/_search -d &#39;{&quot;query&quot;: {&quot;match&quot;:{&quot;user_name&quot;: {&quot;query&quot;:&quot;test user1&quot;, &quot;operator&quot;:&quot;and&quot; }}}}&#39; | jq .hits.hits
[
  {
    &quot;_index&quot;: &quot;test_index&quot;,
    &quot;_type&quot;: &quot;test&quot;,
    &quot;_id&quot;: &quot;1&quot;,
    &quot;_score&quot;: 0.87546873,
    &quot;_source&quot;: {
      &quot;user_name&quot;: &quot;test user1&quot;
    }
  }
]
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;その他の指定&lt;/h3&gt;&lt;b&gt;minimum_should_match&lt;/b&gt;で、指定したキーワードのうち何個マッチ以上マッチしたものを返すことができる。&lt;br /&gt;
この場合は、1を指定しているので1つ以上マッチしたものがヒットする&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;
 curl -H &#39;Content-Type:application/json&#39; http://localhost:9200/test_index/_search -d &#39;{&quot;query&quot;: {&quot;match&quot;:{&quot;user_name&quot;: {&quot;query&quot;:&quot;test user1&quot;, &quot;minimum_should_match&quot;:1 }}}}&#39; | jq .hits.hits
[
  {
    &quot;_index&quot;: &quot;test_index&quot;,
    &quot;_type&quot;: &quot;test&quot;,
    &quot;_id&quot;: &quot;1&quot;,
    &quot;_score&quot;: 0.87546873,
    &quot;_source&quot;: {
      &quot;user_name&quot;: &quot;test user1&quot;
    }
  },
  {
    &quot;_index&quot;: &quot;test_index&quot;,
    &quot;_type&quot;: &quot;test&quot;,
    &quot;_id&quot;: &quot;2&quot;,
    &quot;_score&quot;: 0.18232156,
    &quot;_source&quot;: {
      &quot;user_name&quot;: &quot;test user2&quot;
    }
  }
]
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/2200325660057207718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/2200325660057207718'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2019/02/elasticsearchdsland.html' title='ElasticsearchのクエリDSLでand検索'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-872011400018156718</id><published>2019-01-27T06:06:00.001+09:00</published><updated>2019-01-27T06:07:35.422+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Jackson"/><title type='text'>Jacksonでsnake caseのキーをlower camel caseのプロパティーにデシリアライズする</title><content type='html'>&lt;h1&gt;環境&lt;/h1&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;
implementation &quot;com.fasterxml.jackson.core:jackson-databind:2.9.8&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;ObjectMapperの設定をする&lt;/h1&gt;ObjectMapperにPropertyNamingStrategyを設定します。&lt;br /&gt;
Jsonのキーの名前はsnake_caseなので、PropertyNamingStrategy.SNAKE_CASEを設定します。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;val objectMapper = jacksonObjectMapper().apply { 
    setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h1&gt;確認コード&lt;/h1&gt;動作確認用のコードです。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;fun main(args: Array&lt;string&gt;) {
    val objectMapper = jacksonObjectMapper().apply { 
        setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
    }
    
    val json = &quot;&quot;&quot;{
        |&quot;user_name&quot;: &quot;なまえ&quot;
        |}&quot;&quot;&quot;.trimMargin()

    val user = objectMapper.readValue&lt;user&gt;(json)
    println(&quot;user = ${user}&quot;)

    val string = objectMapper.writeValueAsString(user)
    println(&quot;string = ${string}&quot;)

}
data class User (val userName:String?)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h1&gt;実行結果&lt;/h1&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;user = User(userName=なまえ)
string = {&quot;user_name&quot;:&quot;なまえ&quot;}
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/872011400018156718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/872011400018156718'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2019/01/jacksonsnake-caselower-camel-case.html' title='Jacksonでsnake caseのキーをlower camel caseのプロパティーにデシリアライズする'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-5455669018106669039</id><published>2018-12-29T06:42:00.001+09:00</published><updated>2018-12-29T06:42:41.322+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="readlink"/><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu"/><title type='text'>Ubuntuのターミナルでファイルのフルパスを取得する方法</title><content type='html'>&lt;i&gt;readlink&lt;/i&gt;コマンドを使うとファイルのフルパスを取得できる。&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;例&lt;/h1&gt;取得したいファイルを、-fオプションに指定する。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;$ readlink -f hoge.txt 
/home/hoge/hoge.txt
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/5455669018106669039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/5455669018106669039'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/12/ubuntu.html' title='Ubuntuのターミナルでファイルのフルパスを取得する方法'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-2003998801518628536</id><published>2018-12-26T08:57:00.001+09:00</published><updated>2018-12-26T08:57:46.100+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="elasticsearch"/><title type='text'>Elasticsearchに格納しているデータの一部を書き換える方法</title><content type='html'>Elasticsearch内のデータの一部の書き換えは&lt;i&gt;Update API&lt;/i&gt;を使います。&lt;br /&gt;
ドキュメントは、&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html#_updates_with_a_partial_document&quot;&gt;Updates with a partial document&lt;/a&gt;あたりになります。&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;確認&lt;/h1&gt;書き換え対象のデータの内容です。hoge1とhoge2のキーを持っています。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;$ curl -s http://localhost:9200/test_index/hoge/1 | jq
{
  &quot;_index&quot;: &quot;test_index&quot;,
  &quot;_type&quot;: &quot;hoge&quot;,
  &quot;_id&quot;: &quot;1&quot;,
  &quot;_version&quot;: 3,
  &quot;found&quot;: true,
  &quot;_source&quot;: {
    &quot;hoge1&quot;: &quot;hoge1&quot;,
    &quot;hoge2&quot;: &quot;fuga2&quot;
  }
}

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;i&gt;Update API&lt;/i&gt;を叩いて、hoge1の値を変更してみます。&lt;br /&gt;
公式ドキュメントに従い、&lt;i&gt;POST&lt;/i&gt;で変更対象のidの&lt;i&gt;_update&lt;/i&gt;を叩きます。&lt;br /&gt;
body部には、jsonでdoc配下に変更したい内容を定義して送ります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ curl -XPOST -H &quot;Content-Type: application/json&quot; http://localhost:9200/test_index/hoge/1/_update -d &#39; 
{
  &quot;doc&quot;: {
    &quot;hoge1&quot;: &quot;mod-hoge1&quot;
  }
}
&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
書き換えたデータを取得すると、データの内容が変更されていることが確認できます。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;$ curl -s http://localhost:9200/test_index/hoge/1 | jq
{
  &quot;_index&quot;: &quot;test_index&quot;,
  &quot;_type&quot;: &quot;hoge&quot;,
  &quot;_id&quot;: &quot;1&quot;,
  &quot;_version&quot;: 4,
  &quot;found&quot;: true,
  &quot;_source&quot;: {
    &quot;hoge1&quot;: &quot;mod-hoge1&quot;,
    &quot;hoge2&quot;: &quot;fuga2&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/2003998801518628536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/2003998801518628536'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/12/elasticsearch.html' title='Elasticsearchに格納しているデータの一部を書き換える方法'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-2248011539057411135</id><published>2018-12-14T09:55:00.001+09:00</published><updated>2018-12-14T09:55:26.001+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker-compose"/><title type='text'>docker-compose内のservice一覧を表示する方法</title><content type='html'>&lt;i&gt;docker-compose config --services&lt;/i&gt;でサービス名の一覧を出力できる。</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/2248011539057411135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/2248011539057411135'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/12/docker-composeservice.html' title='docker-compose内のservice一覧を表示する方法'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-4064338518684345039</id><published>2018-10-02T06:44:00.000+09:00</published><updated>2018-10-02T06:44:29.444+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CSV"/><category scheme="http://www.blogger.com/atom/ns#" term="Go"/><title type='text'>GoでCSVファイルを読み込む</title><content type='html'>&lt;a href=&quot;https://golang.org/pkg/encoding/csv/&quot;&gt;Package csv&lt;/a&gt;を使ってCSVファイルを読み込む例になります。&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;読み込むCSVファイルを準備する&lt;/h3&gt;文字列は、「&quot;」で囲み要素内に「,」がある内容としてみました。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;txt&quot;&gt;&quot;name&quot;,&quot;age&quot;
&quot;hoge,fuga&quot;, 100
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;読み込んで見る&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;go&quot;&gt;package main

import (
 &quot;encoding/csv&quot;
 &quot;fmt&quot;
 &quot;io&quot;
 &quot;log&quot;
 &quot;os&quot;
)

func main() {

        // ファイルを開く
 file, err := os.Open(&quot;test.csv&quot;)
 if err != nil {
  log.Fatal(err)
 }

        // 開いたファイルの後始末
 defer file.Close()

        // CSVを読み込むためのReaderを生成
 reader := csv.NewReader(file)

 for {
                // 1行づつ読み込む
  record, err := reader.Read()
                // ファイルの末尾で処理終了
  if err == io.EOF {
   break
  }
  if err != nil {
   log.Fatal(err)
  }
  fmt.Println(record)
 }

}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;出力結果&lt;/h3&gt;クォートが削除されて読み込まれ、要素内の「,」も正しく読み込まれていることがわかります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;txt&quot;&gt;[name age]
[hoge,fuga  100]
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4064338518684345039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4064338518684345039'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/10/gocsv.html' title='GoでCSVファイルを読み込む'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-4139089483832721569</id><published>2018-09-11T14:35:00.000+09:00</published><updated>2018-09-14T09:22:02.128+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Spring Boot"/><title type='text'>spring-boot-maven-pluginのboot:runで起動引数を指定する</title><content type='html'>spring-boot-maven-pluginのboot:run時に起動引数を指定する方法です。&lt;br /&gt;
&lt;br /&gt;
起動引数は、システムプロパティの&lt;i&gt;spring-boot.run.arguments&lt;/i&gt;を使用して指定します。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;cmd&quot;&gt;mvn spring-boot:run -Dspring-boot.run.arguments=[引数]&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4139089483832721569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4139089483832721569'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/09/spring-boot-maven-pluginbootrun.html' title='spring-boot-maven-pluginのboot:runで起動引数を指定する'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-7058074432963410300</id><published>2018-09-06T11:55:00.000+09:00</published><updated>2018-09-06T11:55:17.161+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="assertj"/><category scheme="http://www.blogger.com/atom/ns#" term="JUnit5"/><title type='text'>[AssertJ]JUnit5拡張のsoft assertions</title><content type='html'>AssertJ 3.11.0から追加されたJUnit5拡張のsoft assertionsを試してみる。&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;AssertJを依存ライブラリに追加する&lt;/h3&gt;バージョンは、3.11.0以降を指定する必要があります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;groovy&quot;&gt;testCompile &#39;org.assertj:assertj-core:3.11.1&#39;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;soft assertionsを使ってみる&lt;/h3&gt;実装すればいいことは、以下の2点ですね。&lt;br /&gt;
&lt;i&gt;org.assertj.core.api.SoftAssertions.SoftAssertions&lt;/i&gt;のときは、assertAllを呼び出す必要があったけどそれが不要になりますね。&lt;br /&gt;
&lt;ul&gt;  &lt;li&gt;JUnitJupiterSoftAssertionsをフィールドに定義して@RegisterExtensionを設定する&lt;/li&gt;
  &lt;li&gt;JUnitJupiterSoftAssertionsのassertThatを使ってアサーションを行う&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;public class SampleTest {
    
    @RegisterExtension
    public final JUnitJupiterSoftAssertions softly = new JUnitJupiterSoftAssertions();

    @Test
    void test() {
        softly.assertThat(5)
              .isEqualTo(1);
        softly.assertThat(&quot;hoge&quot;)
              .isEqualTo(&quot;fuga&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;実行結果&lt;/h3&gt;複数箇所でアサーションに失敗した場合でも、それぞれの結果が表示されますね。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;Expected :1
Actual   :5
 &amp;lt;Click to see difference&amp;gt;

Expected :fuga
Actual   :hoge
 &amp;lt;Click to see difference&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7058074432963410300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7058074432963410300'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/09/assertjjunit5soft-assertions.html' title='[AssertJ]JUnit5拡張のsoft assertions'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-4867909706202630199</id><published>2018-08-11T08:08:00.001+09:00</published><updated>2018-08-11T11:26:40.004+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Jenkins"/><category scheme="http://www.blogger.com/atom/ns#" term="Pipeline Utility Steps"/><title type='text'>Jenkins Pipeline Utility Stepsを使ってpomの情報を読み取る</title><content type='html'>Pipeline Utility Stepsを使うことで、Jenkinsのpipeline上でpomの情報を簡単に読み取れるようです。&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;プラグインのインストール&lt;/h2&gt;Pipeline Utility Stepsプラグインをインストールします。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtSG7airZwzN3Mo3SFMCI_Ez6g170dpJckySGHIiIFtOhBapNO_y-TynoOeU8eB16O9cwn3uSQjVzmik_ynpj62UtM9o9dCo6ahF0NA8Y5j5KTF73GwkRSMphLQ4VTffk-U7sb1Do0NO6b/s1600/%25E7%25AF%2584%25E5%259B%25B2%25E3%2582%2592%25E9%2581%25B8%25E6%258A%259E_002.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;543&quot; data-original-width=&quot;1600&quot; height=&quot;109&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtSG7airZwzN3Mo3SFMCI_Ez6g170dpJckySGHIiIFtOhBapNO_y-TynoOeU8eB16O9cwn3uSQjVzmik_ynpj62UtM9o9dCo6ahF0NA8Y5j5KTF73GwkRSMphLQ4VTffk-U7sb1Do0NO6b/s320/%25E7%25AF%2584%25E5%259B%25B2%25E3%2582%2592%25E9%2581%25B8%25E6%258A%259E_002.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h2&gt;パイプラインでpomの情報を参照する&lt;/h2&gt;readMavenPomをパイプラインのscriptブロック内で使うことでpomの内容を参照できます。&lt;br /&gt;
参照（変更）できる内容は、&lt;a href=&quot;http://maven.apache.org/components/ref/3.3.9/maven-model/apidocs/org/apache/maven/model/Model.html&quot;&gt;こちら&lt;/a&gt;を参照&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;groovy&quot;&gt;stage(&#39;test&#39;) {
    steps {
        script {
            pom = readMavenPom file: &#39;pom.xml&#39;
            println(pom.version)
            pom.dependencies.each {
                println(it)
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;実行結果&lt;/h3&gt;上のパイプラインを実行するとバージョン番号とdependenciesの内容が出力されます。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;groovy&quot;&gt;[Pipeline] readMavenPom
[Pipeline] echo
1.0.0
[Pipeline] echo
Dependency {groupId=org.springframework.boot, artifactId=spring-boot-starter-data-jpa, version=null, type=jar}
[Pipeline] echo
Dependency {groupId=org.springframework.boot, artifactId=spring-boot-starter-thymeleaf, version=null, type=jar}
[Pipeline] echo
Dependency {groupId=org.springframework.boot, artifactId=spring-boot-starter-web, version=null, type=jar}
[Pipeline] echo
Dependency {groupId=org.springframework.boot, artifactId=spring-boot-starter-actuator, version=null, type=jar}
[Pipeline] echo
Dependency {groupId=org.postgresql, artifactId=postgresql, version=null, type=jar}
[Pipeline] echo
Dependency {groupId=org.springframework.boot, artifactId=spring-boot-starter-test, version=null, type=jar}
[Pipeline] }
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4867909706202630199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4867909706202630199'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/08/jenkins-pipeline-utility-stepspom.html' title='Jenkins Pipeline Utility Stepsを使ってpomの情報を読み取る'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtSG7airZwzN3Mo3SFMCI_Ez6g170dpJckySGHIiIFtOhBapNO_y-TynoOeU8eB16O9cwn3uSQjVzmik_ynpj62UtM9o9dCo6ahF0NA8Y5j5KTF73GwkRSMphLQ4VTffk-U7sb1Do0NO6b/s72-c/%25E7%25AF%2584%25E5%259B%25B2%25E3%2582%2592%25E9%2581%25B8%25E6%258A%259E_002.jpg" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-7612461428830316409</id><published>2018-07-15T21:13:00.000+09:00</published><updated>2018-07-15T21:13:04.834+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Concourse"/><category scheme="http://www.blogger.com/atom/ns#" term="Maven"/><title type='text'>Concourse CIで成果物をMavenリポジトリにアップする</title><content type='html'>Concourse CIの&lt;a href=&quot;https://github.com/nulldriver/maven-resource&quot;&gt;Maven Resource&lt;/a&gt;を使ってビルド成果物をMavenリポジトリにデプロイする方法です。&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;ジョブの構成&lt;/h3&gt;ジョブは、下の画像のようにアプリケーションをビルドしてnexusにデプロイする構成としています。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig-6KXxi6LUbkr7-knxe7gxQggxFj01CPJHxN1t4hF_ZLDkZvLNFmny-1zI7RvWkdhM2eCdLTeIrJSW_dDjXTprYi_4tAfgJZMGPBhBR-RXgS04VLQ6YRfNP9NMTl4P-yo6CCYEhBt07Nv/s1600/%25E7%25AF%2584%25E5%259B%25B2%25E3%2582%2592%25E9%2581%25B8%25E6%258A%259E_001.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;346&quot; data-original-width=&quot;1194&quot; height=&quot;93&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig-6KXxi6LUbkr7-knxe7gxQggxFj01CPJHxN1t4hF_ZLDkZvLNFmny-1zI7RvWkdhM2eCdLTeIrJSW_dDjXTprYi_4tAfgJZMGPBhBR-RXgS04VLQ6YRfNP9NMTl4P-yo6CCYEhBt07Nv/s320/%25E7%25AF%2584%25E5%259B%25B2%25E3%2582%2592%25E9%2581%25B8%25E6%258A%259E_001.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;ジョブ定義&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;resource_typesで、maven-resourceを定義します。&lt;/li&gt;
&lt;li&gt;resourcesは、resource_typesで定義したmaven-resourceの設定(urlや接続情報やartifactなど)を行います。&lt;/li&gt;
&lt;li&gt;jobのtask定義ではリポジトリにデプロイする対象をoutputsで定義します。&lt;/li&gt;
&lt;li&gt;put定義では、デプロイ対象の成果物（jarとpom)を定義します&lt;/li&gt;
&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;# maven-resourceの定義
resource_types:
- name: maven-resource
  type: docker-image
  source:
    repository: nulldriver/maven-resource
    tag: latest

resources:
- name: app
  type: git
  source:
    uri: http://gitbucket:8080/git/root/sample-app.git

# maven-resourceのリソース定義
# urlや接続情報などを設定します
- name: nexus
  type: maven-resource
  source:
    url: http://nexus:8081/repository/maven-releases/
    snapshot_url: http://nexus:8081/repository/maven-snapshots/
    artifact: sample:sample-app:jar
    username: admin
    password: admin123
jobs:
- name: build
  plan:
  - get: app
    trigger: true
  - task: build
    config:
      platform: linux
      image_resource:
        type: docker-image
        source:
          repository: maven
          tag: &#39;3.5.4-jdk-8&#39;
      inputs:
        - name: app
      # putでmavenリポジトリに成果物をデプロイできるようにするためのoutputsの定義
      outputs:
        - name: target
      run:
        path: bash
        args:
        - -c
        - |
          cd app
          mvn clean package -D maven.repo.local=/tmp/.m2/repository
          cp -r target ..
  # jarとpomを指定してリポジトリにデプロイします
  - put: nexus
    params:
      file: target/sample-app*.jar
      pom_file: app/pom.xml
      
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;ジョブの実行と結果の確認&lt;/h3&gt;ジョブを実行すると、下のようなログが出力されてリポジトリに成果物がアップされていることがわかります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;
[INFO] --- maven-deploy-plugin:2.7:deploy-file (default-cli) @ standalone-pom ---
Downloading: http://nexus:8081/repository/maven-snapshots/sample/sample-app/1.0.0-SNAPSHOT/maven-metadata.xml
Uploading: http://nexus:8081/repository/maven-snapshots/sample/sample-app/1.0.0-SNAPSHOT/sample-app-1.0.0-20180715.115944-1.jar
Uploaded: http://nexus:8081/repository/maven-snapshots/sample/sample-app/1.0.0-SNAPSHOT/sample-app-1.0.0-20180715.115944-1.jar (1.8 kB at 8.4 kB/s)
Uploading: http://nexus:8081/repository/maven-snapshots/sample/sample-app/1.0.0-SNAPSHOT/sample-app-1.0.0-20180715.115944-1.pom
Uploaded: http://nexus:8081/repository/maven-snapshots/sample/sample-app/1.0.0-SNAPSHOT/sample-app-1.0.0-20180715.115944-1.pom (403 B at 5.2 kB/s)
Downloading: http://nexus:8081/repository/maven-snapshots/sample/sample-app/maven-metadata.xml
Uploading: http://nexus:8081/repository/maven-snapshots/sample/sample-app/1.0.0-SNAPSHOT/maven-metadata.xml
Uploaded: http://nexus:8081/repository/maven-snapshots/sample/sample-app/1.0.0-SNAPSHOT/maven-metadata.xml (766 B at 9.9 kB/s)
Uploading: http://nexus:8081/repository/maven-snapshots/sample/sample-app/maven-metadata.xml
Uploaded: http://nexus:8081/repository/maven-snapshots/sample/sample-app/maven-metadata.xml (276 B at 4.1 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
nexusでも成果物がアップされていることが確認できます。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5CSBxBOAmBww7xW3mTHA6VSkunSHpETeVSNPV1IKVQ7FJFqKd1GA5rnXboNpzRVgwWpeUkl2w_k4hCPPq39HeAx1JBupbZ1HrsvJyhVBIG0AlHqeKbXpHGLnPVlkIj0O-Hi3SloMVTA18/s1600/%25E7%25AF%2584%25E5%259B%25B2%25E3%2582%2592%25E9%2581%25B8%25E6%258A%259E_003.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;413&quot; data-original-width=&quot;572&quot; height=&quot;231&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5CSBxBOAmBww7xW3mTHA6VSkunSHpETeVSNPV1IKVQ7FJFqKd1GA5rnXboNpzRVgwWpeUkl2w_k4hCPPq39HeAx1JBupbZ1HrsvJyhVBIG0AlHqeKbXpHGLnPVlkIj0O-Hi3SloMVTA18/s320/%25E7%25AF%2584%25E5%259B%25B2%25E3%2582%2592%25E9%2581%25B8%25E6%258A%259E_003.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7612461428830316409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7612461428830316409'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/07/concourse-cimaven.html' title='Concourse CIで成果物をMavenリポジトリにアップする'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig-6KXxi6LUbkr7-knxe7gxQggxFj01CPJHxN1t4hF_ZLDkZvLNFmny-1zI7RvWkdhM2eCdLTeIrJSW_dDjXTprYi_4tAfgJZMGPBhBR-RXgS04VLQ6YRfNP9NMTl4P-yo6CCYEhBt07Nv/s72-c/%25E7%25AF%2584%25E5%259B%25B2%25E3%2582%2592%25E9%2581%25B8%25E6%258A%259E_001.png" height="72" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-8515310667349089219</id><published>2018-07-15T06:39:00.000+09:00</published><updated>2018-07-15T06:39:35.314+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Maven"/><title type='text'>mvnコマンド実行時にローカルリポジトリの場所を指定する</title><content type='html'>mvnコマンド実行時にローカルリポジトリの場所を指定したい場合は&lt;b&gt;maven.repo.local&lt;/b&gt;システムプロパティを使用します。&lt;br /&gt;
&lt;br /&gt;
例えば、カレントディレクトリ配下にローカルリポジトリを置きたい場合、&lt;b&gt;mvn test -Dmaven.repo.local=./m2/repository&lt;/b&gt;のように指定します。&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;実行例&lt;/h1&gt;システムプロパティで指定した場所にローカルリポジトリが作られているのがわかります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;
$ ls .m2
ls: &#39;.m2&#39; にアクセスできません: そのようなファイルやディレクトリはありません

$ mvn package -Dmaven.repo.local=./.m2/repository
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------------&lt; sample:sample-app &gt;--------------------------
[INFO] Building sample-app 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
*************************************** 省略 ***************************************
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:25 min
[INFO] Finished at: 2018-07-15T06:37:10+09:00
[INFO] ------------------------------------------------------------------------

$ ls .m2
repository
&lt;/pre&gt;&lt;/code&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/8515310667349089219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/8515310667349089219'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/07/mvn.html' title='mvnコマンド実行時にローカルリポジトリの場所を指定する'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-7478886938347389070</id><published>2018-07-11T10:26:00.000+09:00</published><updated>2018-07-11T10:26:27.090+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Jackson"/><title type='text'>JacksonでイミュータブルなオブジェクトにJsonをマッピングする</title><content type='html'>&lt;i&gt;com.fasterxml.jackson.annotation.JsonCreator&lt;/i&gt;アノテーションを使うこと、コンストラクタかファクトリメソッドを使った構築ができる。&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;コンストラクタを使った場合&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;コンストラクタに&lt;i&gt;JsonCreator&lt;/i&gt;アノテーションを設定する。&lt;/li&gt;
&lt;li&gt;引数には、&lt;i&gt;JsonProperty&lt;/i&gt;アノテーションを設定し、Jsonのキー名を指定する。&lt;/li&gt;
&lt;/ul&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;public class Sample {

    public final String name;

    public final short age;

    @JsonCreator
    public Sample(
            @JsonProperty(&quot;name&quot;) final String name,
            @JsonProperty(&quot;age&quot;) final short age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return &quot;Sample{&quot; +
                &quot;name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &quot;, age=&quot; + age +
                &#39;}&#39;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;ファクトリメソッドを使った場合&lt;/h3&gt;ファクトリメソッドの場合には、コンストラクタに設定していたアノテーションをファクトリメソッドにそのまま持ってくれば良い。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;public class Sample {

    public final String name;

    public final short age;

    private Sample(final String name, final short age) {
        this.name = name;
        this.age = age;
    }

    @JsonCreator
    public static Sample create(
            @JsonProperty(&quot;name&quot;) final String name,
            @JsonProperty(&quot;age&quot;) final short age) {
        return new Sample(name, age);
    }

    @Override
    public String toString() {
        return &quot;Sample{&quot; +
                &quot;name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &quot;, age=&quot; + age +
                &#39;}&#39;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;動作結果&lt;/h3&gt;動作確認に使ったコード&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;final ObjectMapper objectMapper = new ObjectMapper();
final Sample sample = objectMapper.readValue(&quot;{\&quot;name\&quot;: \&quot;なまえ\&quot;, \&quot;age\&quot;: 100}&quot;, Sample.class);
System.out.println(&quot;sample = &quot; + sample);
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
標準出力の結果&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;sample = Sample{name=&#39;なまえ&#39;, age=100}&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7478886938347389070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7478886938347389070'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/07/jacksonjson.html' title='JacksonでイミュータブルなオブジェクトにJsonをマッピングする'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-555405666685059403</id><published>2018-06-10T20:53:00.001+09:00</published><updated>2018-06-10T20:53:09.647+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="zsh"/><title type='text'>zshのviモードでCtrl+Rでコマンドの履歴検索をできるようにする</title><content type='html'>これで&lt;b&gt;Ctrl+R&lt;/b&gt;でコマンドの履歴検索ができるようになる。&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;bindkey &#39;^R&#39; history-incremental-pattern-search-backward&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/555405666685059403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/555405666685059403'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/06/zshvictrlr.html' title='zshのviモードでCtrl+Rでコマンドの履歴検索をできるようにする'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-2766689106845904719</id><published>2018-05-28T13:20:00.003+09:00</published><updated>2018-06-01T10:13:08.379+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Spring Boot"/><category scheme="http://www.blogger.com/atom/ns#" term="Spring Boot 2.0.2.RELEASE"/><title type='text'>Spring MVCとThymeleafの組み合わせでcheckboxのデフォルト値を設定する</title><content type='html'>Spring MVCとThymeleafの組み合わせでcheckboxを使った場合の動きを理解する。&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;checkboxの値をBooleanで受け取る場合&lt;/h2&gt;&lt;h3&gt;Form&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;public class Form {

    private Boolean check;

    // ほかは省略
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;Controller&lt;/h3&gt;checkboxの値を確認できるように標準出力に値を出力するだけに&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;@PostMapping(&quot;hello&quot;)
public String hello(Form form) {
    System.out.println(&quot;form.check = &quot; + form.check);
    return &quot;input&quot;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;View&lt;/h3&gt;&lt;pre&gt;&lt;code class=&#39;html&#39;&gt;&amp;lt;form th:action=&amp;quot;@{/hello}&amp;quot; method=&amp;quot;post&amp;quot; th:object=&amp;quot;${form}&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; th:field=&amp;quot;*{check}&amp;quot; /&amp;gt;
  &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;submit&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;動かしてみた結果&lt;/h3&gt;出力されるhtmlには、checkboxとcheckboxに対応したhiddenが出力されます。このhiddenがあることでcheckboxがチェックされなかった場合でもFormに値が設定されます。(Booleanなのでfalseが設定される)&lt;br /&gt;
これは、thymeleafの&lt;i&gt;th:field&lt;/i&gt;で自動的に出力されます。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;html&#39;&gt;&amp;lt;form action=&amp;quot;/hello&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; id=&amp;quot;check1&amp;quot; name=&amp;quot;check&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_check&amp;quot; value=&amp;quot;on&amp;quot;/&amp;gt;
  &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;submit&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
checkboxをチェックしないで送信した時は標準出力に↓が出力されます。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;form.check = false&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
ちなみに、&lt;i&gt;th:field&lt;/i&gt;を使わないと下のようにhiddenが出力されないので、checkboxがチェックされなかった場合はFormには値が設定されないのでnullのままとなります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;html&#39;&gt;&amp;lt;form action=&amp;quot;/hello&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;checkbox&amp;quot; /&amp;gt;
  &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;submit&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;checkboxの値をBoolean以外で受け取る場合&lt;/h2&gt;単一のcheckboxの値をBooleanで受け取ることはないと思うけど、Stringで受け取った場合の動きを確認してみます。&lt;br /&gt;
&lt;br /&gt;
Stringの場合も、Booleanと同じように&lt;i&gt;th:field&lt;/i&gt;を使うと、↓が出力されます。だけど、Stringの場合は&lt;i&gt;th:field&lt;/i&gt;が出力するアンダースコア付きのhiddenに対応していないので、このままだと未チェック時はFormの値はnullのままになります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;html&#39;&gt;
&amp;lt;form action=&amp;quot;/hello&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; value=&amp;quot;on&amp;quot; id=&amp;quot;check1&amp;quot; name=&amp;quot;check&amp;quot;/&amp;gt;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_check&amp;quot; value=&amp;quot;on&amp;quot;/&amp;gt;
  &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;submit&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
未送信時に送信する値は、別途↓のようにhiddenで定義します。デフォルト設定だと、対応するcheckboxのnameの先頭に&lt;b&gt;&lt;i&gt;!&lt;/i&gt;&lt;/b&gt;をつけた名前でhiddenを定義する必要があります。&lt;br /&gt;
プレフィックスの値は&lt;a href=&quot;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/WebDataBinder.html&quot;&gt;WebDataBinderのJavadoc&lt;/a&gt;が参考になります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;html&#39;&gt;&amp;lt;form th:action=&amp;quot;@{/hello}&amp;quot; method=&amp;quot;post&amp;quot; th:object=&amp;quot;${form}&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; th:field=&amp;quot;*{check}&amp;quot; value=&amp;quot;on&amp;quot; /&amp;gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;!check&amp;quot; value=&amp;quot;off&amp;quot; /&amp;gt;
  &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;submit&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
これで、未チェック時にはhiddenで指定した値をFormで受け取れるようになります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;bash&#39;&gt;form.check = off&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/2766689106845904719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/2766689106845904719'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/05/spring-mvcthymeleafcheckbox.html' title='Spring MVCとThymeleafの組み合わせでcheckboxのデフォルト値を設定する'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-9156996728984493275</id><published>2018-05-02T07:45:00.001+09:00</published><updated>2018-05-02T07:45:22.497+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Spring"/><category scheme="http://www.blogger.com/atom/ns#" term="Spring Security"/><title type='text'>Spring Securityで認証後にかならず決まったページに遷移させる</title><content type='html'>&lt;i&gt;defaultSuccessurl&lt;/i&gt;の2番目の引数に&lt;i&gt;true&lt;/i&gt;を指定すると、ログイン成功後に必ず最初に指定したパスにリダイレクトされる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;@Override
protected void configure(final HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .formLogin()
        .defaultSuccessUrl(&quot;/index&quot;, true)
        .and()
        .logout()
        .invalidateHttpSession(true);
}&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/9156996728984493275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/9156996728984493275'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/05/spring-security.html' title='Spring Securityで認証後にかならず決まったページに遷移させる'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-7217804851756250883</id><published>2018-04-03T08:07:00.001+09:00</published><updated>2018-04-05T07:50:04.451+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Flyway"/><category scheme="http://www.blogger.com/atom/ns#" term="Spring Boot"/><title type='text'>Spring BootとFlywayでテーブルなどがあるスキーマに対してマイグレーションを実行する</title><content type='html'>application.propertiesに下を追加して、既存の状態をバージョン001とすることでマイグレーションが可能になる。&lt;br /&gt;
アプリ側のSQLファイルのバージョンは、V002__Create_hoge_table.sqlのようにベースバージョンより大きいバージョンにする。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;properties&quot;&gt;
spring.flyway.baseline-on-migrate=true
spring.flyway.baseline-version=001
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
なお、デフォルト状態だと&lt;b&gt;Found non-empty schema &quot;PUBLIC&quot; without metadata table!&lt;/b&gt;のエラーが出て実行できない。</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7217804851756250883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/7217804851756250883'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/04/spring-bootflyway.html' title='Spring BootとFlywayでテーブルなどがあるスキーマに対してマイグレーションを実行する'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-5555924624971017304</id><published>2018-03-25T08:11:00.000+09:00</published><updated>2018-03-25T08:11:13.655+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SQL Server"/><title type='text'>SQL Serverの計算列</title><content type='html'>SQL Serverでは、テーブル作成時にカラム名の後に&lt;b&gt;as&lt;/b&gt;で計算式を書くことで計算結果をそのカラムに自動的に設定できる。&lt;br /&gt;
この計算列は、計算結果が格納されるのでINSERTやUPDATEに含めることはできない。&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;テーブル定義&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;sql&quot;&gt;create table test
(
  id   int not null
    primary key,
  num1 int,
  num2 int,
  num3 as [num1] + [num2]
)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;insertの実行&lt;/h3&gt;計算列のnum3は含めずに登録を行う。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&#39;sql&#39;&gt;insert  into test (id, num1, num2) values (1, 1, 2)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;結果の確認&lt;/h3&gt;num3には、num1とnum2を元に計算した結果が格納されているのがわかる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;sql&quot;&gt;1&gt; select * from test
2&gt; go
id          num1        num2        num3       
----------- ----------- ----------- -----------
          1           1           2           3

(1 rows affected)
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/5555924624971017304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/5555924624971017304'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/03/sql-server.html' title='SQL Serverの計算列'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-8837712018167453171</id><published>2018-03-21T11:21:00.001+09:00</published><updated>2018-03-21T11:21:31.243+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="tomcat"/><category scheme="http://www.blogger.com/atom/ns#" term="tomcat9"/><title type='text'>Tomcatでポストサイズの上限を設定する</title><content type='html'>HTTP Connectorに&lt;a href=&quot;http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Common_Attributes&quot;&gt;maxPostSize&lt;/a&gt;を設定するとポストサイズの上限を設定できるようなので動きを確認してみた。&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;確認用Servlet&lt;/h3&gt;確認用のServletではpostされた内容を標準出力にだしています。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;kotlin&quot;&gt;override fun doPost(req: HttpServletRequest, resp: HttpServletResponse) {
    println(&quot;Content-Length: ${req.contentLengthLong}&quot;)
    println(&quot;parameter count: ${req.parameterMap.size}&quot;)
    req.parameterMap.forEach {
        println(&quot;${it.key}: ${it.value.joinToString(&quot;, &quot;)}&quot;)
    }
    doGet(req, resp)
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;デフォルト設定で実行&lt;/h3&gt;デフォルト設定だと上限が2MBとなるのでエラーなどは発生しないでうまく処理が行われる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;➜  ~ curl http://localhost:8080/sample/hello --data-urlencode &quot;param_key=値&quot; -X POST -i     
HTTP/1.1 200 
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
サーバの標準出力の内容&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;Content-Length: 19
parameter count: 1
param_key: 値
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;maxPoolSizeを指定して実行&lt;/h3&gt;conf/server.xmlのConnector部分にmaxPostSizeの設定を追加する。簡単に上限を超えるように設定値は1バイトに。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;xml&quot;&gt;&amp;lt;Connector port=&amp;quot;8080&amp;quot; protocol=&amp;quot;HTTP/1.1&amp;quot;
           connectionTimeout=&amp;quot;20000&amp;quot;
           maxPostSize=&amp;quot;1&amp;quot;
           redirectPort=&amp;quot;8443&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
デフォルトの設定だと、クライアントには200が返ってくる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;➜  ~ curl http://localhost:8080/sample/hello --data-urlencode &quot;param_key=値&quot; -X POST -i 
HTTP/1.1 200 
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
サーバのログを見ると、パラメータが存在しない状態でServletが呼び出されている。&lt;br /&gt;
このような場合、リクエストスコープの&lt;i&gt;org.apache.catalina.parameter_parse_failed_reason&lt;/i&gt;の値(org.apache.tomcat.util.http.Parameters.FailReason)を見ると何が起きたかがわかるらしい。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;Content-Length: 19
parameter count: 0
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;FailedRequestFilterを適用して実行&lt;/h3&gt;web.xmlにFailedRequestFilterを追加する。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;xml&quot;&gt;&amp;lt;filter&amp;gt;
  &amp;lt;filter-name&amp;gt;failedRequestFilter&amp;lt;/filter-name&amp;gt;
  &amp;lt;filter-class&amp;gt;org.apache.catalina.filters.FailedRequestFilter&amp;lt;/filter-class&amp;gt;
&amp;lt;/filter&amp;gt;

&amp;lt;filter-mapping&amp;gt;
  &amp;lt;filter-name&amp;gt;failedRequestFilter&amp;lt;/filter-name&amp;gt;
  &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Filterで指定サイズを超えた場合は処理を中断し、413 Request Entity Too Largeが返されるようになる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;➜  ~ curl http://localhost:8080/sample/hello --data-urlencode &quot;param_key=値&quot; -X POST -i 
HTTP/1.1 413 
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ちなみにこのフィルターは&lt;i&gt;application/x-www-form-urlencoded&lt;/i&gt;以外には影響を与えないようです。例えば、application/jsonの場合には下のように正常に処理が終わります。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;➜  ~ curl http://localhost:8080/sample/hello -H &quot;Content-Type: application/json&quot; -d &quot;{}&quot;  -i   
HTTP/1.1 200 
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/8837712018167453171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/8837712018167453171'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/03/tomcat.html' title='Tomcatでポストサイズの上限を設定する'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-6200563377114783642</id><published>2018-03-06T08:28:00.000+09:00</published><updated>2018-03-06T08:28:55.961+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Maven"/><title type='text'>Versions Maven Pluginを使ってparentのバージョンを変更する</title><content type='html'>&lt;pre&gt;&lt;code class=&quot;sh&quot;&gt;org.codehaus.mojo:versions-maven-plugin:2.5:update-parent&lt;/code&gt;&lt;/pre&gt;で参照可能な最新バージョンに変更できる。&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;parentVersion&lt;/i&gt;を使用して、バージョン番号の範囲を指定できる。&lt;br /&gt;
&lt;br /&gt;
例えば、下のように1.0.0か1.1.0のように指定する。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;sh&quot;&gt;org.codehaus.mojo:versions-maven-plugin:2.5:update-parent -DparentVersion=[1.0.0,1.1.0]&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/6200563377114783642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/6200563377114783642'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/03/versions-maven-pluginparent.html' title='Versions Maven Pluginを使ってparentのバージョンを変更する'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-4915482337687812634</id><published>2018-01-31T09:46:00.000+09:00</published><updated>2018-01-31T09:46:16.598+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Maven"/><title type='text'>Versions Maven Pluginを使ってバージョン番号からSNAPSHOTを削除する</title><content type='html'>setゴール実行時に&lt;i&gt;removeSnapshot&lt;/i&gt;にtrueを指定することで、SNAPSHOTが削除できる。&lt;br /&gt;
「1.0.0-SNAPSHOT」の場合は、「1.0.0」になる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;cmd&quot;&gt;mvn org.codehaus.mojo:versions-maven-plugin:2.5:set -DremoveSnapshot=true
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4915482337687812634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4915482337687812634'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/01/versions-maven-pluginsnapshot.html' title='Versions Maven Pluginを使ってバージョン番号からSNAPSHOTを削除する'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2489048893687165335.post-4514363094390941321</id><published>2018-01-30T08:37:00.000+09:00</published><updated>2018-01-30T08:37:55.815+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Maven"/><title type='text'>Apache Maven Clean Pluginを使ってデフォルト以外のファイルを削除する</title><content type='html'>Apache Maven Clean Pluginでは、&lt;i&gt;project.build.directory&lt;/i&gt;などを自動的にクリーニングしてくれるけど、それ以外のファイルをクリーニングしたい場合がある。&lt;br /&gt;
その場合は、下のようにconfigurationにfilesetesを指定する。&lt;br /&gt;
&lt;br /&gt;
この例では、「プロジェクトディレクトリ/temp」配下の「*.log」がクリーニング対象になる。&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;xml&quot;&gt;&amp;lt;plugin&amp;gt;
  &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;maven-clean-plugin&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;3.0.0&amp;lt;/version&amp;gt;
  &amp;lt;configuration&amp;gt;
    &amp;lt;filesets&amp;gt;
      &amp;lt;fileset&amp;gt;
        &amp;lt;directory&amp;gt;temp&amp;lt;/directory&amp;gt;
        &amp;lt;includes&amp;gt;
          &amp;lt;include&amp;gt;*.log&amp;lt;/include&amp;gt;
        &amp;lt;/includes&amp;gt;
      &amp;lt;/fileset&amp;gt;
    &amp;lt;/filesets&amp;gt;
  &amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4514363094390941321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2489048893687165335/posts/default/4514363094390941321'/><link rel='alternate' type='text/html' href='http://se-bikou.blogspot.com/2018/01/apache-maven-clean-plugin.html' title='Apache Maven Clean Pluginを使ってデフォルト以外のファイルを削除する'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>