Spring MVC 4.1 No. 034 form:passwordタグ
form:passwordタグは、HTMLの<input type="password">タグを生成します。
指定できる属性はshowPassword以外はform:inputと同じです。
その要素の内、単純にHTMLの属性に置き換えられるものは、以下の属性です。cssClassやcssStyleはそれぞれclass、style属性に置き換えられます。
属性 | 説明 |
---|---|
accesskey | HTML標準のaccesskey属性 |
alt | HTML標準のalt属性 |
autocomplete | HTML標準のautocomplete属性 |
cssClass | HTML標準のclass属性 |
cssStyle | HTML標準のsytle属性 |
dir | HTML標準のdir属性 |
disabled | HTML標準のdisabled属性 |
id | HTML標準のid属性 |
lang | HTML標準のlang属性 |
maxlength | HTML標準のmaxlength属性 |
readonly | HTML標準のreadonly属性 |
size | HTML標準のsize属性 |
tabindex | HTML標準のtabindex |
title | HTML標準のtitle属性 |
その他、JavaScriptのDOMレベル0イベントとして以下の属性が用意されています。それぞれ同名の属性になります。
属性 |
---|
onblur |
onchange |
onclick |
ondblclick |
onfocus |
onkeydown |
onkeypress |
onkeyup |
onmousedown |
onmousemove |
onmouseout |
onmouseover |
onmouseup |
onselect |
残りがSpring用の属性になります。
属性 | 説明 |
---|---|
cssErrorClass | Validationのエラー時のclass属性 |
htmlEscape | HTMLのエスケープをするかどうか。デフォルトはtrue |
path | 関連付けるModelの名前 |
showPassword | パスワードを表示(value属性に出力)するか |
コントローラで使う、Modelです。パスワードのみを格納します。
package com.example.spring.controller.c034; public class C034Model { private String password; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
サンプルのコントローラです。
package com.example.spring.controller.c034; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/c034") public class C034Controller { @RequestMapping("/password") public String password(Model model) { C034Model c034Model = new C034Model(); ; c034Model.setPassword("password"); model.addAttribute("c034Model", c034Model); return "c034/password"; } }
コントローラではformで利用する値をModelに格納しています。
カスタムタグを使用しているJSPです。
<%@page contentType="text/html; charset=utf-8" %><%-- --%><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>サンプル</title> </head> <body> password: <form:password path="c034Model.password" /><br> showPassword=true: <form:password path="c034Model.password" showPassword="true" /><br> </body> </html>
showPasswordを設定しない場合にはpath属性の値は出力されません。逆にshowPasswordをtrueにするとvalueに値が出力されます。
ソースは https://github.com/kuwalab/spring-mvc41 にあります。タグ034が今回のサンプルです。
まとめ http://kuwalab.hatenablog.jp/entry/spring
最初 http://kuwalab.hatenablog.jp/entry/spring_mvc41/001
前回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/033
次回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/035
Spring MVC 4.1 No. 033 form:inputタグ
form:inputタグは、HTMLの<input type="text">タグを生成します。
その要素の内、単純にHTMLの属性に置き換えられるものは、以下の属性です。cssClassやcssStyleはそれぞれclass、style属性に置き換えられます。
属性 | 説明 |
---|---|
accesskey | HTML標準のaccesskey属性 |
alt | HTML標準のalt属性 |
autocomplete | HTML標準のautocomplete属性 |
cssClass | HTML標準のclass属性 |
cssStyle | HTML標準のsytle属性 |
dir | HTML標準のdir属性 |
disabled | HTML標準のdisabled属性 |
id | HTML標準のid属性 |
lang | HTML標準のlang属性 |
maxlength | HTML標準のmaxlength属性 |
readonly | HTML標準のreadonly属性 |
size | HTML標準のsize属性 |
tabindex | HTML標準のtabindex |
title | HTML標準のtitle属性 |
その他、JavaScriptのDOMレベル0イベントとして以下の属性が用意されています。それぞれ同名の属性になります。
属性 |
---|
onblur |
onchange |
onclick |
ondblclick |
onfocus |
onkeydown |
onkeypress |
onkeyup |
onmousedown |
onmousemove |
onmouseout |
onmouseover |
onmouseup |
onselect |
残りがSpring用の属性になります。
属性 | 説明 |
---|---|
cssErrorClass | Validationのエラー時のclass属性 |
htmlEscape | HTMLのエスケープをするかどうか。デフォルトはtrue |
path | 関連付けるModelの名前 |
コントローラで使用するモデルです。
package com.example.spring.controller.c033; public class C033Model { private String name; private Integer price; private Integer listPrice; public C033Model(String name, Integer price, Integer listPrice) { this.name = name; this.price = price; this.listPrice = listPrice; } // setter、getterは省略 }
サンプルのコントローラです。
package com.example.spring.controller.c033; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/c033") public class C033Controller { @RequestMapping("/input") public String input(Model model) { C033Model c033Model = new C033Model("よく分かるSpring<&>", 2000, 2500); model.addAttribute("c033Model", c033Model); return "c033/input"; } }
コントローラではformで利用する値をModelに格納しています。
カスタムタグを使用しているJSPです。
<%@page contentType="text/html; charset=utf-8" %><%-- --%><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>サンプル</title> </head> <body> 書名: <form:input path="c033Model.name" size="20" /><br> 価格: <form:input path="c033Model.price" size="10" maxlength="6" readonly="true" /><br> 定価: <form:input path="c033Model.listPrice" size="10" disabled="true" /><br> </body> </html>
path属性で、モデルの値とタグを関連付けます。Modelに設定されている値がformの初期値となります。
実際に動作させ、出力されるHTMLは以下のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>サンプル</title> </head> <body> 書名: <input id="name" name="name" type="text" value="よく分かるSpring<&>" size="20"/><br> 価格: <input id="price" name="price" readonly="readonly" type="text" value="2000" size="10" maxlength="6"/><br> 定価: <input id="listPrice" name="listPrice" disabled="disabled" type="text" value="2500" size="10"/><br> </body> </html>
ソースは https://github.com/kuwalab/spring-mvc41 にあります。タグ033が今回のサンプルです。
まとめ http://kuwalab.hatenablog.jp/entry/spring
最初 http://kuwalab.hatenablog.jp/entry/spring_mvc41/001
前回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/032
次回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/034
Spring MVC 4.1 No. 032 CSVファイルのダウンロード4
ダウンロードの4つ目の方法はSpringらしい方法です。まず、spring-context.xmlにViewResolverの設定を追加します。処理する順番(order)を1にして最初に参照するようにします。
<bean id="xmlViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver"> <property name="order" value="1" /> <property name="location" value="/WEB-INF/spring/views.xml" /> </bean>
viewResolverで参照する設定ファイルのviews.xmlは次のようになります。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean id="c032Download" class="com.example.spring.controller.c032.C032DownloadView" /> </beans>
この例だと、viewの名前がc032Downloadの場合にC032DownloadView#renderMergedOutputModelが呼び出されます。そのC032DownloadViewクラスは次のとおりです。
package com.example.spring.controller.c032; import java.io.PrintWriter; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.util.MimeTypeUtils; import org.springframework.web.servlet.view.AbstractView; public class C032DownloadView extends AbstractView { @SuppressWarnings("unchecked") @Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { response.setContentType(MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE + ";charset=utf-8"); response.setHeader("Content-Disposition", "attachment; filename=\"test.csv\""); try (PrintWriter pw = response.getWriter()) { for (C032Model c032Model : (List<C032Model>) model .get("c032ModelList")) { pw.print(c032Model.getName()); pw.print(","); pw.print(c032Model.getPrice()); pw.print("\r\n"); } } } }
AbstractViewを継承し、renderMergedOutputModelメソッドを実装します。実装としてはこれまでどおりのCSVファイルを作成して出力しています。
ContollerとJSPはこれまでと大きく変わりません。
package com.example.spring.controller.c032; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class C032Controller { @RequestMapping("/c032/csvInit") public String csvInit() { return "c032/csvInit"; } @RequestMapping("/c032/csvDown") public String csvDown4(Model model) { List<C032Model> c032ModelList = new ArrayList<>(); C032Model c032Model = new C032Model(); c032Model.setName("よくわかるSpring"); c032Model.setPrice(3000); c032ModelList.add(c032Model); c032Model = new C032Model(); c032Model.setName("よくわかるJava"); c032Model.setPrice(2980); c032ModelList.add(c032Model); model.addAttribute("c032ModelList", c032ModelList); return "c032Download"; } }
package com.example.spring.controller.c032; public class C032Model { private String name; private Integer price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }
<%@page contentType="text/html; charset=utf-8" %><%-- --%><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>サンプル</title> </head> <body> <a href="csvDown">csvDown</a> </body> </html>
確認用のテストケースは次のとおりです。
package com.example.spring.controller.c032; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/spring-context.xml" }) public class C032ControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup() { mockMvc = webAppContextSetup(wac).build(); } @Test public void csvInitのGET() throws Exception { mockMvc.perform(get("/c032/csvInit")).andExpect(status().isOk()) .andExpect(view().name("c032/csvInit")); } @Test public void csvDownのGET() throws Exception { StringBuilder sb = new StringBuilder(); sb.append("よくわかるSpring,3000\r\n"); sb.append("よくわかるJava,2980\r\n"); mockMvc.perform(get("/c032/csvDown")) .andExpect(status().isOk()) .andExpect(view().name("c032Download")) .andExpect( content().contentType( "application/octet-stream;charset=utf-8")) .andExpect(content().string(sb.toString())); } }
ソースは https://github.com/kuwalab/spring-mvc41 にあります。タグ032が今回のサンプルです。
まとめ http://kuwalab.hatenablog.jp/entry/spring
最初 http://kuwalab.hatenablog.jp/entry/spring_mvc41/001
前回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/031
次回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/033
Spring MVC 4.1 No. 031 RedirectAttribute
Springではリダイレクト時にリダイレクト先で参照できるRedirectAttributeを使用できます。
package com.example.spring.controller.c031; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @Controller public class C031Controller { @RequestMapping("/c031/flashScope1") public String flashScope1(RedirectAttributes attrs, Model model) { attrs.addFlashAttribute("flash1", "flash1"); model.addAttribute("request1", "request1"); return "redirect:/c031/flashScope2"; } @RequestMapping("/c031/flashScope2") public String flashScope2() { return "c031/flashScope"; } }
コントローラからJSPへ明示的にリダイレクトしています。
表示用のflashScope1.jspは以下のようになります。
<%@page contentType="text/html; charset=utf-8" %><%-- --%><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>サンプル</title> </head> <body> flash1: <c:out value="${flash1}" /><br> request1: <c:out value="${request1}" /> </body> </html>
確認用のテストケースは次のとおりです。
package com.example.spring.controller.c031; import static org.hamcrest.CoreMatchers.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/spring-context.xml" }) public class C031ControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup() { mockMvc = webAppContextSetup(wac).build(); } @Test public void requestScopeのGET() throws Exception { mockMvc.perform(get("/c031/flashScope1")).andExpect(status().isFound()) .andExpect(redirectedUrl("/c031/flashScope2")) .andExpect(flash().attribute("flash1", "flash1")) .andExpect(request().attribute("request1", is(nullValue()))); } }
ソースは https://github.com/kuwalab/spring-mvc41 にあります。タグ031が今回のサンプルです。
まとめ http://kuwalab.hatenablog.jp/entry/spring
最初 http://kuwalab.hatenablog.jp/entry/spring_mvc41/001
前回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/030
次回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/032
Spring MVC 4.0 No. 030 コンポーネントをSessionスコープから破棄する
SpringのSessionスコープに格納したコンポーネントのうち、コントローラーに関連したものだけをクリアすることができます。セッションに格納する仕組み自体は前回のものと同様です。
まず、Sessionに置くコンポーネントを用意します。
package com.example.spring.controller.c030; import java.io.Serializable; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; import org.springframework.web.context.WebApplicationContext; @Component @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public class C030Model implements Serializable { private static final long serialVersionUID = 1L; private String name; private Integer price; // setter、getterは省略 }
@Scopeアノテーションで、コンポーネントのスコープをSessionにします。また、Sessionスコープを利用する場合には、proxyMode属性を指定します。
次に、コントローラーです。
package com.example.spring.controller.c030; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.support.SessionStatus; @Controller @RequestMapping("/c030") @SessionAttributes("scopedTarget.c030Model") public class C030Controller { @Autowired private C030Model c030Model; @RequestMapping("/sessionStart") public String sessionStart(Model model) { c030Model.setName("よくわかるHttpSession"); c030Model.setPrice(980); model.addAttribute("c030Model", c030Model); return "c030/sessionScope"; } @RequestMapping("/sessionScope") public String sessionScope(Model model) { model.addAttribute("c030Model", c030Model); return "c030/sessionScope"; } @RequestMapping("/sessionClear") public String sesseionClear(Model model, SessionStatus sessionStatus) { sessionStatus.setComplete(); model.addAttribute("c030Model", c030Model); return "c030/sessionScope"; } }
前回と異なるのは、sessionClearメソッドです。sessionClearメソッドではSessionStatusを引数に取り、setCompleteメソッドでクラスの@SessionAttributeで指定したコンポーネントのデータをクリアしています。@SessionAttributeで指定する名前は、"scopedTarget." + コンポーネント名になります。
表示用のsessionScope.jspは次のとおりです。セッションクリアへのリンクを追加しています。
<%@page contentType="text/html; charset=utf-8" %><%-- --%><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>サンプル</title> </head> <body> 書名: <c:out value="${c030Model.name}" /><br> 価格: <c:out value="${c030Model.price}" /><br> <a href="sessionScope">画面遷移</a><br> <a href="sessionClear">セッションクリア</a> </body> </html>
確認用のテストケースは次のとおりです。
package com.example.spring.controller.c030; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpSession; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.ModelAndView; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/spring-context.xml" }) public class C030ControllerTest { @Autowired private WebApplicationContext wac; @Autowired private MockHttpSession mockHttpSession; private MockMvc mockMvc; @Before public void setup() { mockMvc = webAppContextSetup(wac).build(); } @Test public void sessionStartのGET() throws Exception { MvcResult mvcResult = mockMvc .perform(get("/c030/sessionStart").session(mockHttpSession)) .andExpect(status().isOk()) .andExpect(view().name("c030/sessionScope")) .andExpect(model().attributeExists("c030Model")).andReturn(); checkC030Model(mvcResult); mvcResult = mockMvc .perform(get("/c030/sessionScope").session(mockHttpSession)) .andExpect(status().isOk()) .andExpect(view().name("c030/sessionScope")) .andExpect(model().attributeExists("c030Model")).andReturn(); checkC030Model(mvcResult); mvcResult = mockMvc .perform(get("/c030/sessionClear").session(mockHttpSession)) .andExpect(status().isOk()) .andExpect(view().name("c030/sessionScope")) .andExpect(model().attributeExists("c030Model")).andReturn(); ModelAndView mav = mvcResult.getModelAndView(); Object c030ModelObject = mav.getModel().get("c030Model"); assertThat(c030ModelObject, is(notNullValue())); assertThat(c030ModelObject, is(instanceOf(C030Model.class))); C030Model c030Model = (C030Model) c030ModelObject; assertThat(c030Model.getName(), is(nullValue())); assertThat(c030Model.getPrice(), is(nullValue())); } private void checkC030Model(MvcResult mvcResult) { // モデルデータの確認 ModelAndView mav = mvcResult.getModelAndView(); Object c030ModelObject = mav.getModel().get("c030Model"); assertThat(c030ModelObject, is(notNullValue())); assertThat(c030ModelObject, is(instanceOf(C030Model.class))); C030Model c030Model = (C030Model) c030ModelObject; assertThat(c030Model.getName(), is("よくわかるHttpSession")); assertThat(c030Model.getPrice(), is(980)); } }
ソースは https://github.com/kuwalab/spring-mvc41 にあります。タグ030が今回のサンプルです。
まとめ http://kuwalab.hatenablog.jp/entry/spring
最初 http://kuwalab.hatenablog.jp/entry/spring_mvc41/001
前回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/029
次回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/031
Spring MVC 4.0 No. 029 コンポーネントをSessionスコープにする
SpringのコンポーネントをデフォルトのシングルトンからSessionに変更して、リクエストをまたいでコンポーネントを利用することができます。
まず、Sessionに置くコンポーネントを用意します。
package com.example.spring.controller.c029; import java.io.Serializable; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; import org.springframework.web.context.WebApplicationContext; @Component @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public class C029Model implements Serializable { private static final long serialVersionUID = 1L; private String name; private Integer price; // getter、setterは省略 }
@Scopeアノテーションで、コンポーネントのスコープをSessionにします。また、Sessionスコープを利用する場合には、proxyMode属性を指定します。
次に、コントローラーです。
package com.example.spring.controller.c029; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/c029") public class C029Controller { @Autowired private C029Model c029Model; @RequestMapping("/sessionStart") public String sessionStart(Model model) { c029Model.setName("よくわかるHttpSession"); c029Model.setPrice(980); model.addAttribute("c029Model", c029Model); return "c029/sessionScope"; } @RequestMapping("/sessionScope") public String sessionScope(Model model) { model.addAttribute("c029Model", c029Model); return "c029/sessionScope"; } }
コントローラーでは、C029Modelをインジェクションしています。
表示用のsessionScope.jspは次のとおりです。
<%@page contentType="text/html; charset=utf-8" %><%-- --%><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>サンプル</title> </head> <body> 書名: <c:out value="${c029Model.name}" /><br> 価格: <c:out value="${c029Model.price}" /><br> <a href="sessionScope">画面遷移</a> </body> </html>
確認用のテストケースは次のとおりです。
package com.example.spring.controller.c029; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpSession; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.ModelAndView; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/spring-context.xml" }) public class C029ControllerTest { @Autowired private WebApplicationContext wac; @Autowired private MockHttpSession mockHttpSession; private MockMvc mockMvc; @Before public void setup() { mockMvc = webAppContextSetup(wac).build(); } @Test public void sessionStartのGET() throws Exception { MvcResult mvcResult = mockMvc .perform(get("/c029/sessionStart").session(mockHttpSession)) .andExpect(status().isOk()) .andExpect(view().name("c029/sessionScope")) .andExpect(model().attributeExists("c029Model")).andReturn(); checkC029Model(mvcResult); mvcResult = mockMvc .perform(get("/c029/sessionScope").session(mockHttpSession)) .andExpect(status().isOk()) .andExpect(view().name("c029/sessionScope")) .andExpect(model().attributeExists("c029Model")).andReturn(); checkC029Model(mvcResult); } private void checkC029Model(MvcResult mvcResult) { // モデルデータの確認 ModelAndView mav = mvcResult.getModelAndView(); Object c029ModelObject = mav.getModel().get("c029Model"); assertThat(c029ModelObject, is(notNullValue())); assertThat(c029ModelObject, is(instanceOf(C029Model.class))); C029Model c029Model = (C029Model) c029ModelObject; assertThat(c029Model.getName(), is("よくわかるHttpSession")); assertThat(c029Model.getPrice(), is(980)); } }
ソースは https://github.com/kuwalab/spring-mvc41 にあります。タグ029が今回のサンプルです。
まとめ http://kuwalab.hatenablog.jp/entry/spring
最初 http://kuwalab.hatenablog.jp/entry/spring_mvc41/001
前回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/028
次回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/030
Spring MVC 4.1 No. 028 セッションスコープにデータを格納
セッションにデータを格納する方法もリクエスト同様に複数あります。Servlet APIのHttpSessionを使用する方法、WebRequestを使用する方法などです。
WebRequestはリクエストスコープと同様にデータを格納する際にスコープを指定します。
今回は同一の画面に遷移する3つのメソッドを用意しています。最初のものはセッションにデータを格納するもの、2番目は何もしないもの、3番目はセッションをクリアするものになります。
package com.example.spring.controller.c028; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.WebRequest; @Controller @RequestMapping("/c028") public class C028Controller { @RequestMapping("/sessionStart") public String sessionScope1(HttpSession session, WebRequest webRequest) { session.setAttribute("session1", "httpSession"); webRequest.setAttribute("session2", "webRequest", WebRequest.SCOPE_SESSION); return "c028/sessionScope"; } @RequestMapping("/sessionScope") public String sessionScope2() { return "c028/sessionScope"; } @RequestMapping("/sessionClear") public String sessionScope3(HttpSession session) { session.invalidate(); return "c028/sessionScope"; } }
表示用のsessionScop.jspです。
<%@page contentType="text/html; charset=utf-8" %><%-- --%><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>サンプル</title> </head> <body> HttpSession: <c:out value="${sessionScope.session1}" /><br> WebRequest: <c:out value="${sessionScope.session2}" /><br> <a href="sessionScope">セッションをクリアせず再表示</a><br> <a href="sessionClear">セッションをクリアして再表示</a> </body> </html>
確認用のテストケースは次のとおりです。
package com.example.spring.controller.c028; import static org.hamcrest.corematchers.*; import static org.junit.Assert.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; import java.util.UUID; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpSession; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/spring-context.xml" }) public class C028ControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; private MockHttpSession mockHttpSession; @Before public void setup() { mockMvc = webAppContextSetup(wac).build(); mockHttpSession = new MockHttpSession(wac.getServletContext(), UUID .randomUUID().toString()); } @Test public void requestScopeのGET() throws Exception { assertThat(mockHttpSession.getAttribute("session1"), is(nullValue())); assertThat(mockHttpSession.getAttribute("session2"), is(nullValue())); mockMvc.perform(get("/c028/sessionStart").session(mockHttpSession)) .andExpect(status().isOk()) .andExpect(view().name("c028/sessionScope")); assertThat(mockHttpSession.getAttribute("session1"), is("httpSession")); assertThat(mockHttpSession.getAttribute("session2"), is("webRequest")); // セッションは維持される mockMvc.perform(get("/c028/sessionScope").session(mockHttpSession)) .andExpect(view().name("c028/sessionScope")); assertThat(mockHttpSession.getAttribute("session1"), is("httpSession")); assertThat(mockHttpSession.getAttribute("session2"), is("webRequest")); // セッションは破棄される mockMvc.perform(get("/c028/sessionClear").session(mockHttpSession)) .andExpect(view().name("c028/sessionScope")); assertThat(mockHttpSession.isInvalid(), is(true)); } }
ソースは https://github.com/kuwalab/spring-mvc41 にあります。タグ028が今回のサンプルです。
まとめ http://kuwalab.hatenablog.jp/entry/spring
最初 http://kuwalab.hatenablog.jp/entry/spring_mvc41/001
前回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/027
次回 http://kuwalab.hatenablog.jp/entry/spring_mvc41/029