MVC 1.0 - by Exampledevelopermarch.com/developersummit/2016/report/... · Spring MVC around since...
Transcript of MVC 1.0 - by Exampledevelopermarch.com/developersummit/2016/report/... · Spring MVC around since...
MVC 1.0 - by Example
Ivar Grimstad Principal Consultant, Cybercom Sweden
JCP Expert Group Member (JSRs 368, 371, 375)
@ivar_grimstad
https://github.com/ivargrimstad
https://www.linkedin.com/in/ivargrimstad
http://lanyrd.com/profile/ivargrimstad/
MVC
Why?
https://java.net/downloads/javaee-spec/JavaEE8_Community_Survey_Results.pdf
http://glassfish.org/survey
JSR 371 - MVC 1.0
JSR 371 Expert Group
Action-based MVC
Controller
Model View
Request
UpdateUpdate
Get
Controller
Model View
Request
UpdateUpdate
Get
Component-based MVC
Controller
Model View
Request
UpdateUpdate
Get
Action-based MVC
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
Existing Java EE Technologies
Key Decisions
Key Decisions
Build MVC 1.0 on top of JAX-RS
Controllers
publicclassHelloController{
}
Controller
@Path(“hello”)publicclassHelloController{
}
Controller
@Controller@Path(“hello”)publicclassHelloController{
}
Controller
Views
@Controller@Path(“hello”)publicclassHelloController{
}
View
@Controller@Path(“hello”)publicclassHelloController{
@GETpublicStringhello(){return“hello.jsp”;}}
View
@Controller@Path(“hello”)publicclassHelloController{
@GETpublicViewablehello(){returnnewViewable(“hello.jsp”);}}
View
@Controller@Path(“hello”)publicclassHelloController{
@GETpublicResponsehello(){returnResponse.status(OK).entity(“hello.jsp”).build();}}
View
@Controller@Path(“hello”)publicclassHelloController{
@View(“hello.jsp”)@GETpublicvoidhello(){}}
View
@View(“hello.jsp”)@Controller@Path(“hello”)publicclassHelloController{
@GETpublicvoidhello(){}}
View
Models
@Named(“greeting”)@RequestScopedpublicclassGreeting{
privateStringmessage;publicvoidsetMessage(Stringmessage){this.message=message;}
publicvoidgetMessage(){returnmessage;}}
Model
@View(“hello.jsp”)@Controller@Path(“hello”)publicclassHelloController{
@GETpublicvoidhello(){}}
Model
@View(“hello.jsp”)@Controller@Path(“hello”)publicclassHelloController{
@InjectprivateGreetinggreeting;@GETpublicvoidhello(){greeting.setMessage(“HelloBengaluru!”);}}
Model
<%@page contentType=“text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <title>MVC 1.0 Hello Demo</title> </head> <body> <h1>Hello ${greeting.message}</h1> </body> </html>
Model
@View(“hello.jsp”)@Controller@Path(“hello”)publicclassHelloController{
@GETpublicvoidhello(){}}
Model
@View(“hello.jsp”)@Controller@Path(“hello”)publicclassHelloController{
@InjectprivateModelsmodel;@GETpublicvoidhello(){model.put(“message”,“HelloBengaluru!”);}}
Model
<%@page contentType=“text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <title>MVC 1.0 Hello Demo</title> </head> <body> <h1>Hello ${message}</h1> </body> </html>
Model
Validation
@Controller@Path("form")publicclassFormController{
@POSTpublicResponseformPost(@Valid@BeanParamFormDataBeanf){
returnResponse.status(OK).entity(“data.jsp”).build();}}
ConstraintValidationException
@Min, @NotNulletc.
Validation
publicclassFormViolationMapperimplementsExceptionMapper<ConstraintViolationException>{
publicResponsetoResponse(ConstraintViolationExceptione){
//processviolations…
returnResponse.status(BAD_REQUEST).entity(“error.jsp”).build();}}
Validation
@Controller@Path("form")publicclassFormController{
@InjectprivateBindingResultbr;
@POSTpublicResponseformPost(@Valid@BeanParamFormDataBeanf){if(br.isFailed()){returnResponse.status(BAD_REQUEST).entity(“error.jsp”).build();}returnResponse.status(OK).entity(“data.jsp”).build();}}
Allows for MVC Error Handling
Validation
Security
@Controller@Path(“csrf”)publicclassHelloController{
@CsrfValid@POSTpublicResponsepost(@FormParam(“greeting")Stringgreet{}}
Cross Site Request Forgery
<%@page contentType=“text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <title>MVC 1.0 Hello Demo</title> </head> <body> <form action="csrf" method="post" accept-charset="utf-8"> <input type="submit" value="Click here"/> <input type="hidden" name="${mvc.csrf.name}" value="${mvc.csrf.token}"/> </form> </body> </html>
Cross Site Request Forgery
Scopes
@Named(“greeting”)@RedirectScopedpublicclassGreeting{
privateStringmessage;publicvoidsetMessage(Stringmessage){this.message=message;}
publicvoidgetMessage(){returnmessage;}}
@RedirectScoped
@ControllerpublicclassHelloController{
@InjectprivateGreetinggreeting;@POST@Path(“from”)publicStringhello(){greeting.setMessage(“HelloJavaLand!”);return“redirect:to“;}}
@RedirectScoped
@RequestScoped
@RedirectScoped
@ControllerpublicclassHelloController{
@InjectprivateGreetinggreeting;@POST@Path(“to”)publicStringhello(){return“here.jsp“;}}
Same Bean
@RedirectScoped
Tired of slides?
Show me the real CODE !
Model
ReservationCtlUpdate
confirmation
reservation
OK
Browser
POST
Model
ReservationCtl
Access
Update
ConfirmationCtl
GET
confirmation
reservation
OK
Redirect
Browser
POST
View Engines
Bring Your Own View Engine
publicinterfaceViewEngine{
booleansupports(Stringview);
voidprocessView(ViewEngineContextcontext)throwsViewEngineException;}
ViewEngine
@Priority(OUTRAGEOSLY_HIGH)@ApplicationScopedpublicclassFreemarkerViewEngineextendsViewEngineBase{…
}
ViewEngine
Events
BeforeControllerEventAfterControllerEvent
BeforeProcessViewEventAfterProcessViewEvent
ControllerRedirectEvent
@ApplicationScopedpublicclassEventObserver{
voidonBeforeController(@ObservesBeforeControllerEvente){}voidonAfterController(@ObservesAfterControllerEvente){}}
Events Example
Tool Support
Summary
Action-based MVC
Existing Java EE Technologies
Build MVC 1.0 on top of JAX-RS
Project Page https://java.net/projects/mvc-spec
GitHub https://github.com/mvc-spec
Reference Implementation https://ozark.java.net
Samples https://github.com/ivargrimstad/mvc-samples
Blog http://www.agilejava.eu/