View
34
Download
1
Category
Preview:
DESCRIPTION
Spring Web MVC. Ievads. Spring i r atklāta koda Java/J2EE aplikāciju ietvars Viens no interesantākiem komponentiem ir Spring Web MVC. Web aplik āciju uzdevumi. Svarīgie uzdevumi, kuri ir jāatrisina izstrādājot web aplikāciju : Stāvokļu pārvaldība (s tate management ) - PowerPoint PPT Presentation
Citation preview
Spring Web MVC
Ievads• Spring ir atklāta koda Java/J2EE aplikāciju ietvars
• Viens no interesantākiem komponentiem ir Spring Web MVC
Web aplikāciju uzdevumi• Svarīgie uzdevumi, kuri ir jāatrisina
izstrādājot web aplikāciju:• Stāvokļu pārvaldība (state management)• Darba plūsma (workflow)• Validācija
• Spring web ietvars ir uzprojektēts, lai palīdzet izstrādātājiem risināt šīs problēmas
Model-View-Controller Pattern• Model-View-Controller (MVC) ir arhitektūras
paraugs (aprakstīts 1979. gadā, Smalltalk valodā)
• Pamata mērķis: atdalīt datus (Model) no
lietotāja interfeisa (View)
• MVC atrisina
problēmu ieviešot
starpnieka komponenti - kontrolieri (Controller)
Model-View-Controller Pattern• Model - Represents enterprise data and the business rules.
• View - Renders the contents of a model. Accesses enterprise data through the model and specifies how that data should be presented.
• Controller - Translates interactions with the view (button clicks, menu selections) into actions to be performed by the model (activating processes, changing the state of the model).
Spring MVC• Spring MVC sastāv no vairākiem komponentiem,
starp kuriem notiek sadarbība apstrādājot klienta pieprasījumu
Pieprasījuma dzīves cikls (1)• Klients sūta pieprasījumu, kurš tiek nodots
DispatcherServlet komponentam
• Visi pieprasījumi vienmēr tiek nodoti vienam servletam,
kuru sauc par
priekšējo kontrolieri
(front controller)
Pieprasījuma dzīves cikls (2)• Komponents, kurš atbild par pieprasījuma apstrādi ir
Controller
• Lai nolemt kuram kontrolierim atdot
pieprasījumu, DispatcherController
izmanto
HandlerMapping
komponentus
• HandlerMapping:
URL piesaistīšana kontrolieriem
Pieprasījuma dzīves cikls (3-4)• Kad DispatcherServlet nolemj par kontroliera
objektu, tad parsūta tam pieprasījumu, lai kontrolieris izpilda biznesa loģiku
• Pēc darba pabeigšanas Controller atgriež ModelAndView objektu
• ModelAndView saturView objektu vaiskata loģisko vārdu
Pieprasījuma dzīves cikls (5)• Ja ModelAndView objekts satur skata loģisko
vārdu, tad DispatcherServlet izmanto ViewResolver komponenti
• ViewResolver
atrod atbilstošu
View objektu,
lai attēlot atbildi
klientam
Pieprasījuma dzīves cikls (6)• Visbeidzot, DispatcherServlet atdod pieprasījumu
tam View objektam, uz kuru norāda ModelAndView
• View objekts ir atbildīgs par pieprasījumaatbildes atgriešanu un parādīšanu klientam
Spring MVC Sequence Diagram
Front Controller• At the heart of Spring MVC is
DispatcherServlet, a servlet that functions as front controller
• A front controller is a common web-application pattern where a single servlet delegates responsibility for a request to other components of an application to perform the actual processing
DispatcherServlet config• Jākonfigurē web aplikācijas web.xml failā:
<servlet> <servlet-name>training</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup></servlet>
• Nākamais solis ir nodefinēt servlet mapping:
<servlet-mapping><servlet-name>training</servlet-name><url-pattern>*.htm</url-pattern>
</servlet-mapping>
DispatcherServlet context• WebApplicationContext tiek ielādēts no faila:
training-servlet.xml
kurš atrodas direktorijā WEB-INF (līdzīgi web.xml failam)
• Ir iespējams arī sadalīt
konfigurāciju starp
vairākiem failiem
Vienkāršas Web lapas izveidošana• Nepieciešamie soļi, lai izveidot web lapu ar
Spring MVC:
1. Uzrakstīt kontroliera klasi, kas izpildīs biznesa loģiku
2. Iekonfigurēt kontrolieri DispatcherServlet konteksta konfigurācijas failā (training-servlet.xml)
3. Iekonfigurēt view resolver, kurš piesaistīs kontrolieri pie JSP
4. Uzrakstīt JSP, kas attēlos lapu klientam
Kontroliera izveidošanapublic class HomeController implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("home", "message", greeting); }
private String greeting; public void setGreeting(String greeting) { this.greeting = greeting; }}
• Nodarbojas ar pieprasījuma apstrādāšanu• Pamata metodes signatūra ir līdzīga servleta service() metodei• Atgriež ModelAndView objektu
Kontroliera konfigurēšana• Kontrolieri ir jāieraksta DispatcherServlet
konteksta konfigurācijas failā:<bean name="/home.htm" class="com.springinaction.training.mvc.HomeController"><property name="greeting"> <value>Welcome to Spring Training!</value></property></bean>
• The default handler mapping is BeanNameUrlHandlerMapping, which uses the base name as the URL pattern
• When a request comes with a URL that ends with “/home.htm”, DispatcherServlet will dispatch the request to HomeController
View Resolver deklarēšana• View resolver darbs ir pēc skata loģiska vārda (kurš ir
atgriezts ModelAndView objektā) atrast pašu skatu
• Viens no variantiem ir izmantot skata vārdu kā JSP faila vārdu:<bean id="viewResolver" class="org.springframework.web.
servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property></bean>
“home” /WEB-INF/jsp/home.jsp
JSP izveidošana• Pēdējais kas palika – izveidot pašu JSP
<html><head><title>Spring Training, Inc.</title></head><body><h2>${message}</h2></body></html>
• Failu ir jānosauc par “home.jsp” un ir jānoliek zem /WEB-INF/jsp/ direktorijas
Kopsavilkums
HandlerMapping• Tipiski piesaista specifisku kontrolieri pie
URL adreses parauga
• Spring piedāvā četras noderīgas HandlerMapping implementācijas
• BeanNameUrlHandlerMapping
• SimpleUrlHandlerMapping
• CommonsPathMapHandlerMapping
BeanNameUrlHandlerMapping• Piesaista URL adresi pie kontroliera, kurš ir
reģistrēts konfigurācijas failā ar tādu pašu vārdu• e.g. /simple.htm maps to a bean named “/simple.htm”
• Ir jāizmanto name atribūtu, jo “/” nav atļauts XML atribūtā id
<bean class="org.springframework.web.servlet. handler.BeanNameUrlHandlerMapping"/>
<bean name="/simple.htm" class="com.mvc.web.SimpleController">. . .</bean>
SimpleUrlHandlerMapping• Pats vispārīgs veids kā piesaistīt pieprasījuma
URLus kontrolieriem
• Tiek konfigurēts kā saraksts no name/value pāriem (URL/kontrolieru vārds)
<bean id="simpleUrlMapping" class="org.springframework.web .servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings"> <props> <prop key="/listCourses.htm">listCoursesController</prop> <prop key="/register.htm">registerStudentController</prop> <prop key="/displayCourse.htm">displayCourseController</prop> </props> </property></bean>
CommonsPathMapHandlerMapping• Considers source-level metadata placed in a controller’s
source code to determine the URL mapping
• Need to set up build to
include the Commons
Attributes compiler so
that the attributes will
be compiled into
application code
<bean id="urlMapping" class="org.springframework.web.servlet.handler.metadata.CommonsPathMapHandlerMapping"/>
/** @@org.springframework.web.servlet. handler.commonsattributes.PathMap(
"/displayCourse.htm")*/public class DisplayCourseControllerextends AbstractCommandController {…}
Multiple handler mappings• Ir iespējams deklarēt vairākus handler
mappings vienā aplikācijā
• Handler mapping klases implementē Spring’a Ordered interfeisu
• Var uzstādīt order īpašību, lai norādīt izpildes kārtību attiecībā uz citiem handler mapping komponentiem
Multiple handler mappings<bean id="beanNameUrlMapping"
class="org.springframework.web.
servlet.handler.BeanNameUrlHandlerMapping"> <property name="order"><value>1</value></property></bean>
<bean id="simpleUrlMapping" class="org.springframework.web.
servlet.handler.SimpleUrlHandlerMapping"> <property name="order"><value>0</value></property> <property name="mappings"> … </property></bean>
Kontrolieri• Ja DispatcherServlet ir Spring MVC
sirds, tad kontrolieri ir smadzenes
Kontrolieru hierarhija• Spring piedāvā
bagātu kontrolieruhierarhiju
• Hierarhijas virsotnē atrodas Controller interfeiss
• Parasti ir jāizmantokādu no implementācijas apakšklasēm
AbstractController• Pats vienkāršākais kontrolieris
public class SampleController extends AbstractController {
public ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView("hello“, “message”, "Hello World!");
}}
ModelAndView objekts• Iekapsulē skatu un modeļa datus, kurus skats attēlos
• Modelis ir realizēts kā java.util.Map
• Ērts konstruktors viena modeļa objekta gadījumam:
ModelAndView(
String viewName,
String modelName,
Object modelObject)
ModelAndView objekts• Ir iespējams arī pievienot modelim
vairākus objektus:
public ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView(“welcome"); mav.addObject("message1", “Welcome!"); mav.addObject("message2", "Nice to see you!"); return mav; }
Parametru apstrāde• Web pieprasījums bieži satur vienu vai vairākus
parametrus
Kādā veidā varētu piekļūt parametriem kontroliera kodā???
<form action="/login" method="POST"> Login: <input id=“login" name="login"/> Password: <input id="password" name="password" type="password"/> <input type="submit" value="Login"/></form>
Risinājums• Varētu izmantot AbstractController un
nolasīt parametrus no HttpServletRequest
public ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception {
String login = request.getParameter("login"); String pass = request.getParameter("password"); . . .}
Spring piedāvā ērtāku iespēju!
AbstractCommandController• Automātiski ieraksta parametrus speciālajā
komandas objektā (command object)
• Ir iespēja pievienot validatoru, lai nodrošināt to, ka parametri ir pareizi
• Galvenā izpildes metode:
handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)
AbstractCommandController
public class DisplayCourseController extends AbstractCommandController {
public DisplayCourseController() { setCommandClass(DisplayCourseCommand.class);}
protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response, Object command,BindException errors) throws Exception {
DisplayCourseCommand displayCommand =(DisplayCourseCommand) command;
Course course = courseService.getCourse(displayCommand.getId()); return new ModelAndView("courseDetail", "course", course);}
Command Object• A command object is a bean that is meant
to hold request parameters for easy access
public class DisplayCourseCommand {private Integer id;public void setId(Integer id) {
this.id = id;}public Integer getId() {
return id;}
}
• Spring will attempt to match any parameters passed in the request to properties in the command object
Pārskats
Formu apstrāde• Tipiska web aplikācija satur vismaz vienu formu
• Lietotājs aizpilda formu un aizsūta to• Dati tiek nosūtīti serverim• Kad datu apstrāde ir pabeigta, tad lietotājs
saņem vienu no variantiem:• Lapa ar veiksmīgas izpildes paziņojumu• Formas lapa ar kļūdu paziņojumiem
Kādā veidā varētu to realizēt???
Risinājums• Izmantot AbstractController formas
attēlošanai• Izmantot AbstractCommandController
formas apstrādei
• Trūkums: vajag uzturēt divus dažādus kontrolierus, kuri kopā nodarbojas ar viena uzdevuma risināšanu
SimpleFormController• Formu kontroliera funkcionalitāte:
• Attēlo formu uz HTTP GET pieprasījuma• Apstrādā formu uz HTTP POST pieprasījuma• Ja notiek kļūda, tad atkārtoti parāda formupublic class RegisterStudentControllerextends SimpleFormController {
public RegisterStudentController() {setCommandClass(Student.class);
}protected void doSubmitAction(Object command)throws Exception {
Student student = (Student) command;studentService.enrollStudent(student);
}}
SimpleFormController config• Kontrolieris ir uzprojektēts tādā veidā, lai pēc iespējas
vairāk atdalīt skatu detaļas no kontroliera koda<bean id="registerStudentController" class="com.springinaction.
training.mvc.RegisterStudentController"> <property name="formView">
<value>newStudentForm</value> </property> <property name="successView">
<value>studentWelcome</value> </property> . . .</bean>
HTTP GET
• Ja ir nepieciešams aizsūtīt datus skatam, tad vajag izmantot onSubmit() metodi
Formu validācija• Viens no svarīgiem uzdevumiem ir formas datu
validācija
• Par validāciju atbild sekojošais interfeisspublic interface Validator { void validate(Object obj, Errors errors); boolean supports(Class clazz);}
• Implementējot šī interfeisa validate() metodi vajag pārbaudīt objekta atribūtu vērtības un noraidīt nepareizas vērtības izmantojot Errors objektu
Validatora reģistrēšana• Validatoru vajag piesaistīt kontrolierim
konfigurācijas failā
<bean id="registerStudentController" class="com.springinaction.training.mvc.
RegisterStudentController">… <property name="validator"> <bean class="com.springinaction.training.
mvc.StudentValidator"/> </property></bean>
Wizard (daudzekrānu) formas
• Uzdevums – realizēt aptaujas formu ar 40 jautājumiem
• Variants – izmantot SimpleFormController, izvietot visus jautājumus vienā lapā
• Bet tas nav ērti lietotājam!
Kādā veidā varētu to realizēt???
Wizard formas• Spring piedāvā kontrolieri, kas atbild par secīgu
virzīšanos cauri vairākām lapām
AbstractWizardFormController
• Līdzīgs parastai formai, bet ir iespējams validēt datus pa daļām (katrā ekrānā savu daļu)
• Formas apstrāde parasti notek pašās beigās
• Ir iespēja visu procesu atcelt (cancel) jebkurā brīdī
Wizard formas kontrolierispublic class FeedbackWizardController
extends AbstractWizardFormController {
public FeedbackWizardController() {setCommandClass(FeedbackSurvey.class);
}
protected ModelAndView processFinish(HttpServletRequest request,HttpServletResponse response, Object command,BindException errors) throws Exception {
FeedbackSurvey feedback = (FeedbackSurvey) command;feedbackService.submitFeedback(feedback);return new ModelAndView("thankyou");
}
Wizard formas konfigurēšana
• Formas kontroliera konfigurēšana
<bean id="feedbackController" class="com.springinaction.training.mvc.MyWizardController">
<property name="pages"> <list> <value>general</value> <value>instructor</value> <value>course</value> </list></property></bean>
• Šeit tiek definētas visas lapas
Wizard formas lapas• Pa lapām var pārvietoties ierakstot
pieprasījumā parametru ar vārdu "_targetX", kur X ir lapas numurs
<form method="POST" action="feedback.htm">…<input type="submit" value="Back" name="_target1"> <input type="submit" value="Next" name="_target3"></form>
Wizard formas finish/cancel• Formas pabeigšana - tiks izsaukta metode processFinish()
<input type="submit" value="Finish" name="_finish">
• Formas atcelšana - tiks izsaukta metode processCancel()
<input type="submit" value="Cancel" name="_cancel">
Wizard formas validācija• Formas komandas objekts tiek validēts pa
lapām
protected void validatePage(Object command, Errors errors, int page) {
FeedbackSurvey feedback = (FeedbackSurvey) command;FeedbackValidator validator =
(FeedbackValidator) getValidator();if(page == 0) { validator.validateEmail(feedback.getEmail(), errors);}}
Vairāku darbību apstrāde• Visi līdz šīm apskatītie kontrolieri pildīja kādu vienu
uzdevumu• Veidot vairākus kontrolierus lai pildīt līdzīgus uzdevumus
nav īsti racionāli• Piemērām, vajag attēlot kursu sarakstu dažādos variantos:
• Nesakārtotā veidā• Sakārtoti pēc datuma• Sakārtoti pēc nosaukuma
Kādā veidā varētu to realizēt???
MultiActionController
public class ListCoursesController extends MultiActionController {
public ModelAndView coursesUnsorted(HttpServletRequest request, HttpServletResponse response) {. . .}public ModelAndView coursesSortedByStartDate(HttpServletRequest request, HttpServletResponse response) {. . .}public ModelAndView coursesSortedByName(HttpServletRequest request, HttpServletResponse response) {. . .}
Metodes vārda noteikšana• Pēc noklusējuma metodes vārds tiek noteikts
izmantojot URL sastāvdaļu:
•“http://…/coursesUnsorted.htm” coursesUnsorted()
•“http://…/coursesSortedByStartDate.htm”
coursesSortedByStartDate()
•“http://…/coursesSortedByName.htm” coursesSortedByName()
Metodes vārda noteikšana• Ir pieejami arī citi varianti:
• ParameterMethodNameResolver - Resolves the execution method name based on a parameter in the request
• PropertiesMethodNameResolver -Resolves the name of the execution method by consulting a list of key/value pairs
Pārskats
ThrowawayController• Nav Controller hierarhijas daļa
• Netiek izmantots HTTP pieprasījums vai komandas objekts
• Parametri tiek ierakstīti tieši kontrolierī• Ir noderīgi, kad nav modeļa objekta, kuru varētu
izmantot• Atšķirībā no citiem kontrolieriem, nav singleton
public interface ThrowawayController { ModelAndView execute() throws Exception;}
ThrowawayController
public class DisplayCourseController
implements ThrowawayController {
private Integer id;
public void setId(Integer id) { this.id = id; }
public ModelAndView execute() throws Exception {
Course course = courseService.getCourse(id);
return new ModelAndView(
"courseDetail", "course", course);
}
}
Interceptors• Iespēja pievienot papildus funkcionalitāti pirms
un pēc pieprasījuma
• Satur divas interception metodes –
preHandle un postHandle
• Satur vienu callback metodi –
afterCompletion
• Tiek piesaistīts kontrolieru kopai kopā ar HandlerMapping
Piemērs: Interceptor config<beans> <bean id="handlerMapping" class="org.springframework.web.
servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors"> <list> <ref bean="officeHoursInterceptor"/> </list> </property> <property name="mappings"> <value> /*.form=editAccountFormController
</value> </property> </bean>
<bean id="officeHoursInterceptor" class="samples.TimeBasedAccessInterceptor"> <property name="openingTime" value="9"/> <property name="closingTime" value="18"/> </bean><beans>
Piemērs: Interceptor kodspublic class TimeBasedAccessInterceptor extends
HandlerInterceptorAdapter {
. . .
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Calendar cal = Calendar.getInstance(); int hour = cal.get(HOUR_OF_DAY); if (openingTime <= hour < closingTime) { return true; } else { response.sendRedirect(
"http://host.com/outsideOfficeHours.html");
return false; } }}
View Resolving• A view is a bean that renders results to the user• Spring MVC consults view resolvers when trying
to determine which View bean to use
ViewResolver implementācijasSpring piedāvā četras pamata ViewResolver interfeisa implementācijas
• InternalResourceViewResolver –• Resolves logical view names into View objects
that are rendered using template file resources (such as JSPs and Velocity templates)
• BeanNameViewResolver - • Resolves logical view names into View beans
in the DispatcherServlet’s application context
ViewResolver implementācijas• ResourceBundleViewResolver –
• Mappings are contained within a properties file• Supports internationalization
• XmlViewResolver –
• Mappings are contained within a XML file that is separate from the DispatcherServlet’s application context
• VelocityViewResolver• FreeMarkerViewResolver
View klasesSpring piedāvā sekojošas skatu apakšklases:• JstlView
• Attēlo viewName par JSP lapu, kurā uzstādīti arī JSTL tagu bibliotēkām vajadzīgie mainīgie, piemēram, lokalizācija.
• RedirectView• Veic HTTP Redirect
• VelocityLayoutView, VelocityToolboxView, VelocityView
• Velocity skati ar vai bez papildu objektiem, ko konfigurē toolbox.xml
• FreeMarkerView
Internacionalizācija• Spring dod iespēju automātiski izvēlēties ziņojumu
tekstus izmantojot lietotāja lokāli
• DispatcherServlet izmanto LocaleResolver lai noteikt klienta lokāli
• AcceptHeaderLocaleResolver• izmantot HTTP "Accept-language" hederi lokāles atrašanai
• CookieLocaleResolver• izmantot cookies lokāles atrašanai
• SessionLocaleResolver • lokāle liek glabāta sesijā
Internacionalizācija• Lokāles izmaiņas funkcionalitātei var izmantot klasi
LocaleChangeInterceptor, to ir jāpieliek klāt kādam HandlerMapping
• Visbeidzot, teksta ziņojumus ir jāieraksta failos zem /WEB-INF/classes/:
• messages_en.properties• messages_de.properties• utml
• JSP lapā ziņojumus var ielikt izmantojot tagu <fmf:message key="<msg_name>">
<fmf:message key=“hello">
#msg_name=msg_textgreetings=Hello!true=Yesfalse=No
Springa tēmas• Viegli konfigurējamas un izpildes laikā
nomaināmas aplikācijas "ādas“
Springa tēmas• Tēma (theme) ir statisko resursu kolekcija,
kas ietekmē aplikācijas vizuālo stilu• style sheets (css), images
• ResourceBundleThemeSource ielāde properties failus no classpath saknes
/WEB-INF/classes/
• Daudz līdzības ar internacionalizācijas konfigurēšanu
Springa tēmas• Properties faila piemērs:
styleSheet=/themes/cool/style.css background=/themes/cool/img/coolBg.jpg
• JSP lapā ir jāizmanto <spring:theme> tagu<%@ taglib prefix="spring"
uri="http://www.springframework.org/tags"%><html> <head> <link rel="stylesheet"
href="<spring:theme code="styleSheet"/>" type="text/css"/>
</head> <body background="<spring:theme code="background"/>"> ... </body></html>
Failu augšupielāde• Spring piedāvā failu augšupielādes funkcionalitāti
(multipart file upload)
• Atbalsta CommonFileUpload un COS FileUpload
<bean id="multipartResolver“ class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000"/></bean>
<h1>Please upload a file</h1><form method="post" action="upload.form"
enctype="multipart/form-data"><input type="file" name="file"/><input type="submit"/></form>
Izņēmumu apstrāde• Viena no Springa īpatnībām - vairums izņēmumu
ir RuntimeException apakštipi, tos nevajag metodēs ķert vai deklarēt
• Ir piedāvāta iespēja apstrādāt negaidītas kļūdas
• SimpleMappingExceptionResolver• Iespēja piesaistīt skatu izņēmuma klasei
konfigurācijas failā
• HandlerExceptionResolver• Interfeiss, kuru vajag implementēt, lai apstrādāt
kontrolieru kļūdas
SimpleMappingExceptionResolver
<bean id="exceptionResolver" class="org.springframework.web.
servlet.handler. SimpleMappingExceptionResolver">
<property name="exceptionMappings"><props>
<prop key="java.lang.Exception">friendlyError</prop>
</props></property>
</bean>
Countries piemērs• Spring piemēru, kuru var palaist un apskatīties
kodu var atrast zem:\spring-framework-2.0.6\samples\countries\
Special Spring MVC features:• paged list navigation• locale and theme switching• localized view definitions• page composition through
view definitions• generation of PDF and
Excel views
Resursi• Spring Home
http://www.springframework.org
• C. Walls, R.Breidenbach. Spring in Action http://www.manning.com/walls2/
• Spring Web MVC Framework http://www.springframework.org/docs/reference/mvc.html
• Spring MVC step-by-step Tutorial http://www.springframework.org/docs/MVC-step-by-step/Spring-MVC-step-by-step.html
Resursi• Model-View-Controller pattern by Sun
http://java.sun.com/blueprints/patterns/MVC.html
• Core J2EE Patterns - Front Controller http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html
Recommended