<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Java アーカイブ - Sheltie Garage Tech</title>
	<atom:link href="https://sheltie-garage.xyz/tech/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>https://sheltie-garage.xyz/tech/category/java/</link>
	<description>テクノロジー関連の話題をまとめたブログです</description>
	<lastBuildDate>Tue, 04 Aug 2026 08:35:15 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>
	<item>
		<title>Java思い出し会：SpringBootを利用したシンプルなWebアプリケーション</title>
		<link>https://sheltie-garage.xyz/tech/2026/07/java%e6%80%9d%e3%81%84%e5%87%ba%e3%81%97%e4%bc%9a%ef%bc%9aspringboot%e3%82%92%e5%88%a9%e7%94%a8%e3%81%97%e3%81%9f%e3%82%b7%e3%83%b3%e3%83%97%e3%83%ab%e3%81%aaweb%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1/</link>
					<comments>https://sheltie-garage.xyz/tech/2026/07/java%e6%80%9d%e3%81%84%e5%87%ba%e3%81%97%e4%bc%9a%ef%bc%9aspringboot%e3%82%92%e5%88%a9%e7%94%a8%e3%81%97%e3%81%9f%e3%82%b7%e3%83%b3%e3%83%97%e3%83%ab%e3%81%aaweb%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1/#respond</comments>
		
		<dc:creator><![CDATA[monodon]]></dc:creator>
		<pubDate>Fri, 24 Jul 2026 11:06:02 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://sheltie-garage.xyz/tech/?p=1984</guid>

					<description><![CDATA[<p>リポジトリ リポジトリはこちらhttps://github.com/sheltie-fusafusa/SpringBootPractice 作ったアプリについて 「自分のバイクを登録できるだけ」のWebアプリですバイクの [&#8230;]</p>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2026/07/java%e6%80%9d%e3%81%84%e5%87%ba%e3%81%97%e4%bc%9a%ef%bc%9aspringboot%e3%82%92%e5%88%a9%e7%94%a8%e3%81%97%e3%81%9f%e3%82%b7%e3%83%b3%e3%83%97%e3%83%ab%e3%81%aaweb%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1/">Java思い出し会：SpringBootを利用したシンプルなWebアプリケーション</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">リポジトリ</h2>



<p class="wp-block-paragraph">リポジトリはこちら<br><a href="https://github.com/sheltie-fusafusa/SpringBootPractice" target="_blank" rel="noreferrer noopener">https://github.com/sheltie-fusafusa/SpringBootPractice</a></p>



<h2 class="wp-block-heading">作ったアプリについて</h2>



<p class="wp-block-paragraph">「自分のバイクを登録できるだけ」のWebアプリです<br>バイクの(名前のみ)登録と、登録したバイクの一覧が表示されます</p>



<p class="wp-block-paragraph">Thymeleafを利用したHTMLを返却するタイプと、REST APIでデータを返却するパターンを作成</p>



<h2 class="wp-block-heading">Spring Initializr</h2>



<p class="wp-block-paragraph">今回はIntellij IDEAを利用します<br>Intellij IDEAにはSpring Initializrが付属しているので、この機能を利用してプロジェクトを作成しました</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="913" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_001-1024x913.png" alt="" class="wp-image-1985" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_001-1024x913.png 1024w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_001-300x268.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_001-768x685.png 768w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_001-1536x1370.png 1536w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_001.png 1848w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="917" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_002-1024x917.png" alt="" class="wp-image-1986" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_002-1024x917.png 1024w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_002-300x269.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_002-768x688.png 768w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_002-1536x1376.png 1536w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_002.png 1826w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">以上のような依存関係でプロジェクトを作成しました<br>今回は単純な思い出し会なので、DBは手軽に使えるH2(インメモリ)で使用しています</p>



<p class="wp-block-paragraph">ORマッパーはMyBatisを利用しようと思ったのですが、Spring Initializrには適合するバージョンがありませんでした<br>ということで、MyBatisは `build.gradle`に直接手を加えて導入しています</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>dependencies {
    implementation &#39;org.mybatis.spring.boot:mybatis-spring-boot-starter:4.0.1&#39; ←追加
　　　以降、自動生成から変更無し</code></pre></div>



<p class="wp-block-paragraph">変更後は、以下のボタンからプロジェクトをリフレッシュできます<br>build.gradleを開いていれば右側にアイコンが表示されます</p>



<figure class="wp-block-image size-full"><img decoding="async" width="648" height="372" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_004.png" alt="" class="wp-image-1987" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_004.png 648w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260723_004-300x172.png 300w" sizes="(max-width: 648px) 100vw, 648px" /></figure>



<h2 class="wp-block-heading">思い出しポイント1:MyBatisを利用したDB接続</h2>



<p class="wp-block-paragraph">データベースの接続は以下の方法で設定<br>resources/application.propertiesに設定しました</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>spring.application.name=SimpleBikeMaintenanceDemo

# H2データベースの設定
spring.datasource.url=jdbc:h2:mem:bikedb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=


# H2コンソール
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

#MyBatis設定
mybatis.mapper-locations=classpath:mapper/*.xml</code></pre></div>



<p class="wp-block-paragraph">H2コンソールを指定しておけば、ブラウザから手軽にデータを確認することができます</p>



<p class="wp-block-paragraph">次にschema.sqlと、初期データのdata.sqlを作ります<br>resources/schema.sql</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>CREATE TABLE IF NOT EXISTS bikes (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);</code></pre></div>



<p class="wp-block-paragraph">resources/data.sql</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>INSERT INTO bikes (name) VALUES (&#39;Bimota Tesi 3D&#39;);</code></pre></div>



<p class="wp-block-paragraph">resource配下にschema.sqlとdata.sqlを作成しておけば、アプリ起動時に自動で実行してくれるとのこと！<br>ただ、「起動時に毎回実行される」ので注意！<br>今回はインメモリで利用しているため、アプリ終了→メモリ内のDBの消去　の流れなので毎回実行されても問題ないけど<br>将来的にMySQLなどの永続性のあるDBに変更した場合、毎回実行されるのでゴミデータができたり一意制約エラーになる可能性がある</p>



<p class="wp-block-paragraph">resource配下にmapperを作成して、具体的なSQL情報を記述<br>resources/mapper/BikeMapper.xml</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE mapper
        PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;
&lt;mapper namespace=&quot;xyz.sheltie_garage.simplebikemaintenancedemo.mapper.BikeMapper&quot;&gt;

    &lt;insert id=&quot;insert&quot; parameterType=&quot;xyz.sheltie_garage.simplebikemaintenancedemo.entity.Bike&quot;&gt;
        INSERT INTO bikes (name) VALUES (#{name})
    &lt;/insert&gt;

    &lt;select id=&quot;selectAll&quot; resultType=&quot;xyz.sheltie_garage.simplebikemaintenancedemo.entity.Bike&quot;&gt;
        SELECT id, name, created_at AS createdAt FROM bikes
    &lt;/select&gt;

&lt;/mapper&gt;</code></pre></div>



<p class="wp-block-paragraph">昔Javaで開発しているときにありがちだったのは、namespaceや〇〇Typeを指定するときのパスが間違えていて、うまくデータが取れなかったりということが多かった<br>この辺りは気を付けて指定したいところです</p>



<p class="wp-block-paragraph">ということで、マッパーとエンティティは以下に作成しました</p>



<p class="wp-block-paragraph">java/xyz/sheltie_garage/simplebikemaintenancedemo/mapper/BikeMapper.java</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>package xyz.sheltie_garage.simplebikemaintenancedemo.mapper;

import org.apache.ibatis.annotations.Mapper;
import xyz.sheltie_garage.simplebikemaintenancedemo.entity.Bike;

import java.util.List;

@Mapper
public interface BikeMapper {
    void insert(Bike bike);
    List&lt;Bike&gt; selectAll();
}
</code></pre></div>



<p class="wp-block-paragraph">java/xyz/sheltie_garage/simplebikemaintenancedemo/entity/Bike.java</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>package xyz.sheltie_garage.simplebikemaintenancedemo.entity;

import java.time.LocalDateTime;

public class Bike {
    private Long id;
    private String name;
    private LocalDateTime createdAt;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalDateTime getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }
}
</code></pre></div>



<p class="wp-block-paragraph">エンティティはシンプルにメンバ変数とgetter / setterで構成されてます<br>Lambokを導入すれば、この辺りのボイラープレートコードを自動生成できますね<br>(Intellii IDEAではGetter / Setter生成機能があるので、Lambokが無くてもそこまで手間ではない)</p>



<h2 class="wp-block-heading">ビジネスロジック(Serviceクラス)を作る</h2>



<p class="wp-block-paragraph">ビジネスロジックはServiceクラスに作成しました<br>今回はデータの登録、データ取得しかありません<br>java/xyz/sheltie_garage/simplebikemaintenancedemo/service/BikeService.java</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>package xyz.sheltie_garage.simplebikemaintenancedemo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xyz.sheltie_garage.simplebikemaintenancedemo.entity.Bike;
import xyz.sheltie_garage.simplebikemaintenancedemo.mapper.BikeMapper;

import java.util.List;

@Service
public class BikeService {

    private final BikeMapper bikeMapper;

    @Autowired
    public BikeService(BikeMapper bikeMapper) {
        this.bikeMapper = bikeMapper;
    }

    public void registerBike(String name){
        Bike bike = new Bike();
        bike.setName(name);
        bikeMapper.insert(bike);
    }

    public List&lt;Bike&gt; getAllBikes(){
        return bikeMapper.selectAll();
    }
}</code></pre></div>



<p class="wp-block-paragraph">@Serviceや@Autowiredなどのアノテーションを指定しています(あったあった！　懐かしい・・・)</p>



<p class="wp-block-paragraph">適切なアノテーションを付与することでコードの可読性が上がると同時に、Spring側で正しく情報が管理され、Autowired指定時に適切なクラスを自動設定することができます</p>



<p class="wp-block-paragraph">なので、アノテーションの付与を忘れたりすると、@Autowiredで適切なクラスが設定されません</p>



<p class="wp-block-paragraph">ちなみに、昔はおまじないだと思っていた@Autowiredアノテーションですが、役割としては「必要とされる部品を、適切にインスタンス化して設定してくれる」アノテーションです</p>



<h2 class="wp-block-heading">コントローラー作成</h2>



<p class="wp-block-paragraph">ビジネスロジックをServiceクラスに記述したことで、<br>・レスポンスとしてHTML(Thymeleaf)を返却するコントローラ<br>・REST API(JSON)を返却するコントローラ<br>の両方の処理が1つのビジネスロジックで対応できます</p>



<p class="wp-block-paragraph">まずはThymeleafを利用するコントローラ<br>java/xyz/sheltie_garage/simplebikemaintenancedemo/controller/BikeController.java</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>package xyz.sheltie_garage.simplebikemaintenancedemo.controller;

import org.springframework.ui.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import xyz.sheltie_garage.simplebikemaintenancedemo.service.BikeService;

@Controller
public class BikeViewController {

    private final BikeService bikeService;

    @Autowired
    public BikeViewController(BikeService bikeService) {
        this.bikeService = bikeService;
    }

    @GetMapping(&quot;/bikes&quot;)
    public String listBikes(Model model){
        model.addAttribute(&quot;bikes&quot;, bikeService.getAllBikes());
        return &quot;bikes/list&quot;; // templates/bikes/list.htmlを返却
    }

    @PostMapping(&quot;/bikes&quot;)
    public String registerBike(@RequestParam String name){
        bikeService.registerBike(name);
        return &quot;redirect:/bikes&quot;;  // 登録後はリダイレクト処理
    }
}
</code></pre></div>



<p class="wp-block-paragraph">@PostMapping, @GetMappingでそれぞれURLのパスを指定<br>returnで返却するのはThymeleafのパス(ファイル)で、templateディレクトリ配下に配置したテンプレートを指定します</p>



<p class="wp-block-paragraph">テンプレートは以下になります<br>resources/templates/bikes/list.html</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot; xmlns:th=&quot;http://www.thymeleaf.org&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;バイク一覧&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;バイク管理&lt;/h1&gt;

&lt;form method=&quot;post&quot; th:action=&quot;@{/bikes}&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;name&quot; placeholder=&quot;バイク名&quot; required&gt;
    &lt;button type=&quot;submit&quot;&gt;登録&lt;/button&gt;
&lt;/form&gt;

&lt;table border=&quot;1&quot;&gt;
    &lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;ID&lt;/th&gt;
        &lt;th&gt;名前&lt;/th&gt;
        &lt;th&gt;登録日時&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;tr th:each=&quot;bike : ${bikes}&quot;&gt;
        &lt;td th:text=&quot;${bike.id}&quot;&gt;&lt;/td&gt;
        &lt;td th:text=&quot;${bike.name}&quot;&gt;&lt;/td&gt;
        &lt;td th:text=&quot;${bike.createdAt}&quot;&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></div>



<p class="wp-block-paragraph">th:から始まる部分がThymeleafのタグです<br>このタグを利用してBeanのデータを表示したり、actionのURLを設定したりしています</p>



<p class="wp-block-paragraph">PostMappingではテンプレートを返却せず、「&#8221;redirect:/bikes&#8221;;」を指定することで一覧画面にリダイレクトし、二重登録を防ぎます<br>(<strong>PRGパターン</strong>（Post-Redirect-Get）という書き方)</p>



<h2 class="wp-block-heading">REST Controller</h2>



<p class="wp-block-paragraph">次はREST APIでの使用を想定したコントローラになります<br>java/xyz/sheltie_garage/simplebikemaintenancedemo/controller/BikeRestController.java</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>package xyz.sheltie_garage.simplebikemaintenancedemo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import xyz.sheltie_garage.simplebikemaintenancedemo.entity.Bike;
import xyz.sheltie_garage.simplebikemaintenancedemo.service.BikeService;

import java.util.List;

@RestController
@RequestMapping(&quot;/api/bikes&quot;)
public class BikeRestController {
    private final BikeService bikeService;

    @Autowired
    public BikeRestController(BikeService bikeService){
        this.bikeService = bikeService;
    }

    // 一覧取得
    @GetMapping
    public List&lt;Bike&gt; getAllBikes(){
        return bikeService.getAllBikes();
    }

    @PostMapping
    public String registerBike(@RequestParam String name){
        bikeService.registerBike(name);
        return &quot;登録しました:&quot; + name;
    }
}
</code></pre></div>



<p class="wp-block-paragraph">アノテーションは@RestControllerを利用<br>@RequestMapping(&#8220;/api/bikes&#8221;)を指定することで、GETメソッドでアクセスすればリスト取得が、POSTメソッドでアクセス(データを送信)すればデータ登録が行われます</p>



<p class="wp-block-paragraph">POSTメソッドに送信するデータのサンプルは以下になります</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>curl -X POST &quot;http://localhost:8080/api/bikes&quot; -d &quot;name=Kawasaki Ninja&quot;</code></pre></div>



<p class="wp-block-paragraph">以上で簡単なWebアプリ作成は完了です<br>プロジェクト全体はGitHubへアップしていますので、参考にしてください</p>



<h2 class="wp-block-heading">おまけ</h2>



<p class="wp-block-paragraph">h2-consoleを利用したデータ作成方法をメモしてきます</p>



<p class="wp-block-paragraph">まず、WebコンソールにアクセスするためのURLは以下の通り</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>http://localhost:8080/h2-console</code></pre></div>



<p class="wp-block-paragraph">以下の設定で接続できます</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>項目	入力する値
Driver Class	org.h2.Driver
JDBC URL	jdbc:h2:mem:bikedb
User Name	sa
Password	（空欄のまま）</code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="460" height="367" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260724_001.png" alt="" class="wp-image-1988" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260724_001.png 460w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260724_001-300x239.png 300w" sizes="auto, (max-width: 460px) 100vw, 460px" /></figure>



<p class="wp-block-paragraph">後はSQLを記述して実行すればデータが確認できます</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="847" height="391" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260724_002.png" alt="" class="wp-image-1989" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260724_002.png 847w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260724_002-300x138.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2026/07/20260724_002-768x355.png 768w" sizes="auto, (max-width: 847px) 100vw, 847px" /></figure>



<h2 class="wp-block-heading">以上</h2>



<p class="wp-block-paragraph">ということで、Java思い出し会でした<br>そろそろ就職先をと思って色々探し始めると、やっぱりJavaはまだまだ現役ということで思い出しておく必要があるなと痛感しました<br>Java自体、経験歴は長いのですが、同じシステムにずっと関わってた関係で知識が固定化してしまっています<br>無職という良い機会なので、Javaの知識も復習しておこうと思います</p>


<div id="rinkerid1993" class="yyi-rinker-contents  yyi-rinker-postid-1993 yyi-rinker-img-m yyi-rinker-catid-11 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJava%2Bspring%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img loading="lazy" decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/rakutenkobo-ebooks/cabinet/0633/2000004500633.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;"></a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJava%2Bspring%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発 【電子書籍】[ 株式会社NTTデータ ]</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥4,400</span>
															<span class="price_at">(2026/10/18 07:37:38時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=Java+spring&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJava%2Bspring%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3DJava%2Bspring" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>


<div id="rinkerid1995" class="yyi-rinker-contents  yyi-rinker-postid-1995 yyi-rinker-img-m yyi-rinker-catid-11 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fintellij%2Bidea%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img loading="lazy" decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/3830/9784774193830.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;"></a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fintellij%2Bidea%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">IntelliJ　IDEAハンズオン 基本操作からプロジェクト管理までマスター [ 山本裕介 ]</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥2,948</span>
															<span class="price_at">(2026/10/18 07:37:38時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=intellij+idea&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fintellij%2Bidea%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3Dintellij%2Bidea" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2026/07/java%e6%80%9d%e3%81%84%e5%87%ba%e3%81%97%e4%bc%9a%ef%bc%9aspringboot%e3%82%92%e5%88%a9%e7%94%a8%e3%81%97%e3%81%9f%e3%82%b7%e3%83%b3%e3%83%97%e3%83%ab%e3%81%aaweb%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1/">Java思い出し会：SpringBootを利用したシンプルなWebアプリケーション</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sheltie-garage.xyz/tech/2026/07/java%e6%80%9d%e3%81%84%e5%87%ba%e3%81%97%e4%bc%9a%ef%bc%9aspringboot%e3%82%92%e5%88%a9%e7%94%a8%e3%81%97%e3%81%9f%e3%82%b7%e3%83%b3%e3%83%97%e3%83%ab%e3%81%aaweb%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Javaで独自のToStringメソッドを作ってみる</title>
		<link>https://sheltie-garage.xyz/tech/2022/12/java%e3%81%a7%e7%8b%ac%e8%87%aa%e3%81%aetostring%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/</link>
					<comments>https://sheltie-garage.xyz/tech/2022/12/java%e3%81%a7%e7%8b%ac%e8%87%aa%e3%81%aetostring%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/#respond</comments>
		
		<dc:creator><![CDATA[monodon]]></dc:creator>
		<pubDate>Wed, 30 Nov 2022 21:47:24 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://sheltie-garage.xyz/tech/?p=502</guid>

					<description><![CDATA[<p>JavaのClassオブジェクトを利用して、private宣言されたメンバー変数の値を列挙するメソッドを作ります。lombokの@ToStringアノテーションのようなイメージです なぜすでにあるものを作るのか？ lom [&#8230;]</p>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2022/12/java%e3%81%a7%e7%8b%ac%e8%87%aa%e3%81%aetostring%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/">Javaで独自のToStringメソッドを作ってみる</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">JavaのClassオブジェクトを利用して、private宣言されたメンバー変数の値を列挙するメソッドを作ります。<br><a href="https://projectlombok.org/features/ToString" target="_blank" rel="noreferrer noopener">lombokの@ToString</a>アノテーションのようなイメージです</p>



<h3 class="wp-block-heading">なぜすでにあるものを作るのか？</h3>



<p class="wp-block-paragraph">lombokで準備されているならlombok使えばいいじゃない？となりますが、自作する理由はいかになります<br>・今従事しているプロジェクトで、ライブラリの導入がめんどくさそう(管理面で)<br>・純粋にJava勉強のため</p>



<p class="wp-block-paragraph">lombokが利用できるなら、lombokを利用するのが良いと思います</p>



<h2 class="wp-block-heading">実現方法</h2>



<p class="wp-block-paragraph">具体的なソースは<a href="https://github.com/sheltie-fusafusa/myToString" target="_blank" rel="noreferrer noopener">GitHub</a>を参照してください<br>以降はポイントになる点を記載します</p>



<h2 class="wp-block-heading">プログラム全文</h2>



<div class="hcb_wrap"><pre class="prism line-numbers lang-java" data-lang="java"><code>package org.example;

import java.lang.reflect.Field;
import java.util.Optional;

public class Util {

    public static String myToString(Object obj) {

        StringBuilder sb = new StringBuilder();
        try {
            StringBuilder innerSb = new StringBuilder();
            for(Field a : obj.getClass().getDeclaredFields()){　・・・①
                Field field = obj.getClass().getDeclaredField(a.getName());
                field.setAccessible(true);　・・・②

                innerSb.append(a.getName()).append(&quot; = &quot;).append(field.get(obj)).append(&quot;,&quot;);　・・・③
            }

            String str = Optional.ofNullable(innerSb.toString())
                    .filter(s -&gt; s.length() != 0)
                    .map(s -&gt; s.substring(0, s.length() - 1))
                    .orElse(&quot;&quot;);　・・・④

            sb.append(obj.getClass().getName()).append(&quot;(&quot;);
            sb.append(str);
            sb.append(&quot;)&quot;);
        } catch(Exception e) {
            System.out.println(e.getMessage());
        }

        return sb.toString();
    }
}</code></pre></div>



<p class="wp-block-paragraph">①・・・Classオブジェクトの「getDeclaredFields」を利用してメンバー変数名一覧を取得しループします<br>②・・・「field.setAccessible(true)」でprivateメソッドにアクセスできるように設定します<br>③・・・「field.get(obj)」を利用して変数の値を出力します<br>④・・・ログ出力時に付与される余計なカンマを削除する処理です。他ライブラリに依存するのが何となく嫌だったので、このような処理になっています</p>



<p class="wp-block-paragraph">変数の中身を列挙したいオブジェクトをこの変数に引数として渡してやれば、変数を列挙した文字列を返却します。</p>



<h2 class="wp-block-heading">以上</h2>



<p class="wp-block-paragraph">自家製のToString処理の紹介でした。このメソッドの利点はJava標準ライブラリのみ利用しているので導入が簡単な点でしょうか？</p>



<p class="wp-block-paragraph">Javaは長年使ってきたと思っていましたが、まだまだ知らないことも多く新しい発見がある言語です。<br>リリースサイクルも早まっていますので、進化についていけるかちょっと心配ですね・・・</p>


<div id="rinkerid504" class="yyi-rinker-contents  yyi-rinker-postid-504 yyi-rinker-img-m yyi-rinker-catid-11 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Feffective%2Bjava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/3252/9784621303252.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;" loading="lazy"></a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Feffective%2Bjava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">Effective Java [ Joshua Bloch ]</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥4,400</span>
															<span class="price_at">(2026/10/18 07:37:38時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=effective+java&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Feffective%2Bjava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3Deffective%2Bjava" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>


<div id="rinkerid505" class="yyi-rinker-contents  yyi-rinker-postid-505 yyi-rinker-img-m yyi-rinker-catid-11 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fjava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/7807/9784295007807.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;" loading="lazy"></a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fjava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">スッキリわかるJava入門第3版 [ 中山清喬 ]</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥2,860</span>
															<span class="price_at">(2026/10/18 07:37:38時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=java&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fjava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3Djava" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2022/12/java%e3%81%a7%e7%8b%ac%e8%87%aa%e3%81%aetostring%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/">Javaで独自のToStringメソッドを作ってみる</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sheltie-garage.xyz/tech/2022/12/java%e3%81%a7%e7%8b%ac%e8%87%aa%e3%81%aetostring%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>JUnitとMockitoでユニットテストの練習</title>
		<link>https://sheltie-garage.xyz/tech/2022/07/junit%e3%81%a8mockito%e3%81%a7%e3%83%a6%e3%83%8b%e3%83%83%e3%83%88%e3%83%86%e3%82%b9%e3%83%88%e3%81%ae%e7%b7%b4%e7%bf%92/</link>
					<comments>https://sheltie-garage.xyz/tech/2022/07/junit%e3%81%a8mockito%e3%81%a7%e3%83%a6%e3%83%8b%e3%83%83%e3%83%88%e3%83%86%e3%82%b9%e3%83%88%e3%81%ae%e7%b7%b4%e7%bf%92/#respond</comments>
		
		<dc:creator><![CDATA[monodon]]></dc:creator>
		<pubDate>Sun, 24 Jul 2022 04:14:30 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://sheltie-garage.xyz/tech/?p=172</guid>

					<description><![CDATA[<p>新しい会社ではきちんとユニットテストを書く文化があったので、練習のためMockitoの利用方法を練習していました。今まで経験した会社ではユニットテストを作る文化がなかったので、仕事でかなり単体テスト作成に手間取っています [&#8230;]</p>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2022/07/junit%e3%81%a8mockito%e3%81%a7%e3%83%a6%e3%83%8b%e3%83%83%e3%83%88%e3%83%86%e3%82%b9%e3%83%88%e3%81%ae%e7%b7%b4%e7%bf%92/">JUnitとMockitoでユニットテストの練習</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">新しい会社ではきちんとユニットテストを書く文化があったので、練習のためMockitoの利用方法を練習していました。<br>今まで経験した会社ではユニットテストを作る文化がなかったので、仕事でかなり単体テスト作成に手間取っています。<br>少しでもこの遅れを取り戻したい！ということもあり、Mockitoの練習をしてみました</p>



<h2 class="wp-block-heading">今回のプログラム</h2>



<p class="wp-block-paragraph">今回のサンプルプログラムは以下になります<br><a href="https://github.com/sheltie-fusafusa/JUnitMockitoPractice" target="_blank" rel="noreferrer noopener">https://github.com/sheltie-fusafusa/JUnitMockitoPractice</a></p>



<p class="wp-block-paragraph">この記事では、上記プログラム内で個人的に詰まった部分を抜粋して紹介します</p>



<h2 class="wp-block-heading">そもそもMockitoとは？</h2>



<p class="wp-block-paragraph">今回始めてMockitoに触ったのですが、そもそもこれが何なのか？何のために必要なのか？もわからない状態でした。<br>軽く調べて、以下のように理解しました。</p>



<p class="wp-block-paragraph"><strong>Mockitoとは</strong><br> プログラムのモックを簡単に作成するためのフレームワーク。Mock化したいクラスを指定して、各メソッドが呼び出されたときの戻り値を指定することでテストが行える</p>



<p class="wp-block-paragraph"><strong>なぜMock化が必要なのか？</strong><br> プログラムは単体ではなく、別のシステム（DBやAPI）やライブラリなどの他パーツを組み合わせて作成される。ある機能のテストを行おうとした時、DBに処理に使用するデータの登録が無かったり、連携先の外部APIが未完成だと、当然テストが行えない。そこでDBから値を返す処理や、外部APIと連携する部分をMock化することでテストの都合の良いデータが返却できるようになり、テストが行えるようになる</p>



<p class="wp-block-paragraph">と、理解しました</p>



<h2 class="wp-block-heading">シンプルなクラスで、テストを行ってみる</h2>



<p class="wp-block-paragraph">今回は以下のようなクラスを作成しました</p>



<pre class="wp-block-code"><code>package org.example.service;

public class ExampleService {

    public int plus(int a, int b){
        return a + b;
    }

    public int square(int a){
        return a * a;
    }

    public int minus(int a, int b){
        return a - b;
    }

    public int divide(int a, int b){
        if(b == 0){
            return 0;
        }

        return a / b;
    }

    // 足し算した後に2乗する
    public int plusSquare(int a, int b){

        int result = plus(a, b);
        return square(result);
    }
}</code></pre>



<p class="wp-block-paragraph">足し算や引き算、累乗を計算するようなシンプルな内容のクラスです。</p>



<p class="wp-block-paragraph">このクラスに対して単体テストを記述すると、以下のようになります</p>



<pre class="wp-block-code"><code>package org.example.service;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ExampleServiceTest {

    @Test
    public void plusTest(){

        // プラスメソッドが正しく動くことを確認
        ExampleService exampleService = new ExampleService();
        int result = exampleService.plus(1, 2);

        assertEquals(result, 1 + 2);
    }

    @Test
    public void plusSquareTest(){

        // モック準備
        ExampleService exampleServiceMock = mock(ExampleService.class);
        when(exampleServiceMock.plus(anyInt(), anyInt())).thenReturn(10);

        // 上記でplusのMockを作成し、必ず10を返却するように設定しているため
        // 以下の処理では2ではなく、10が返却される
        int result = exampleServiceMock.plus(1,1);

        assertEquals(10, result);
    }
}</code></pre>



<p class="wp-block-paragraph">基本的なテスト方法は<br>・テストしたいメソッドを呼び出す<br>・assert〜メソッドで値を比較する<br>の流れになります。</p>



<p class="wp-block-paragraph">plusSquareTestメソッドで実際にMockを作成し、plusメソッドで 10を返却するように設定しています。そのため、plus(1,1)の結果は2ではなく10が返却され、assertEquals(10, result);の結果、テストOKという動きとなります</p>



<h2 class="wp-block-heading">問題はstaticメソッドのテスト</h2>



<p class="wp-block-paragraph">Mockitoではstaticメソッドのテストも3.4.0からサポートされたとのこと。<br>以下のようにsutaticメソッドを多数含むクラスを作成し、上記と同様のテストを作成してみました</p>



<pre class="wp-block-code"><code>package org.example.service;

public class StaticExampleService {

    public static int plus(int a, int b){
        return a + b;
    }

    public static int square(int a){
        return a * a;
    }

    public static int minus(int a, int b){
        return a - b;
    }

    public static int divide(int a, int b){
        if(b == 0){
            return 0;
        }

        return a / b;
    }

    // 足し算した後に2乗する
    public static int plusSquare(int a, int b){

        int result = StaticExampleService.plus(a, b);
        return StaticExampleService.square(result);
    }
}
</code></pre>



<p class="wp-block-paragraph">テストはこんな感じです</p>



<pre class="wp-block-code"><code>package org.example.service;

import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.*;

public class StaticExampleServiceTest {

    @Test
    public void staticPlusTest(){

        try(MockedStatic&lt;StaticExampleService> mocked = mockStatic(StaticExampleService.class)){
            // モックのセットアップ
            mocked.when(() -> StaticExampleService.plus(anyInt(), anyInt())).thenReturn(3);

            int result = StaticExampleService.plus(10, 20);

            // plusメソッドはMock化されており、どのような値でも3で返却するように設定されている
            assertEquals(3, result);
        }
    }

    @Test
    public void staticPlusSquareTest(){

        try(MockedStatic&lt;StaticExampleService> mocked = mockStatic(StaticExampleService.class)){
            // モックのセットアップ
            mocked.when(() -> StaticExampleService.plus(anyInt(), anyInt())).thenReturn(3);

            int result = StaticExampleService.plusSquare(2,2);

            // plusメソッドはMock化されており、3が返却されるので9になるはず
            assertEquals(9, result);
        }
    }
}</code></pre>



<p class="wp-block-paragraph">スタティックメソッドの場合、mockStaticメソッドを利用してモックを作成します<br>また、try-with-resourceを利用することで、mocked.close()開放漏れを防ぐ事ができます<br>参考：<a href="https://keyno63.hatenablog.com/entry/2021/05/15/060156" target="_blank" rel="noreferrer noopener">https://keyno63.hatenablog.com/entry/2021/05/15/060156</a></p>



<p class="wp-block-paragraph">staticPlusTestについては問題なくテストを行うことが出来ました。</p>



<p class="wp-block-paragraph">問題はstaticPlusSquareTestで、上記の記述では正しく動きません</p>



<h2 class="wp-block-heading">staticPlusSquareTestの問題点とは</h2>



<p class="wp-block-paragraph">staticメソッドの中でローカル変数を利用している場合、テストが正しく動かないようです</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1018" height="364" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_001.png" alt="" class="wp-image-176" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_001.png 1018w, https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_001-300x107.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_001-768x275.png 768w" sizes="auto, (max-width: 1018px) 100vw, 1018px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="405" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_002-1024x405.png" alt="" class="wp-image-175" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_002-1024x405.png 1024w, https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_002-300x119.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_002-768x303.png 768w, https://sheltie-garage.xyz/tech/wp-content/uploads/2022/07/20220724_002.png 1488w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">上記の通り、ローカル変数に設定された値が読み込まれず、plusメソッドは3を返却することを期待してMockを構築下にも関わらず、0が返却されテストが失敗します。<br>このあたりの解決法を土日に調べてみたのですが、このように動作する理由や解決法は見つかりませんでした・・・</p>



<h2 class="wp-block-heading">以上</h2>



<p class="wp-block-paragraph">ということで、JUnitとMockitoの利用方法を土日に調べていました。というお話でした。<br>結果的に解決出来ずで心残りはありますが、もうだめなのでここで一旦打ち切りにします。<br>上記のことから、基本的にstaticメソッドはモック化しないほうが良い気がしていますが、何かしら、ユニットテストのベストプラクティを知りたいところです。</p>



<p class="wp-block-paragraph">こっそりStackOverFlowで聞いてみようかしら</p>


<div id="rinkerid177" class="yyi-rinker-contents  yyi-rinker-postid-177 yyi-rinker-img-m yyi-rinker-catid-11 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/7807/9784295007807.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;" loading="lazy"></a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">スッキリわかるJava入門第3版 [ 中山清喬 ]</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥2,860</span>
															<span class="price_at">(2026/10/18 07:37:39時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=Java&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJava%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3DJava" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>


<div id="rinkerid178" class="yyi-rinker-contents  yyi-rinker-postid-178 yyi-rinker-img-m yyi-rinker-catid-11 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJUnit%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/3773/9784774153773.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;" loading="lazy"></a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJUnit%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">JUnit実践入門 体系的に学ぶユニットテストの技法 （WEB＋DB　press　plusシリーズ） [ 渡辺修司 ]</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥3,630</span>
															<span class="price_at">(2026/10/18 07:37:39時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=JUnit&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FJUnit%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3DJUnit" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2022/07/junit%e3%81%a8mockito%e3%81%a7%e3%83%a6%e3%83%8b%e3%83%83%e3%83%88%e3%83%86%e3%82%b9%e3%83%88%e3%81%ae%e7%b7%b4%e7%bf%92/">JUnitとMockitoでユニットテストの練習</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sheltie-garage.xyz/tech/2022/07/junit%e3%81%a8mockito%e3%81%a7%e3%83%a6%e3%83%8b%e3%83%83%e3%83%88%e3%83%86%e3%82%b9%e3%83%88%e3%81%ae%e7%b7%b4%e7%bf%92/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
