Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java EEアクションベースMVC入門 #jjug_ccc #ccc_cd4

Java EEアクションベースMVC入門 #jjug_ccc #ccc_cd4

JJUG CCC 2016 Spring「ネクストStruts/Seasar2としてのJava EEアクションベースMVC入門」の発表資料です。ビューはThymeleaf3を使っています。
Java EE 7, Java EE 8, JAX-RS, Thymeleaf 3

Masatoshi Tada

May 21, 2016
Tweet

More Decks by Masatoshi Tada

Other Decks in Technology

Transcript

  1. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ωΫετStruts/Seasar2ͱͯ͠ͷ Java EEΞΫγϣϯϕʔεMVCೖ໳

    גࣜձࣾΧαϨΞϧɹଟాਅහ JJUG CCC 2016 Spring 2016/5/21(౔) 1
  2. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ͜ͷηογϣϯʹ͍ͭͯ ! ʮJava

    EE͸Struts/Seasar2ͷ୅ସͱͯ͠
 ʰ࢖͑Δʱͷ͔ʁʯͱ͍͏ٙ໰ʹ͓౴͑͠·͢ ! Ϗϡʔͱͯ͠ThymeleafΛ࢖ͬͯ·͢ʂ ! ιʔε͸GitHubʹ͋Γ·͢ ! https://github.com/MasatoshiTada/jjug-action-based-mvc ! ຊεϥΠυͷίʔυ͸εϖʔεͷ౎߹্ɺҰ෦লུ͍ͯ͠ ·͢ɻGitHubͷίʔυ͕ਖ਼͍͠Ͱ͢ 2
  3. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ࣗݾ঺հ ! ଟాਅහʢͨͩ·͞ͱ͠ʣ

    ! (ג)ΧαϨΞϧ ! GlassFish User Group Japan ! Java EE/Spring/SwiftͳͲͷݚमτϨʔφʔ ! JJUG CCC͸5ճ࿈ଓ5ճ໨ͷग़৔ ! Twitterɿ@suke_masa ! ͸ͯͳϒϩάɿJava EE ࣄ࢝Ίʂ 3
  4. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ໨࣍ ᶃ ΞΫγϣϯϕʔεMVCͱ͸ʁ

    ᶄ MVC 1.0(EE 8)ೖ໳ ᶅ EE 7ʹ͓͚ΔJersey MVCͱ
 RESTEasy HTMLͷ׆༻ ᶆ ͦͷଞͷ஌͓ͬͯ͘΂͖Java EE 4
  5. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ΞΫγϣϯϕʔεMVCͱ͸ʁ ! HTTPͷϦΫΤετɾϨεϙϯεʹ


    ϑΥʔΧεͨ͠WebϑϨʔϜϫʔΫ ! StrutsɾSeasar2ɾSpring MVCͳͲɺ
 େ൒ͷϑϨʔϜϫʔΫ͕ΞΫγϣϯϕʔε 6
  6. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ΞΫγϣϯϕʔεMVCͱ͸ʁ 7 View

    View Controller Model ϦΫΤετ Ϩεϙϯε Struts/Seasar2։ൃऀʹ͸ ͱͯ΋ೃછΈ΍͍͢
  7. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ίϯϙʔωϯτϕʔεMVCͱ͸ʁ 8 View

    Backing Bean Model ը໘ͱJavaΫϥε͕1ର1 →গ͠ೃછΈͮΒ͍
  8. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Java EEͷWebϑϨʔϜϫʔΫ !

    JSF ! HTMLΛฦ͢ ! ίϯϙʔωϯτϕʔε ! JAX-RS ! JSON΍XMLΛฦ͢ ! ΞΫγϣϯϕʔε 9 ʮHTMLΛฦ͢ʯ͔ͭ ʮΞΫγϣϯϕʔεʯͳ ϑϨʔϜϫʔΫ͸ແ͔ͬͨ
  9. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ଴๬ͷJava EEඪ४ ΞΫγϣϯϕʔεMVC

    ! Model-View-Controller API (MVC 1.0) ! Java EE 8Ͱಋೖ (2017೥্൒ظͷ༧ఆ) ! JAX-RSϕʔε 10
  10. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. MVC 1.0ͷ࢓༷ͱ࣮૷ !

    MVC 1.0͸࢓༷ ! ≒ΠϯλϑΣʔεɾྫ֎ɾΞϊςʔγϣϯͷू߹ ! ࢀর࣮૷͸Ozark ! ্هͷΠϯλϑΣʔε࣮૷Ϋϥε΍ɺͦͷଞͷ ඞཁͳΫϥεͷू߹ ! ࢀর࣮૷ʹެࣜͷ࣮૷ 12
  11. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Struts/Seasar2ͷʮ͋ͷʯػೳ ! ίϯτϩʔϥʔ

    ! ೖྗݕূ ! ྫ֎ॲཧ ! ը໘ߏங ! ೋॏαϒϛοτ๷ࢭ 13
  12. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. MVC 1.0ʹ͸ʁ !

    ίϯτϩʔϥʔ → ⭕ ! ೖྗݕূ → ⭕ ! ྫ֎ॲཧ → ⭕ ! ը໘ߏங → ❌ ! ೋॏαϒϛοτ๷ࢭ → ❌ 14
  13. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ը໘ߏங͕ແ͍ཧ༝ ! MVC࢓༷ࡦఆͷํ਑Ͱ


    ʮ৽ͨͳϏϡʔݴޠ͸ఆٛ͠ͳ͍ʯ
 ͱܾ·͍ͬͯΔͨΊ ! ୅ΘΓʹɺ༷ʑͳϏϡʔٕज़ͱ࿈ܞ͢Δ ͨΊͷػೳΛఏڙ͍ͯ͠Δ 15
  14. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. MVC 1.0Ͱ࢖͑ΔϏϡʔٕज़ !

    MVC 1.0ެࣜ ! JSPɺFacelets ! Ozarkಠࣗ ! ThymeleafɺMustacheɺFreemarkerɺ
 HandlerbarsɺVelocityɺAsciiDocɺ౳ 16 ViewEngineΠϯλϑΣʔεΛ ࣮૷͢Ε͹ଞͷϏϡʔ΋ར༻Մೳ
  15. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. JSPɾFaceletsͷ໰୊఺ 17 !

    JSP ! ϏϡʔͱϩδοΫ͕ࠞ͟Δ͜ͱ͕͋Δ ! XSS੬ऑੑΛҾ͖ى͜͠΍͍͢ ! Facelets ! MVC 1.0Ͱ͸શػೳΛ׆༻Ͱ͖ͳ͍ ! JavaScriptͱ૬ੑ͕ѱ͍
  16. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ThymeleafΛ࢖ͬͯΈΑ͏ʂ 18 !

    ϐϡΞͳHTMLͰॻ͚Δʂ ! ϏϡʔͱϩδοΫ͕׬શʹ෼཭Ͱ͖Δʂ ! JavaScriptͱͷ૬ੑ͕ྑ͍ʂ ! σϑΥϧτͰΤεέʔϓͯ͘͠ΕΔʂ ! ϦϯΫࣜ΍ϝοηʔδͷࠃࡍԽ΋ศརʂ ! http://www.thymeleaf.org/doc/tutorials/2.1/ usingthymeleaf_ja.html (by @bufferings͞Μʂ)
  17. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. MVC 1.0ͰThymeleafΛ࢖͏ํ๏ 19

    <dependency> <groupId>org.glassfish.ozark.ext</groupId> <artifactId>ozark-thymeleaf</artifactId> <version>1.0.0-m02</version> <scope>compile</scope> </dependency> ! pom.xmlʹԼهͷґଘੑΛՃ͑Δ͚ͩ ݱ࣌఺Ͱ͸Thymeleaf2ɻ ࠓճ͸3༻ͷViewEngineΛࣗલͰ࣮૷
  18. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ೋॏαϒϛοτ๷ࢭ͕ແ͍ཧ༝ ! ΤΩεύʔτάϧʔϓͷٞ࿦Ͱɺ


    ʮΫϥΠΞϯταΠυͰରԠ͢΂͖ʯ ͱҙݟ͕Ұகͨͨ͠Ί ! https://java.net/projects/mvc-spec/lists/jsr371- experts/archive/2015-07/message/2 ! Spring MVCʹ΋͜ͷػೳ͸ແ͍ 20
  19. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ೋॏαϒϛοτΛ๷ࢭ͢Δํ๏ ! γεςϜΤϯδχΞAdvent

    Calender ! http://qiita.com/syobochim/items/ 120109315f671918f28d ! TERASOLUNAΨΠυϥΠϯ ! http://terasolunaorg.github.io/guideline/ 5.1.0.RELEASE/ja/ArchitectureInDetail/ DoubleSubmitProtection.html 21
  20. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ४උɿJAX-RSͷ༗ޮԽ 22 @ApplicationPath("/api")

    public class MyApplication extends Application { } ApplicationΛܧঝ ΞϊςʔγϣϯΛ෇Ճ jjug-mvc10/src/main/java/com/example/rest/MyApllication.java
  21. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. جຊతͳίϯτϩʔϥʔ 23 @Path("/employee")

    public class EmployeeController { @GET @Path("/index") @Controller public String index() { return "employee/index.html"; } } Ϗϡʔͷύε(֦ுࢠඞਢ) ίϯτϩʔϥʔϝιου Ͱ͋Δ͜ͱΛࣔ͢ URL΍HTTPϝιου ͱͷରԠ෇͚ ※ࣼମ෦෼͕MVC1.0ͷػೳ jjug-mvc10/src/main/java/com/example/rest/controller/EmployeeController.java
  22. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ೖྗ஋Λड͚औΔϑΥʔϜΫϥε 24 public

    class EmployeeIdForm { @QueryParam("id") @NotBlank @Pattern(regexp = "[1-9][0-9]*") private String id; // setter/getter } ΫΤϦύϥϝʔλ"id" Λऔಘ͢Δ Bean Validationͷ ݕূΞϊςʔγϣϯ jjug-mvc10/src/main/java/com/example/rest/form/EmployeeIdForm.java
  23. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Ϗϡʔʹ஋Λ౉͢ 25 public

    class EmployeeController { @Inject private Models models; @GET @Path("/result") @Controller @ValidateOnExecution(type=ExecutableType.NONE) public String result(…) { models.put("employee", employee); return "employee/result.html"; } ஋ͷೖΕ෺ ʢMap + Iteratorʣ ϏϡʔͰ ࢀর͢Δ஋ ※ࣼମ෦෼͕MVC1.0ͷػೳ jjug-mvc10/src/main/java/com/example/rest/controller/EmployeeController.java
  24. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ౉͞Εͨ஋ͷදࣔ 26 <table

    th:if="${employee}"> <tr th:object="${employee}"> <td th:text="*{empId}">99999</td> <td th:text="*{name}">Taro Yamada</td> <td th:text="*{joinedDate}">2020-01-01</td> <td th:text="*{department.deptId}">99</td> <td th:text="*{department.name}">Admin</td> </tr> </table> Ϗϡʔ͸WEB-INF/viewsʹ࡞੒ jjug-mvc10/src/main/webapp/WEB-INF/views/employee/result.html Modelsʹput໊ͨ͠લ
  25. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. όϦσʔγϣϯ 27 public

    class EmployeeController { @Inject private BindingResult br; @GET @Path("/result") @Controller @ValidateOnExecution(type=ExecutableType.NONE) public String result( @Valid @BeanParam EmployeeIdForm form) { if (br.isFailed()) { models.put("bindingResult", br); return "employee/index.html"; // ೖྗը໘΁ Τϥʔϝοηʔδͷ ೖΕ෺ ݕূͷ ༗ޮԽ Τϥʔ࣌ͷॲཧ ※ࣼମ෦෼͕MVC1.0ͷػೳ jjug-mvc10/src/main/java/com/example/rest/controller/EmployeeController.java
  26. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Τϥʔϝοηʔδͷදࣔ 28 <ul

    th:if="${bindingResult}"> <li th:each="message : ${bindingResult.allMessages}" th:text="${message}"> μϛʔͷϝοηʔδ </li> </ul> BindingResult͔Β ϝοηʔδΛऔಘ jjug-mvc10/src/main/webapp/WEB-INF/views/employee/index.html
  27. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Τϥʔϝοηʔδͷهड़ ! src/main/resources/

    ValidationMessages.propertiesʹهड़ ! ΞϊςʔγϣϯݕূΞϊςʔγϣϯͷ messageଐੑʹϝοηʔδͷΩʔΛࢦఆ 29
  28. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Τϥʔϝοηʔδͷࢦఆ 30 public

    class EmployeeIdForm { @QueryParam("id") @NotBlank(message = "{id.notblank}") @Pattern(regexp = "[1-9][0-9]*", message = "{id.pattern}") private String id; // setter/getter {}Λ෇͚ͯ ϝοηʔδͷΩʔΛࢦఆ jjug-mvc10/src/main/java/com/example/rest/form/EmployeeIdForm.java
  29. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ஫ҙɿ ϑΥʔϜόΠϯσΟϯάػೳ͸ແ͍ !

    @BeanParam͸ɺ͋͘·Ͱෳ਺ͷύϥ ϝʔλΛ1ͭͷΫϥεʹ·ͱΊΔ͚ͩ ! ݕূΤϥʔͰೖྗը໘ʹ໭ͬͨࡍʹɺ
 ೖྗ஋ΛςΩετϘοΫεʹ࢒͢ॲཧ͸ɺ ࣗ෼Ͱ࣮૷͢Δ 31
  30. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ϑΥʔϜόΠϯσΟϯάͷ࣮૷ 32 <form

    action="./result" method="get"> <input type="text" name="id" value="" th:value="${param.id} ? ${param.id[0]} : '' "> <input type="submit" value="ݕࡧ"> </form> jjug-mvc10/src/main/webapp/WEB-INF/views/employee/index.html ηϨΫτϘοΫεͱ͔͸ ͪΐͬͱେม͔΋…
  31. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ྫ֎ॲཧ ! ExceptionMapperΠϯλϑΣʔε࣮૷Ϋ

    ϥεΛ࡞੒ ! ίϯτϩʔϥʔϝιου಺Ͱྫ֎͕ൃੜ ͢ΔͱɺExceptionMapperʹॲཧ͕ҠΔ ! ྫ֎ͷܕʹ߹Θͤͯෳ਺࡞੒Մೳ 33
  32. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ExceptionMapperΫϥε 34 @Provider

    public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<Exception> { public Response toResponse( Exception exception) { // Τϥʔը໘΁ͷભҠͳͲ } } @ProviderΛ๨Εͣʹ εϩʔ͞Εͨྫ֎͸ Ҿ਺Ͱड͚औΔ ExceptionMapper Λ࣮૷ jjug-mvc10/src/main/java/com/example/rest/exception/mapper/ExceptionMapper.java
  33. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ͦͷଞͷػೳ ! ηΩϡϦςΟʢCSRFରࡦɺXSSରࡦʣ

    ! ϑΝΠϧΞοϓϩʔυɺμ΢ϯϩʔυ ! MvcContextʢURLࢦఆ͕؆୯ʹʣ ! HTMLΞϓϦͱRESTͷࠞ߹ʢϋΠϒϦουΫϥεʣ ! ৄࡉ͸GlassFishษڧձͷࢿྉ΁ ! http://www.slideshare.net/masatoshitada7/java-ee-8mvc-10 35
  34. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ͜͜·Ͱͷ·ͱΊ ! MVC

    1.0 + ThymeleafͰɺStruts/Seasar2ͷػೳ ͸΄΅ΧόʔͰ͖Δ ! ͔͠΋ɺΑΓ؆୯ʹʂΑΓηΩϡΞʹʂ ! ೋॏαϒϛοτ๷ࢭͱϑΥʔϜόΠϯσΟϯά ͸ɺࣗ෼Ͱ࣮૷͢Δඞཁ͋Γ ! MVC 1.0ࣗମͷػೳ͸γϯϓϧͰɺطଘͷJava EEͷػೳΛϑϧ׆༻͍ͯ͠Δ 36
  35. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Java EE 7Ͱ͸Ͳ͏͢Δ͔ʁ

    ! MVC 1.0͸Java EE 8Ͱಋೖ͞ΕΔ ! Java EE 8͸2017೥্൒ظ 38 Java EE 7ͷࠓ͸ Jersey MVCɾRESTEasy HTMLΛ࢖͏ʂ
  36. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Jersey MVCͱ͸ʁ !

    JAX-RSͷࢀর࣮૷ʮJerseyʯͷಠࣗػೳ ! MVC 1.0ͷϞσϧʹͳͬͨͱݴΘΕͯ ͍Δ ! GlassFish/Payara͸಺แ͍ͯ͠Δ ! WebLogic͸಺แ͍ͯ͠ͳ͍ 39
  37. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. RESTEasy HTMLͱ͸ʁ !

    JAX-RSͷ࣮૷ʮRESTEasyʯͷಠࣗػೳ ! RESTEasy͸WildFly/JBoss಺แ͕ͩɺ
 RESTEasy HTML͸಺แ͞Ε͍ͯͳ͍ 40
  38. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Jersey MVCͷجຊతͳ࢖͍ํᶃ !

    ApplicationαϒΫϥεʹMvcFeatureΫϥ εΛొ࿥͢Δ 41 @ApplicationPath("/api") public class MyApplication extends ResourceConfig { public MyApplication() { register(MvcFeature.class); property(MvcFeature.TEMPLATE_BASE_PATH, "/WEB-INF/views/"); packages(true, "com.example.rest"); } } jjug-jersey-mvc/src/main/java/com/example/rest/MyApplication.java ※ࣼମ෦෼͕Jersey MVCͷػೳ
  39. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Jersey MVCͷجຊతͳ࢖͍ํᶄ !

    ίϯτϩʔϥʔϝιουͰViewableΛ໭ Γ஋ʹ͢Δ 42 @Path("/employee") public class EmployeeController { @GET @Path("/index") public ThymeleafViewable index(…) { return new ThymeleafViewable( "employee/index.html"); } } ViewableͷαϒΫϥε ͱͯࣗ͠࡞ͨ͠΋ͷ jjug-jersey-mvc/src/main/java/com/example/rest/controller/EmployeeControler.java ※ࣼମ෦෼͕Jersey MVCͷػೳ
  40. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Jersey MVCͷجຊతͳ࢖͍ํᶅ !

    ViewableίϯετϥΫλͷୈ2Ҿ਺Ͱ Ϗϡʔʹ஋Λ౉͢ 43 @Path("/employee") public class EmployeeController { @GET @Path("/result") public ThymeleafViewable result(…) { Map<String, Object> models = … return new ThymeleafViewable( "employee/result.html", models); } ౉͍ͨ͠஋ΛMapʹ put͓ͯ͘͠ jjug-jersey-mvc/src/main/java/com/example/rest/controller/EmployeeControler.java ※ࣼମ෦෼͕Jersey MVCͷػೳ
  41. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Jersey MVCͰThymeleafΛ࢖͏ํ๏ !

    Jersey MVC͕ఏڙ͍ͯ͠Δ TemplateProcessorΠϯλϑΣʔεΛ࣮ ૷͢Δ ! ্هΠϯλϑΣʔεΛ࣮૷ͨ͠ AbstractTemplateProcessorΫϥεΛܧ ঝ͢Δͱศར 44
  42. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Thymeleaf༻TemplateProcessor 45 @Provider

    public class ThymeleafTemplateProcessor extends AbstractTemplateProcessor<String> { private TemplateEngine templateEngine; @Inject public ThymeleafTemplateProcessor( Configuration config, ServletContext sc) { super(config, sc, "html", "html"); ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(sc); … templateEngine = new TemplateEngine(); templateEngine.setTemplateResolver(resolver); } // ࣍΁ଓ͘ jjug-jersey-mvc/src/main/java/com/example/rest /thymeleaf/ThymeleafTemplateProcessor.java ※ࣼମ෦෼͕Jersey MVCͷػೳ
  43. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Thymeleaf༻TemplateProcessor(ଓ͖) 46 //

    ଓ͖ @Override public void writeTo(...) { WebContext webContext = new WebContext( request, response, servletContext, request.getLocale()); Map<String, Object> map = (Map) viewable.getModel(); webContext.setVariables(map); templateEngine.process( viewable.getTemplateName(), webContext, response.getWriter()); } } jjug-jersey-mvc/src/main/java/com/example/rest /thymeleaf/ThymeleafTemplateProcessor.java Thymeleaf͕ ϨεϙϯεΛॻ͖ग़͢ ※ࣼମ෦෼͕Jersey MVCͷػೳ
  44. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Jersey MVCͰόϦσʔγϣϯ !

    @ErrorTemplateͰݕূΤϥʔ࣌ʹ໭ΔϏϡʔΛ ࢦఆͰ͖Δ͕ɾɾɾ ! όϦσʔγϣϯͱྫ֎Λಉ͡ʹѻ͏ͷͰ࢖͍ ͮΒ͍ ! MVC 1.0ʹ͸ແ͍ػೳͳͷͰҠ২ੑ͕ѱ͍ ! όϦσʔγϣϯάϧʔϓ΍άϧʔϓγʔέϯ ε͕࢖͑ͳ͍ 47
  45. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ίϯτϩʔϥʔϝιου಺Ͱ όϦσʔγϣϯ͢Δ 48

    @Inject Validator validator; @GET @Path("/result") public ThymeleafViewable result( @BeanParam EmployeeIdForm form) { Set<ConstraintViolation<EmployeeIdForm>> violations = validator.validate(form); if (!violations.isEmpty()) { Map<String, Object> model = …; model.put("violations", violations); return new ThymeleafViewable( "employee/index.html", model); } Bean ValidationΛ ࣮ߦ͢ΔΠϯλϑΣʔε Ҿ਺ʹ@Valid͸෇͚ͳ͍ ݕূ࣮ߦ Τϥʔ͕͋Ε͹ ೖྗը໘ʹ໭Δ
  46. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Τϥʔϝοηʔδͷදࣔ 49 <ul

    th:if="${violations}"> <li th:each="violation : ${violations}" th:text="${violation.message}"> μϛʔͷϝοηʔδ </li> </ul>
  47. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ͜ͷํ๏ͷϝϦοτɾσϝϦοτ ! ϝϦοτ

    ! ϐϡΞͳJAX-RSίʔυ ! MVC 1.0ʹҠߦ͠΍͍͢ ! ΦϨΦϨϑϨʔϜϫʔΫԽΛ๷͛Δ ! σϝϦοτ ! গʑख͕͔͔ؒΔ 50 ৭ʑͱࢼ͠ߟ͕͑ͨ ݱঢ়͜ͷํ๏͕ϕετ
  48. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ࢀߟɿϦμΠϨΫτ͍ͨ͠৔߹ ! JAX-RSͷίʔυͰॻ͚͹OK

    52 @GET @Path("/redirect") public Response redirect( @Context UriInfo uriInfo) throws Exception { URI location = uriInfo.getBaseUriBuilder() .path(HelloResource.class) .path("redirect2") .build(); return Response.status(Response.Status.FOUND) .location(location).build(); } URIΛ૊ΈཱͯΔ ϝιουΛ࣋ͭ ૊ΈཱͯͨURIΛLocationϔομʹࢦఆ εςʔλείʔυΛ 3xxʹࢦఆ
  49. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. RESTEasy HTMLͷجຊతͳ࢖͍ํᶃ !

    ApplicationαϒΫϥεΛ࡞੒͢Δ ! ಛผͳΫϥεͷొ࿥͸ඞཁͳ͠ ! JAX-RSͷProvidersػೳʹΑΔ΋ͷ 53 @ApplicationPath("/api") public class MyApplication extends Application { } jjug-resteasy-html/src/main/java/com/example/rest/MyApplication.java
  50. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. RESTEasy HTMLͷجຊతͳ࢖͍ํᶄ !

    RenderableΛίϯτϩʔϥʔϝιουͷ ໭Γ஋ʹ͢Δ 54 <<interface>> Renderable ViewΫϥε (ϑΥϫʔυ) RedirectΫϥε (ϦμΠϨΫτ)
  51. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. RESTEasy HTMLͰ ThymeleafΛ࢖͏ํ๏

    ! RenderableΛ࣮૷ͨ͠ΫϥεΛ࡞੒͢Δ 55 <<interface>> Renderable View Redirect ThymeleafView
  52. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Thymeleaf༻Renderableͷ࡞੒ 56 public

    class ThymeleafView implements Renderable { private String templateName; private Map<String, Object> models; private TemplateEngine templateEngine; public ThymeleafView(String templateName) { this(templateName, new HashMap<>()); } public ThymeleafView(String templateName, Map<String, Object> models) { this.templateName = templateName; this.models = models; } void setTemplateEngine(TemplateEngine templateEngine) { this.templateEngine = templateEngine; } RenderableΛ࣮૷ ※ࣼମ෦෼͕RESTEasy HTMLͷػೳ
  53. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Thymeleaf༻Renderableͷ࡞੒(ଓ͖) 57 //

    ଓ͖ @Override public void render(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, WebApplicationException { response.setCharacterEncoding("UTF-8"); WebContext webContext = new WebContext( request, response, request.getServletContext(), request.getLocale()); webContext.setVariables(models); templateEngine.process(templateName, webContext, response.getWriter()); } } render()಺ͰTemplateEngine#process()Λ࣮ߦ ※ࣼମ෦෼͕RESTEasy HTMLͷػೳ
  54. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. TemplateEngineΛηοτ͢Δ Πϯλʔηϓλʔͷ࡞੒ !

    JAX-RSͷWriterInterceptorͰ࡞੒ ! NameBindingΞϊςʔγϣϯΛࣗ࡞ͯ͠ɺ্ هΠϯλʔηϓλʔΛద༻͢Δίϯτϩʔϥʔ ϝιου಺Λࢦఆ ! खஈ͸͜Ε͚ͩͰ͸ͳ͍ͷͰɺ৭ʑࢼͯ͠Έ ͍ͯͩ͘͞ 58
  55. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Ξϊςʔγϣϯͷ࡞੒ 59 @NameBinding

    @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Documented public @interface ThymeleafController { } @NameBindingΛ෇Ճͨ͠ ΞϊςʔγϣϯΛࣗ࡞
  56. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. WriterInterceptorͷ࡞੒ 60 @Provider

    @ThymeleafController public class ThymeleafWriterInterceptor implements WriterInterceptor { private TemplateEngine templateEngine; @Inject private ServletContext sc; @PostConstruct public void init() { ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(sc); resolver.setPrefix("/WEB-INF/views/"); resolver.setTemplateMode(TemplateMode.HTML); templateEngine = new TemplateEngine(); templateEngine.setTemplateResolver(resolver); } ࣗ࡞Ξϊςʔγϣϯ Λ෇Ճ WriterInterceptorΛ࣮૷
  57. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. WriterInterceptorͷ࡞੒(ଓ͖) 61 @Override

    public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException { Object entity = context.getEntity(); if (ThymeleafView.class.isAssignableFrom(entity.getClass())) { ThymeleafView thymeleafView = (ThymeleafView) context.getEntity(); thymeleafView.setTemplateEngine(templateEngine); } context.proceed(); } } context.proceed()ΑΓલʹ TemplateEngineΛηοτ͢Δ
  58. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ίϯτϩʔϥʔϝιου 62 @GET

    @Path("result") @ThymeleafController public ThymeleafView result(…) { Map<String, Object> models = …; models.put("employee", employee); return new ThymeleafView( "employee/result.html", models); } ࣗ࡞ͨ͠ΞϊςʔγϣϯΛ෇Ճ →Πϯλʔηϓλʔ͕ద༻͞ΕΔ Ϗϡʔͷύεͱ౉͢஋Λࢦఆ ※ࣼମ෦෼͕RESTEasy HTMLͷػೳ
  59. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ͜͜·Ͱͷ·ͱΊ ! Java

    EE 7Ͱ͸Jersey MVC·ͨ͸RESTEasy HTMLΛ࢖͏ʂ ! ίϯτϩʔϥʔϝιουɺϏϡʔɺྫ֎ ॲཧ͸΄΅MVC 1.0ͱಉ͡ʂ ! BindingResult͕ແ͍ͷͰɺόϦσʔγϣ ϯ͸ίϯτϩʔϥʔϝιου಺Ͱߦ͏ʂ 64
  60. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. JAX-RS ! MVC

    1.0/Jersey MVC/RESTEasy HTMLࣗମ ͷػೳ͸ଟ͘ͳ͍ ! ΍Γ͍ͨࣄͷ࣮ݱ΍τϥϒϧղܾͷͨΊʹ ͸ɺJAX-RSͷ஌͕ࣝෆՄܽ 66
  61. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. JAX-RSͷࢀߟ৘ใ ! ͏Β͕Έ͞Μͷࢿྉ

    ! ಛʹॲཧύΠϓϥΠϯ͕ॏཁ ! http://backpaper0.github.io/ghosts/ jaxrs-getting-started-and- practice.html#38 ! Java EE 7పఈೖ໳ ! Oracle͞Μͷྗ࡞ʂ 67
  62. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ͦͷଞ ! Bean

    Validation → @opengl_8080͞Μͷϒϩά ! http://qiita.com/opengl-8080/items/ 3926fbde5469c0b330c2 ! CDI → ࣉా͞ΜͷJDT2015ͷࢿྉ ! http://www.oracle.com/technetwork/jp/ondemand/ online2015-javaday-2511676-ja.html ! JPA → JJUG CCC 2015 Springͷࢿྉʢ੿ஶʣ ! http://www.slideshare.net/masatoshitada7/jpa-46874399 68
  63. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ·ͱΊ ! MVC

    1.0 + ThymeleafͰɺStruts/Seasar2 ͱಉ౳ͷػೳΛΑΓ؆୯ʹɺΑΓηΩϡ Ξʹ࣮૷Ͱ͖Δʂ ! EE 7Ͱ͸Jersey MVC or RESTEasy HTMLΛ ࢖͏ʂ ! JAX-RSͷ࢓૊ΈΛཧղ͢Δ͜ͱ͕ॏཁʂ 70
  64. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ஫ҙ఺ ! Jersey

    MVCɾRESTEasy HTML͸
 Java EE 7ඪ४ͷػೳͰ͸ͳ͍ͷͰɺ
 ϕϯμʔαϙʔτର৅֎ͷՄೳੑ͋Γ ! Java EE 7ඪ४ͷൣғ಺Ͱ͸ɺ
 JSF͕།ҰͷHTMLΛฦ͢ϑϨʔϜϫʔΫ 71
  65. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Enjoy Java EE

    !! ! ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ 72