O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Getting start Java EE Action-Based MVC with Thymeleaf

2.622 visualizações

Publicada em

at JJUG CCC (Japan JUG Cross Community Conference)
2016-5-21

Publicada em: Tecnologia
  • Seja o primeiro a comentar

Getting start Java EE Action-Based MVC with Thymeleaf

  1. 1. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Getting Start Java EE Action-Based MVC With Thymeleaf Masatoshi Tada (Casareal ,Inc) JJUG CCC 2016 Spring 2016-5-21(Sat) 1
  2. 2. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. About This Session ! Answer Your Question "Java EE is Useful Framework As Next Struts?" ! View is Thymeleaf ! ! Code on GitHub ! https://github.com/MasatoshiTada/jjug-action-based- mvc ! Sorry, comments are written in Japanese 2
  3. 3. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. About Me ! Masatoshi Tada !Casareal, Inc !GlassFish User Group Japan !Trainer(Java EE/Spring/Swift) !Twitter:@suke_masa 3
  4. 4. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Agenda ① What’s "Action-Based MVC"? ② Getting Start MVC 1.0(EE 8) ③ Using Jersey MVC & RESTEasy HTML in EE 7 ④ Other Java EE Technologies You Should Know ⑤ Final Conclusions 4
  5. 5. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ①What’s "Action-Based MVC"? 5
  6. 6. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. What’s Action-Based MVC? ! Web Framework which focuses HTTP request & response ! Most of framework are Action-Based ! Struts, Spring MVC, … 6
  7. 7. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. What’s Action-Based MVC? 7 View View Controller Model request response Struts developer friendly
  8. 8. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. What’s "Component-Based MVC"? 8 View Backing Bean Model GUI(VB, Android…) developer friendly -> Struts developer Un-Friendly
  9. 9. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Web Framework of Java EE ! JSF ! Responses HTML ! Component-Based ! JAX-RS ! Responses JSON/XML ! Action-Based 9 There’s no Framework which is "Action-Based" and "Responses HTML"
  10. 10. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Java EE Standard Action-Based MVC!! ! Model-View-Controller API (MVC 1.0) ! Java EE 8 (2017 H1) ! Based on JAX-RS 10
  11. 11. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ②Getting Start MVC 1.0 11
  12. 12. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. MVC 1.0 ! MVC 1.0 is Specification ! ≒Set of Interfaces, Annotations, and Exceptions ! Reference Implementation is Ozark ! Set of Implementation Classes of above interfaces 12
  13. 13. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Main Functions of Struts ! Controller ! Validation ! Handling Exception ! View Technology ! Transaction Token 13
  14. 14. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. in MVC 1.0? ! Controller → ⭕ ! Validation → ⭕ ! Handling Exception → ⭕ ! View Technology → ❌ ! Transaction Token → ❌ 14
  15. 15. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Why No View Technologies in MVC? ! Non-Goal 1 of MVC specification
 "Define a new view (template) language and processor." ! Instead, MVC provides integration with many view technologies! 15
  16. 16. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. View Technologies We Can Use in MVC 1.0 ! MVC ! JSP, Facelets ! Ozark ! Thymeleaf, Mustache, Freemarker,
 Handlerbars, Velocity, AsciiDoc, … 16 If you want to use other View, Implement ViewEngine interface
  17. 17. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Problems of JSP and Facelets 17 ! JSP ! Mix of Logic and View ! Sometime Occurs XSS ! Facelets ! Cannot Use All Features in MVC 1.0 ! Bad Compatibility with JavaScript
  18. 18. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Let’s Use Thymeleaf! 18 ! Pure HTML! ! Isolate View and Logic absolutely! ! Good Compatibility with JavaScript! ! Link Expression is very useful! ! Internationalizing message! ! http://www.thymeleaf.org/doc/tutorials/2.1/ usingthymeleaf.html#a-multi-language-welcome
  19. 19. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Using Thymeleaf in MVC 1.0 19 <dependency> <groupId>org.glassfish.ozark.ext</groupId> <artifactId>ozark-thymeleaf</artifactId> <version>1.0.0-m02</version> <scope>compile</scope> </dependency> ! Just adding dependency like below
  20. 20. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Why No Transaction Token Feature? ! In Expert Group’s Mailing-List, 
 "This is a client side concern" ! https://java.net/projects/mvc-spec/lists/ jsr371-experts/archive/2015-07/message/2 ! Spring MVC has no transaction token feature, too. 20
  21. 21. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. How to Avoid Double-Submit-Problem ! See TERASOLUNA Guideline ! http://terasolunaorg.github.io/guideline/ 5.1.0.RELEASE/en/ArchitectureInDetail/ DoubleSubmitProtection.html 21
  22. 22. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Preparation : Enabling JAX-RS 22 @ApplicationPath("/api") public class MyApplication extends Application { } Inherit Application class Add Annotation jjug-mvc10/src/main/java/com/example/rest/MyApllication.java
  23. 23. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Basic Controller 23 @Path("/employee") public class EmployeeController { @GET @Path("/index") @Controller public String index() { return "employee/index.html"; } } Path of View (extention is REQUIRED) Indicate as controller method Mapping to URL & HTTP method ※Italic is feature of MVC jjug-mvc10/src/main/java/com/example/rest/controller/EmployeeController.java
  24. 24. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Form Class 24 public class EmployeeIdForm { @QueryParam("id") @NotBlank @Pattern(regexp = "[1-9][0-9]*") private String id; // setter/getter } Mapping to "id" Query Parameter Constraint of Bean Validation jjug-mvc10/src/main/java/com/example/rest/form/EmployeeIdForm.java
  25. 25. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Send Object to View 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"; } Box of Object (Map + Iterator) Object referred by View jjug-mvc10/src/main/java/com/example/rest/controller/EmployeeController.java ※Italic is feature of MVC
  26. 26. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Referring Object in View 26 <table th:unless="${employee == null}"> <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 is view folder jjug-mvc10/src/main/webapp/WEB-INF/views/employee/result.html Name put to Models
  27. 27. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Validation 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"; // To input view Box of Messages Enable Validation Error Processing jjug-mvc10/src/main/java/com/example/rest/controller/EmployeeController.java ※Italic is feature of MVC
  28. 28. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Showing Error Messages 28 <ul th:if="${bindingResult != null}"> <li th:each="message : ${bindingResult.allMessages}" th:text="${message}"> This is Dummy Message </li> </ul> Get Messages From BindingResult jjug-mvc10/src/main/webapp/WEB-INF/views/employee/index.html
  29. 29. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Writing Error Messages ! Write messages in 
 src/main/resources/ ValidationMessages.properties ! Specify Key of Message to "message" attribute in Annotation 29
  30. 30. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Specifying Error Message Key 30 public class EmployeeIdForm { @QueryParam("id") @NotBlank(message = "{id.notblank}") @Pattern(regexp = "[1-9][0-9]*", message = "{id.pattern}") private String id; // setter/getter Key of Message with "{}" jjug-mvc10/src/main/java/com/example/rest/form/EmployeeIdForm.java
  31. 31. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Caution : MVC has No "Form-Binding" Feature ! @BeanParam is not "Form-Binding" ! On error, If You want to leave values in input-components on view, Write view as Next 31
  32. 32. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Implementing Form-Binding 32 <form action="./result" method="get"> <input type="text" name="id" value="" th:value="${param.id == null} ? '' : ${param.id[0]}"/> <input type="submit" value="search"/> </form> jjug-mvc10/src/main/webapp/WEB-INF/views/employee/index.html Maybe Complex with selectbox …
  33. 33. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Handling Exception ! Implement ExceptionMapper interface ! When error occurs, ExceptionMapper catches Exception ! You can implement multiple ExceptionMappers 33
  34. 34. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ExceptionMapper class 34 @Provider public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<Exception> { public Response toResponse( Exception exception) { // Forward to Error View… } } Don’t Forget @Provider Catches Exception as Method Argument Implement ExceptionMapper
  35. 35. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Other Features of MVC ! Security (XSS, CSRF) ! File Upload, Download ! MvcContext (Easy Specifying URL) ! Hybrid Class (HTML and REST) ! More Details, See GUGJ Slides below ! http://www.slideshare.net/masatoshitada7/java-ee-8mvc-10 35
  36. 36. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Conclusions of this chapter ! MVC 1.0 + Thymeleaf covers almost features of Struts! ! Need to implement Transaction Token and Form-Binding By Yourself ! Features of MVC are Simple, Reveraging existing Java EE Features. 36
  37. 37. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ③Using Jersey MVC & RESTEasy HTML in EE 7 37
  38. 38. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. What framework should we use in Java EE 7? ! MVC 1.0 is Java EE 8 ! Java EE 8 will be released in 2017 H1 38 Let’s use Jersey MVC or RESTEasy HTML in EE7!
  39. 39. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. What’s Jersey MVC? ! Original Extension of Jersey(JAX-RS RI) ! Similar to MVC 1.0 ! GlassFish/Payara inside ! WebLogic not inside 39
  40. 40. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. What’s RESTEasy HTML? ! Original Extension of RESTEasy (other implementation of JAX-RS) ! RESTEasy is inside WildFly/JBoss,
 but RESTEasy HTML is not inside 40
  41. 41. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Basic Jersey MVC ! Register MvcFeature class to Your Application sub class (ResourceConfig is Convinient) 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 ※Italic is Jersey MVC’s feature
  42. 42. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Basic Jersey MVC ! Return Viewable in controller methods 42 @Path("/employee") public class EmployeeController { @GET @Path("/index") public ThymeleafViewable index(…) { return new ThymeleafViewable( "employee/index.html"); } } My original class (Viewable’s subclass) jjug-jersey-mvc/src/main/java/com/example/rest/controller/EmployeeControler.java ※Italic is Jersey MVC’s feature
  43. 43. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Basic Jersey MVC ! Add value to Viewable constructor’s 2nd parameter 43 @Path("/employee") public class EmployeeController { @GET @Path("/result") public ThymeleafViewable result(…) { Map<String, Object> models = … return new ThymeleafViewable( "employee/result.html", models); } Put objects to Map jjug-jersey-mvc/src/main/java/com/example/rest/controller/EmployeeControler.java ※Italic is Jersey MVC’s feature
  44. 44. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. How to Use Thymeleaf with Jersey MVC ! Implment TemplateProcessor interface (Provided by Jersey) ! AbstractTemplateProcessor class is useful ! implementation of TemplateProcessor 44
  45. 45. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ThymeleafTemplateProcessor 45 @Provider public class ThymeleafTemplateProcessor extends AbstractTemplateProcessor<String> { private TemplateEngine templateEngine; @Inject public ThymeleafTemplateProcessor( Configuration config, ServletContext servletContext) { super(config, servletContext, "html", "html"); TemplateResolver templateResolver = new ServletContextTemplateResolver(); templateResolver.setPrefix((String) config.getProperty( MvcFeature.TEMPLATE_BASE_PATH)); templateEngine = new TemplateEngine(); templateEngine.setTemplateResolver(templateResolver); } // to next slide jjug-jersey-mvc/src/main/java/com/example/rest /thymeleaf/ThymeleafTemplateProcessor.java ※Italic is Jersey MVC’s feature
  46. 46. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ThymeleafTemplateProcessor 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 write the response ※Italic is Jersey MVC’s feature
  47. 47. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Validation in Jersey MVC ! Jersey provides @ErrorTemplate annotation to specify error view, but… ! This annotation is feature for handling exception (not for validation) ! MVC 1.0 doesn’t have similar feature, so migration will be difficult ! Cannot use "Validation Group" and "Group Sequence" (Features of Bean Validation) 47
  48. 48. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Validate in Controller Methods 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); } Execute Bean Validation No @Valid to arguments Validate On error, return to input view
  49. 49. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Showing Error Message 49 <ul th:if="${violations != null}"> <li th:each="violation : ${violations}" th:text="${violation.message}"> This is Dummy Message </li> </ul>
  50. 50. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. About This Method ! Advantage ! Pure JAX-RS code ! Easy MVC 1.0 migration ! Avoid excess framework customization ! Disadvantage ! It takes time and effort 50 I Tried a variety of methods, this method is best
  51. 51. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Handling Exception ! ExceptionMapper ! Same to MVC 1.0 sample code 51
  52. 52. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Redirect ! 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(); } UriInfo has variety of method to build URI Specify URI to Location header Status code 3xx
  53. 53. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Basic RESTEasy HTML ! Create Application’s sub class ! No need to register any specific class ! By JAX-RS "Providers" 53 @ApplicationPath("/api") public class MyApplication extends Application { } jjug-resteasy-html/src/main/java/com/example/rest/MyApplication.java
  54. 54. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Basic RESTEasy HTML ! Return Renderable in controller method 54 <<interface>> Renderable View class (Forward) Redirect class (Redirect)
  55. 55. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Using Thymeleaf in RESTEasy HTML ! Create Renderable implementation class 55 <<interface>> Renderable View Redirect ThymeleafView
  56. 56. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ThymeleafView 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; } Implement Renderable ※Italic is RESTEasy HTML feature
  57. 57. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ThymeleafView 57 // from previous slide @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()); } } Call TemplateEngine#process() in render() ※Italic is RESTEasy HTML feature
  58. 58. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Creating Interceptor Setting TemplateEngine to ThymeleafView ! Use JAX-RS WriterInterceptor ! Create custom annotation with NameBinding, to specify which controller apply interceptor ! There’re many ways(This is not only way) 58
  59. 59. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Creating annotation 59 @NameBinding @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Documented public @interface ThymeleafController { } Create annotation with @NameBinding
  60. 60. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Creating WriterInterceptor 60 @Provider @ThymeleafController public class ThymeleafWriterInterceptor implements WriterInterceptor { private TemplateEngine templateEngine; @PostConstruct public void init() { TemplateResolver resolver = new ServletContextTemplateResolver(); resolver.setPrefix("/WEB-INF/views/"); templateEngine = new TemplateEngine(); templateEngine.setTemplateResolver(resolver); } Specify annotation you created Implement WriterInterceptor
  61. 61. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Creating 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(); } } Set TemplateEngine before context.proceed()
  62. 62. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Controller 62 @GET @Path("result") @ThymeleafController public ThymeleafView result(…) { Map<String, Object> models = …; models.put("employee", employee); return new ThymeleafView( "employee/result.html", models); } Specify annotation →Applying interceptor View path and values ※Italic is RESTEasy HTML feature
  63. 63. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Validation and Handling Exception ! Same as Jersey MVC sample code 63
  64. 64. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Conclusions of this chapter ! In Java EE 7, 
 Use Jersey MVC or RESTEasy HTML! ! Controller methods, views and handling exceptions are same as MVC 1.0! ! They have no BindingResult, so validate in controller methods! 64
  65. 65. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ④Other Java EE Technologies You Should Know 65
  66. 66. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. JAX-RS ! Specific features of MVC 1.0/Jersey MVC/ RESTEasy HTML are not many ! To achieve what you want to do, and trouble-shooting, knowledge of JAX-RS is very important 66
  67. 67. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. JAX-RS Reference ! JSR-339 JAX-RS 2.0 rev.A ! You should learn Processing Pipeline
 (Appendix C) ! https://jcp.org/en/jsr/detail?id=339 ! Jersey Document ! RESTEasy Document 67
  68. 68. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Others ! Bean Validation ! CDI ! JPA 68
  69. 69. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. ⑤Final Conclusions 69
  70. 70. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Final Conclusions ! MVC 1.0 + Thymeleaf covers almost features of Struts! ! In EE 7, Use Jersey MVC or RESTEasy HTML! ! Understanding JAX-RS is very important! 70
  71. 71. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Caution ! Jersey MVC and RESTEasy HTML are 
 NOT "Java EE 7 standard" ! They will be out of range 
 of server vendors’ support ! In "Java EE 7 standard", 
 JSF is the ONLY HTML Framework 71
  72. 72. #ccc_cd4 (C) CASAREAL, Inc. All rights reserved. Enjoy Java EE!! ! Thank you! 72

×