【Spring】テクニック

リクエスト情報を基底クラスに定義

基底クラスにリクエストを格納する処理(セッターインジェクション)を記載しておくことで継承先クラスでの利便性を上げる(requestとして使える)

// 基底クラス
public class BaseController {
    /**
     * リクエスト情報
     */
    protected transient HttpServletRequest request;

    /**
     * HttpServletRequest
     * @param request request
     */
    @Autowired
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }
}
// リクエストを使用するクラス
@Controller
public class OfferController extends BaseController{
    @RequestMapping(value = "/offer", method = RequestMethod.GET)
    public void sample() {
        // リクエストはrequestで使える
        request.getSession().setAttribute("sample", "aiueo");
        String a = (String)request.getSession().getAttribute("sample");
    }
}

jspからServiceのメソッドを呼び出す

ModelにServiceを格納するとjspからServiceのメソッドを呼び出せる
Controller

@Controller
public class ConfirmOffer {
    @Autowired
    OfferService service;

    @PostMapping("offer_confirm")
    public String confirm(Model model) {
        // ServiceをModelに格納する
        model.addAttribute("offerService", service);

        return "offer/confirmOffer";
    }
}

Service

@Service
public class OfferService {

    @Autowired
    OfferRepository offerRepository;

    // MyBatisでDBから値を取得する
    public MemberBean selectMember(Integer userId) {
        MemberBean bean = offerRepository.selectMember(userId);
        return bean;
    }

    public String getSample() {
        return "あいうえお";
    }
}

jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<%-- 引数なしの場合 --%>
${offerService.getSample()}
<br>
<%-- 引数あり、戻り値がBeanの場合 --%>
${offerService.selectMember(8).name}
</body>
</html>

プロパティファイルの値を使用する

【プロパティファイルとは】
プロパティファイルは、プログラムの設定値などを保存しておくファイルとして使われる。中身の値を変えるとコンパイルなしでプログラムの動作を変更できる。
ファイルの文字コードは「ISO 8859-1(Latin-1)」を使用する。
【プロパティファイルの記載方法】
プロパティファイルをLimyプロパティエディターで開くと文字化けせずに編集できる

【プロパティファイルの配置場所】
クラスパスはsrc/main/resourcesとsrc/main/java配下のファイルから作成される。

target>classesがクラスパス。

方法1.ResourceBundleMessageSourceを使用

コンテキストファイル(root-context.xmlやapplicationContext等)に以下を記載する。
valueはクラスパスからのファイルのパス。

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
      <property name="basename" value="properties/errorMessages" />
    </bean>

【複数のプロパティファイルを読み込む場合】
※同じキーが重複する場合は、先に記載したプロパティファイルの値を優先する

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>properties/applicationMessages</value>
                <value>properties/errorMessages</value>
            </list>
        </property>
    </bean>

【使用方法】

@Controller
public class OfferController {

    // MessageSourceをDIする
    @Autowired
    protected MessageSource messageSource;

    @GetMapping("/offer_initDisplay")
    public String initDisplay(Model model) {

        // 引数なしの場合
        String msg1 = messageSource.getMessage("errors.sample", null, Locale.getDefault());

        // 引数ありの場合
        String msg2 = messageSource.getMessage("errors.length", new String[]{"ID", "5"}, Locale.getDefault());

        return "offer/offer";
    }
}
方法2.アノテーション(@Value)を使用

コンテキストファイル(spring-mvc.xmlとapplicationContextや、servlet-context.xmlとroot-context.xml)に以下を記載する。※2つに記載必要
valueはクラスパスからのファイルのパス。
方法1の引数ありのパターンは無理そう。

    <context:property-placeholder location="classpath*:properties/*.properties"/>

【使用方法】

@Controller
@RequestMapping("/offer")
public class OfferController {

    // プロパティファイルのキーを指定
    @Value("${errors.sample}")
    private String errorMsg;

    @GetMapping("/offer_initDisplay")
    public String initDisplay(Model model) {
        System.out.println(errorMsg);

        return "offer/offer";
    }
}
方法3.@ConfigurationPropertiesを使用(SpringBoot)

Beanにまとめて格納できる
application.properties

# comment
test1.id=propertiesID1
test1.pw=propertiesPW1

test2.id=propertiesID2
test2.pw=propertiesPW2

PropertiesBean.java

@Component
@ConfigurationProperties(prefix = "test1")
public class PropertiesBean {
	private String id;
	private String pw;

	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPw() {
		return pw;
	}
	public void setPw(String pw) {
		this.pw = pw;
	}
}

MainController.java

@Controller
public class MainController {

	@Autowired
	private PropertiesBean test1;

    @RequestMapping(value = "/sample")
    public String test(Model model) {
    	model.addAttribute("id",test1.getId());

        return "sample";
    }
}

実行結果

point

格納したい階層をprefixに記述する(test1を記述すればtest1配下すべて)