Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Getting start Java EE Action-Based MVC with Thymeleaf

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

  • Login to see the comments

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

×