560 likes | 691 Views
CGS – 4854 Summer 2012 . Instructor: Francisco R. Ortega Chapter 3 Part 1. Web Site Construction and Management. Today’s Lecture. Chapter 4 Quiz 4 will be short and given at the start of class (June 14) Covers chapter 3 and Chapter 4. . Mid-Term. Mid-Term June 21 st .
E N D
CGS – 4854 Summer 2012 Instructor: Francisco R. Ortega Chapter 3 Part 1 Web Site Construction and Management
Today’s Lecture • Chapter 4 • Quiz 4 will be short and given at the start of class (June 14) • Covers chapter 3 and Chapter 4.
Mid-Term • Mid-Term June 21st. • Chapters 1,2,3 and 4. • Possible review for mid-term • June 14 (after quiz 4) or June 19 • Extra Credit for Mid-Term • Extra credit question may be Java related or Regular Expressions (if covered before the exam) • You are allowed to bring one letter size paper to the exam
Enhancing the Controller • We will be adding some cool features to our controller from Chapter 3 • Logging • …
Logging • Excellent resource to keep debugging information • We will be using log4j • http://logging.apache.org/log4j/1.2/
Log4j • Up to 5 levels • It will only write the same level or lower levels • Fatal errors always are written to the log • FATAL, ERROR, WARN, INFO, DEBUG
Examples • warn(“optional playerName variable is empty”); • Warn, info, debug
Initialization Servlet • It is great to have servlets that set up initial values/classes that you will need • They will be called once • It cannot be called by a user via the browser
Initialization Servlet + Log4j <servlet> <servlet-name>InitLog4j</servlet-name> <servlet-class>shared.InitLog4j</servlet-class> <init-param> <param-name>logPath</param-name> <param-value>/WEB-INF/logs/error.log</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Question • Why don’t we need mapping for the initialization server?
Initialization Servlet (pg. 109) public class InitLog4j extendsHttpServlet { publicvoidinit() { … } privateFileAppendergetAppender(String filename){ … } privatevoid initLogger(String name, FileAppenderappender, Level level) { … } }
Helper Methods: getAppender PrivateFileAppendergetAppender(StringfileName) { RollingFileAppenderappender = null; try{ Appender = newRollingFileAppender(…..) appender.setMaxBackupIndex(5); Appender.setMaxFileSize(“1MB”); } Catch (IOException ex) { } return appender; }
Helper Methods: initLogger private void initLogger(String name, FileAppender Name, Level level) { Logger logger; If (name == null) { logger = Logger.getRootLogger(); } else { logger = Logger.getLogger(name); } logger.setLevel(level); logger.addAppender(appender) Logger.info(“Starting “ + logger.getName(); }
Init() public void init() { String initPath = getInitParameter(“logPath”); String logPath = “/WEB-INF/logs/errors.log” If (initPath != null) logPath = initPath; FileAppenderappender = getAppender(logPath) If (appender == null) return; initLogger(null, appender, Level.ERROR); initLogger(“org.apache.commons.beanutils”, appender, Level.DEBUG); }
Adding more initialization parameters … <init-param> <param-name>logPath</param-name> <param-value>/WEB-INF/logs/error.log</param-value> <param-name>logName</param-name> <param-value>error.log</param-value> <param-name>logLevel</param-name> <param-value>Level.Debug</param-value> </init-param> …
Note: shared Package (book) • The helper based classed has been renamed to HelperBaseCh4 (and ch5, ch6) in the shared package. • HelperBaseClass has 4 parameters now • servlet,request,response,logger • Checked moodle or the book site for the shared package
Initializing the logger • We will initialize in the the base class!
HerlperBaseCh4 public HelperBaseCh4( HttpServlet servlet, HttpServletRequest request, HttpServletResponse response) { this.servlet = servlet; this.request = request; this.response = response; initLogger(); } protected void initLogger() { String logName = "bytesizebook.webdev"; String initName = servlet.getInitParameter("logName"); if (initName != null) logName = initName; Level logLevel = Level.DEBUG; String strLevel = servlet.getInitParameter("logLevel"); if (strLevel != null) { logLevel = Level.toLevel(strLevel); } logger = Logger.getLogger(logName); logger.setLevel(logLevel); } … }
Hidden Fields -- ${helper} • Controller Helper • Has bean with data entered by user • Write itself to the session ( this ) • Hidden fields • Stores data • Send it back to application • Trigger by button • Session State • Data is stored for duration of the session. • Controller Helper can retrieve it from the session
Eliminating Hidden Fields • You may want a site to let you restart • You may want to save a helper from a different application
Note: Using enumeration If (state == SessionData.READ) { ….. } public enumStreetLight { RED, YELLOW, GREEN}; http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
Helper Methods • addHelperToSession • setAttribute to add helper • Retrieve old helper from session • copyFromSession • Copy specific values from old session • In our particular example, it copies the entire bean
public void addHelperToSession(String name, SessionDatastate) { if (SessionData.READ== state) { Object sessionObj = request.getSession().getAttribute(name); if (sessionObj != null) { copyFromSession(sessionObj); } } request.getSession().setAttribute(name, this); }
public void copyFromSession(Object sessionHelper) { if (sessionHelper.getClass() == this.getClass()) { ControllerHelperoldHelper = (ControllerHelper)sessionHelper; data = oldHelper.data; } }
Packages needed for BaseHelperCh4 import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Level; import org.apache.log4j.Logger;
public abstract class HelperBaseCh4 { … protected abstract void copyFromSession(Object helper); public void addHelperToSession(String name, SessionData state) { … } public void addHelperToSession(String name, booleancheckSession) { … } }
Java Question • Why use abstract classes? • Why is it that we can call an abstract method from the base class ? • What would happened if we didn’t have an abstract method for our example? • Can the implementation of the copyFromSession Method be moved to the base class? Explain.
NOTE: CopyToSession • By making the copyToSession an abstract method in the HelperBase, then the addHelperToSession method can be defined in the base class.
AddHelperToSession • Parameter name should be unique • In our book, we keep it the same • If you were using multiple controllers • Make sure to have a different name for each helper • Parameter state • Use READ when: • Need to read old helper. • Use IGNORE when: • Start of a new request
HelperBase HttpServletRequest request HttpServletResponse response Logger logger Abstract copyFromSession() addHelperToSession() ControllerHelper RequestData data doGet() getData() copyFromSession()
copyFromSession if (sessionHelper.getClass() == this.getClass() ){ ControllerHelper helper = (ControllerHelper)sessionHelper; data = helper.data; } It’s important to know that the helper is the same type of controller for the application
ControllerHelper.doGet() public voiddoGet() throws ServletException, IOException { addHelperToSession(“helper”,SessionData.READ); … }
Location JSP • If not relative • Must specify path
Location of JSP – OLD WAY if (request.getParameter("processButton") != null) { address = "/ch3/dataBean/Process.jsp"; } else if (request.getParameter("confirmButton") != null) { address = "/ch3/dataBean/Confirm.jsp"; } else { address = "/ch3/dataBean/Edit.jsp"; }
Location of JSP protected String jspLocation(String page) { return "/ch3/dataBean/" + page; }
Location of JSP - New Way if (request.getParameter("processButton") != null) { address = "Process.jsp"; } else if (request.getParameter("confirmButton") != null) { address = "Confirm.jsp"; } Else { address = "Edit.jsp"; } address = jspLocation(address);
Visible and Hidden JSP • Visible • /homework3/jsp/ • Hidden • /WEB-INF/homework3/jsp/ • WEB-INF is hidden from the browser not the servlet
JSP Location - MORE • If jsp is at the same location of the class • “/WEB-INF/classes/mypackage/myclass/” + page • Where to keep the JSPs pages? • Keep it hidden to yield to the controller.
JSP LOCATION - MORE • If you are single developer • You may want to keep the jsp in the same location that you have your controller • Starting chapter 4, the book will follow this method. • If you are working in a team or want to keep things organized • Keep JSP in separate folders
Controller Logic - MORE • Controllers need to perform several task • Save/Load Data • Validate Data • Set address of next page • … • To keep things more organized • Use a method for each button • Use annotations to specify the button
Decoding Button Names @ButtonMethod(buttonName= “confirmButton“) public String confirmButton() { fillBeanFromRequest(data); String address; if (isValid(data) ){ address = “Confirm.jsp”; } else { address = “Edit.jsp”; } return jspLocation(address); }
Buttons & Annotations • Use isDefault=True parameter for the default button • @ButtonMethod(buttonName=“editButton”, isDefault=true) • Even if no button is clicked, this will be the default action • Make sure the annotation reflects the name of the method and button
Executing the button • Call executeButtonMethod() • Call executeButtonMethods(Class clazz, booleansearchForDefaults) • Call InvokeButtonMethod(Method buttonMethod)
protected String executeButtonMethod(Class clazz, booleansearchForDefault) throws IllegalAccessException, InvocationTargetException { String result = ""; Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { ButtonMethod annotation = method.getAnnotation(ButtonMethod.class); if (annotation != null) { if (searchForDefault && annotation.isDefault()) { methodDefault = method; } if (request.getParameter(annotation.buttonName()) != null) { result = invokeButtonMethod(method); break; } } }
In-Class participation • Due June 14: please write pseudo-code and comments explaining how the button invocation works. • This includes the following methods from HelperBaseCh4 • Call executeButtonMethod() • Call executeButtonMethods(Class clazz, booleansearchForDefaults) • Call InvokeButtonMethod(Method buttonMethod) • It will be only be accepted late during the day of June 14. It must be handed to me before the end of my office hours.
Filling a bean • Can we automate the mutators methods for the bean? • void setPlayerName(string playerName) • We can use a java extension to do this • Remember to follow the name conventions • playerName will be? • setPlayerName(….) • getPlayerName()
What do you need? • commons-collection • Version used in book: 3.2.1 • commons-logging • Version used in book: 1.1.1 • commons-beanutils • Version used in book: 1.8.3 • Download from the book site (jar) or • htttp://jakarta.apache.org/common/