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

MVC 1.0 - by Example @ Devoxx Belgium 2015

MVC 1.0 - by Example @ Devoxx Belgium 2015

Joint presentation with René Gielen

ivargrimstad

November 12, 2015
Tweet

More Decks by ivargrimstad

Other Decks in Programming

Transcript

  1. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    JSR 371
    MVC 1.0 for Java EE 8

    View Slide

  2. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Ivar Grimstad
    Principal Consultant for
    Cybercom Sweden
    JSR 371 Expert Group Member

    View Slide

  3. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    René Gielen
    Independent Software
    Craftsman, Consultant, Trainer
    Apache Struts PMC Chair

    View Slide

  4. @rgielen / @ivar_grimstad
    #Devoxx #JSR371

    View Slide

  5. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Front Controller

    View Slide

  6. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Action

    View Slide

  7. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Request

    View Slide

  8. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Response

    View Slide

  9. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Serious Business

    View Slide

  10. @rgielen / @ivar_grimstad
    #Devoxx #JSR371

    View Slide

  11. @rgielen / @ivar_grimstad
    #Devoxx #JSR371

    View Slide

  12. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Action vs. Component
    Component based
    Complex Stateful Components
    Abstract away Request-Response
    Action based
    Abstract away Technical Details of HTTP
    Stateless
    Embrace Request-Response

    View Slide

  13. @rgielen / @ivar_grimstad
    #Devoxx #JSR371

    View Slide

  14. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Introduction to JSR 371

    View Slide

  15. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Why?

    View Slide

  16. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    https://java.net/downloads/javaee-spec/JavaEE8_Community_Survey_Results.pdf

    View Slide

  17. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    http://glassfish.org/survey

    View Slide

  18. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Action-based MVC

    View Slide

  19. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Existing Java EE Technologies

    View Slide

  20. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    JSR 371 Expert Group

    View Slide

  21. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Key Decisions

    View Slide

  22. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Key Decisions

    View Slide

  23. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Build MVC 1.0 on top of JAX-RS

    View Slide

  24. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Show me the CODE !

    View Slide

  25. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Controllers

    View Slide

  26. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    public class HelloController {
    }
    Controller

    View Slide

  27. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Path(“hello”)
    public class HelloController {
    }
    Controller

    View Slide

  28. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path(“hello”)
    public class HelloController {
    }
    Controller

    View Slide

  29. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Views

    View Slide

  30. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path(“hello”)
    public class HelloController {
    }
    View

    View Slide

  31. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path(“hello”)
    public class HelloController {
    @GET
    public String hello() {
    return “hello.jsp”;
    }
    }
    View

    View Slide

  32. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path(“hello”)
    public class HelloController {
    @GET
    public Viewable hello() {
    return new Viewable(“hello.jsp”);
    }
    }
    View

    View Slide

  33. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path(“hello”)
    public class HelloController {
    @GET
    public Response hello() {
    return Response.status(OK).entity(“hello.jsp”).build();
    }
    }
    View

    View Slide

  34. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path(“hello”)
    public class HelloController {
    @View(“hello.jsp”)
    @GET
    public void hello() {
    }
    }
    View

    View Slide

  35. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @View(“hello.jsp”)
    @Controller
    @Path(“hello”)
    public class HelloController {
    @GET
    public void hello() {
    }
    }
    View

    View Slide

  36. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Models

    View Slide

  37. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @View(“hello.jsp”)
    @Controller
    @Path(“hello”)
    public class HelloController {
    @GET
    public void hello() {
    }
    }
    Model

    View Slide

  38. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Named(“greeting”)
    @RequestScoped
    public class Greeting {
    private String message;
    public void setMessate(String message) {
    this.message = message;
    }
    public void getMessage() { return message; }
    }
    Model

    View Slide

  39. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @View(“hello.jsp”)
    @Controller
    @Path(“hello”)
    public class HelloController {
    @Inject
    private Greeting greeting;
    @GET
    public void hello() {
    greeting.setMessage(“Hello Devoxx!”);
    }
    }
    Model

    View Slide

  40. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    pageEncoding="UTF-8"%>



    MVC 1.0 Hello Demo


    Hello ${greeting.message}


    Model

    View Slide

  41. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @View(“hello.jsp”)
    @Controller
    @Path(“hello”)
    public class HelloController {
    @GET
    public void hello() {
    }
    }
    Model

    View Slide

  42. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @View(“hello.jsp”)
    @Controller
    @Path(“hello”)
    public class HelloController {
    @Inject
    private Models model;
    @GET
    public void hello() {
    model.put(“message”, “Hello Devoxx!”);
    }
    }
    Model

    View Slide

  43. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    pageEncoding="UTF-8"%>



    MVC 1.0 Hello Demo


    Hello ${message}


    Model

    View Slide

  44. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    View Engines

    View Slide

  45. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Bring Your Own View Engine
    BYOVE

    View Slide

  46. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    public interface ViewEngine {
    boolean supports(String view);
    void processView(ViewEngineContext context)
    throws ViewEngineException;
    }
    ViewEngine

    View Slide

  47. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Priority(OUTRAGEOSLY_HIGH)

    @ApplicationScoped

    public class FreemarkerViewEngine extends ViewEngineBase {

    }
    View Engine Conflicts

    View Slide

  48. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Validation

    View Slide

  49. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path("form")
    public class FormController {
    @POST
    public Response formPost(@Valid @BeanParam FormDataBean f) {
    return Response.status(OK).entity(“data.jsp”).build();
    }
    }
    Validation
    ConstraintValidationException
    @Min, @NotNull
    etc.

    View Slide

  50. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    public class FormViolationMapper implements
    ExceptionMapper {
    public Response toResponse(ConstraintViolationException e) {
    Set> s =e.getConstraintViolations();
    // process violations ...
    return Response.status(BAD_REQUEST)
    .entity(“error.jsp”).build();
    }
    }
    Validation

    View Slide

  51. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path("form")
    public class FormController {
    @Inject private BindingResult br;
    @POST
    public Response formPost(@Valid @BeanParam FormDataBean f) {
    if (br.isFailed()) {
    return Response.status(BAD_REQUEST)
    .entity(“error.jsp”).build();
    }
    return Response.status(OK).entity(“data.jsp”).build();
    }
    }
    Validation
    Allows for MVC Error Handling

    View Slide

  52. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Scopes

    View Slide

  53. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Named(“greeting”)
    @RedirectScoped
    public class Greeting {
    private String message;
    public void setMessate(String message) {
    this.message = message;
    }
    public void getMessage() { return message; }
    }
    @RedirectScoped

    View Slide

  54. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    public class HelloController {
    @Inject
    private Greeting greeting;
    @POST
    @Path(“from”)
    public String hello() {
    greeting.setMessage(“Hello Devoxx!”);
    return “redirect:/to“;
    }
    }
    @RedirectScoped
    @RedirectScoped
    @RequestScoped

    View Slide

  55. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    public class HelloController {
    @Inject
    private Greeting greeting;
    @POST
    @Path(“to”)
    public String hello() {
    return “here.jsp“;
    }
    }
    @RedirectScoped
    Same Bean

    View Slide

  56. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Security

    View Slide

  57. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @Controller
    @Path(“csrf”)
    public class HelloController {
    @CsrfValid
    @POST
    public Response post(@FormParam(“greeting") String greet {
    }
    }
    Cross Site Request Forgery

    View Slide

  58. @rgielen / @ivar_grimstad
    #Devoxx #JSR371




    MVC 1.0 Hello Demo




    value="${mvc.csrf.token}"/>



    Cross Site Request Forgery

    View Slide

  59. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Events

    View Slide

  60. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    BeforeControllerEvent
    AfterControllerEvent
    BeforeProcessViewEvent
    AfterProcessViewEvent
    ControllerRedirectEvent
    Currently Supported Events

    View Slide

  61. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    @ApplicationScoped
    public class EventObserver {
    void onBeforeController(@Observes BeforeControllerEvent e) {
    println("URI: " + e.getUriInfo().getRequestURI());
    }
    void onAfterController(@Observes AfterControllerEvent e) {
    println("Controller: " +
    e.getResourceInfo().getResourceMethod());
    }
    }
    Events Example

    View Slide

  62. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Summary

    View Slide

  63. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Project Page
    https://java.net/projects/mvc-spec
    Mailing List
    [email protected]
    Reference Implementation
    https://ozark.java.net

    View Slide

  64. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    JSR 371 - Test Drive

    View Slide

  65. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    How about Real World?

    View Slide

  66. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Real World - Key Questions
    Common Problems Solved for Real World?
    On Par with comparable Servlet-based Frameworks?

    View Slide

  67. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Comparable Frameworks
    Spring MVC
    around since 2005
    “Real World” since 2008 (Spring 2.5 onward)
    today’s leader in Action-Land
    Struts 2
    around since 2004 (WebWork 2)
    “Real World” since 2007 (Struts 2.0.9 onward)
    still widely adopted

    View Slide

  68. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Comparable Frameworks
    Spring MVC
    around since 2005
    “Real World” since 2008 (Spring 2.5 onward)
    today’s leader in Action-Land
    Struts 2
    around since 2004 (WebWork 2)
    “Real World” since 2007 (Struts 2.0.9 onward)
    still widely adopted
    3 Years till getting Real!

    View Slide

  69. @rgielen / @ivar_grimstad
    #Devoxx #JSR371

    View Slide

  70. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Let’s relax a bit…
    JSR 371: „Standing on the Shoulder of Giants“
    JAX-RS / Jersey
    CDI
    Bean Validation
    Interceptors
    Facelets, Thymeleaf, Freemarker, Velocity
    Adds on Top
    Lightweight Top Layer
    Extension Points

    View Slide

  71. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    So - what are these
    “Common Problems“?

    View Slide

  72. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    “Hello MVC”
    is not enough!

    View Slide

  73. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Common Real World Needs
    Scoped DI
    Controller Decoupling
    Controller Testability
    View Technology Flexibility
    VDL Expressiveness
    i18n / l10n
    Form Binding
    Type Conversion
    Declarative Validation
    Message Passing to View
    Post-Redirect-Get
    File Upload
    UI Controls and Theming
    AJAX Support
    Decorator Support
    Cross Cutting Concerns

    View Slide

  74. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Scoped Dependency Injection
    Spring MVC
    Spring DI
    Struts 2
    Supported
    Containers
    Supported Scopes EJB Support
    Spring MVC Spring DI
    Application, Session,
    Request, Redirect,
    Custom
    Yes (Adapter
    Framework)
    Struts 2
    Spring DI, Guice,
    CDI
    Application, Session,
    Request, Redirect,
    Custom
    Yes (CDI)
    JSR 371 / Ozark CDI
    Application,
    Session, Request,
    Redirect, Custom
    Yes

    View Slide

  75. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Controller Decoupling
    Spring MVC
    Spring DI
    Struts 2
    Controllers as
    POJOs
    Coupling to
    Servlet API
    required
    Coupling to
    Servlet API
    supported
    Model
    Abstraction
    Spring MVC Yes No Yes
    Model
    Container,
    Return value
    Struts 2 Yes No Yes
    Controller
    Instance, Value
    Stack
    JSR 371 / Ozark Yes No Yes
    Scoped CDI
    Beans, Model
    Container

    View Slide

  76. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Controller Testing Support
    Spring MVC
    Spring DI
    Struts 2
    Unit Testing Mocking Support
    Integration
    Test Framework
    Spring MVC Easy Easy Spring Test MVC
    Struts 2 Easy Easy
    Struts 2 Test
    Framework
    JSR 371 / Ozark Easy Easy
    No / presumably
    Jersey Test
    Framework

    View Slide

  77. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Supported View Technologies
    Spring MVC
    Spring DI
    Struts 2
    JSP Templating
    DHTML
    Integration
    Others
    Spring MVC Yes
    Thymeleaf,
    Freemarker,
    Velocity, GSP
    Various 3rd
    Party
    Contributions
    JSON, XML,
    JasperReports
    Struts 2 Yes
    Freemarker,
    Velocity,
    Thymeleaf
    jQuery,
    Bootstrap, YUI
    AngularJS
    JSON, XML,
    JasperReports
    JSR 371 / Ozark Yes
    Facelets,
    Freemarker,
    Velocity,
    Thymeleaf
    Handlebars,
    Mustache
    JSON + XML
    (JAX-RS),
    AsciiDoc

    View Slide

  78. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Real Code

    View Slide

  79. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Wrap-up: State of MVC
    Lightweight Layer on Top of well established Technologies
    Easy to extend
    Addresses most Common Needs
    Some Gaps and Glitches
    most can easily addressed by Implementations and Extensions
    some might be gone in the final Specifications

    View Slide

  80. @rgielen / @ivar_grimstad
    #Devoxx #JSR371
    Q & A

    View Slide