Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Servlet, JSP Margus Hanni, Nortal AS 11.03.2013 Viited varasematele materjalidele… 2012 – TÜ - Servlets, JSP, Web Containers – Roman Tekhov 2010 – Webmedia - Java EE + containers – Anti Orgla Kas on asjakohane? http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html Kas on asjakohane? http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html Hello World - C ja JAVA #include <stdio.h> int main() { printf("Hello World\n"); return 0; } public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World"); } } Kas on asjakohane? Võrreldes eelmise aastaga on JAVA populaarsus taas kasvanud Jätkuvalt on JAVA populaarseim keel ning selles osas arvatavasti lähiajal muutusi ei toimu JAVA on laialdaselt kasutuses erinevate veebilahenduste loomisel JAVA EE (Enterprise Edition) Kogum vahendeid erinevate lahenduste loomiseks: Veebi rakendused Veebi teenused Sõnumivahetus Andmebaasid … http://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition JAVA EE Kogum vahendeid erinevate lahenduste loomiseks: Veebi rakendused Veebi teenused Sõnumivahetus Andmebaasis … Web Container Servlet JSP http://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition Web Container Manages component life cycles Accepts requests, sends responses Routes requests to applications http://tutorials.jenkov.com/java-servlets/overview.html Web Containers Apache Tomcat JBoss WebLogic Jetty Glassfish Websphere … Web Containers Multiple applications inside one container http://tutorials.jenkov.com/java-servlets/overview.html Application structure Application structure Java source files Application structure Document root Application structure Static content 15 Application structure Configuration, executable code Application structure Deployment descriptor Application structure Compiled classes Application structure Dependencies (JAR-s) Application structure Java Server Pages Deployment descriptor (web.xml) Instructs the container how to deal with this application <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app> Deployment descriptor (web.xml) In Servlet API version 3.0 most components of web.xml are replaced by annotations that go directly to Java source code. We will see examples later Servlets On JAVA klass, mis töötleb sissetulevat päringut ning tagastab vastuse Enamasti kasutatakse HTTP päringute ja vastuste töötlemiseks Servletid töötavad veebikonteineris, mis hoolitseb nende elutsükli ning päringute suunamise eest javax.servlet.http.HttpServlet – abstraktne klass, mis sisaldab meetodeid doGet ja doPost HTTP päringute töötlemiseks Servlet example public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.println("<html><head><title>Hello</title></head><bo dy>"); writer.println("<p>Hello World!</p>"); writer.println("<p>Current time: " + new Date() + "</p>"); writer.println("</body></html>"); } } HttpServlet methods For each HTTP method there is corresponding HttpServlet method doPost doGet doPut … Servleti töö Servlet Mapping Before Servlet 3.0 in web.xml <servlet> <servlet-name>hello</servlet-name> <servlet-class>example.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> Servlet Mapping In Servlet 3.0 via annotation @WebServlet("/hello") public class HelloServlet extends HttpServlet { ... Servlet life cycle http://tutorials.jenkov.com/java-servlets/servlet-life-cycle.html Üldine servleti elutsükkel Kui veebikonteineris puudub Servleti instants Laetakse Servleti klass Luuakse isend Initsialiseeritakse (init meetod) Iga päringu jaoks kutsutakse välja service meetod Servleti kustutamisel kutsutakse välja destroy meetod Sessions HTTP is a stateless protocol, but we often need the server to remember us between requests There are some ways Cookies URL rewriting Java HttpSession HttpSession is a common interface for accessing session context Java Servlet API abstract away the details of how the session is maintained Java HttpSession http://java.sun.com/developer/onlineTraining/JSPIntro/contents.html HttpSession example HttpSession session = req.getSession(); int visit; if (session.isNew()) { visit = 0; } else { visit = (Integer) session.getAttribute("visit"); } session.setAttribute("visit", ++visit); HttpSession example Either create a new HttpSession session = req.getSession(); session or get existing int visit; if (session.isNew()) { visit = 0; } else { visit = (Integer) session.getAttribute("visit"); } session.setAttribute("visit", ++visit); HttpSession example HttpSession session = req.getSession(); int visit; if (session.isNew()) { Check if the session is fresh or not visit = 0; } else { visit = (Integer) session.getAttribute("visit"); } session.setAttribute("visit", ++visit); HttpSession example HttpSession session = req.getSession(); int visit; if (session.isNew()) { visit = 0; } else { Retrieve attribute visit = (Integer) session.getAttribute("visit"); } session.setAttribute("visit", ++visit); HttpSession example HttpSession session = req.getSession(); int visit; if (session.isNew()) { visit = 0; } else { visit = (Integer) session.getAttribute("visit"); } session.setAttribute("visit", ++visit); Update attribute HttpServletRequest Contains request information Also can be used to store attributes request.setAttribute(“key", value); request.getAttribute(“key”); HttpServletRequest: parameters request.getParameterNames(); Enumeration<String> String value = request.getParameter("name"); HttpServletRequest: meta data request.getMethod(); “GET”, “POST”, … request.getRemoteAddr(); Remote client’s IP request.getServletPath(); “/path/to/servlet” … HttpServletRequest: headers request.getHeaderNames(); Enumeration<String> request.getHeader("User-Agent"); “Mozilla/5.0 (X11; Linux x86_64) …” Request Headers Accept Accept-Encoding Accept-Language Connection Cookie Host User-Agent text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 gzip, deflate et,et-ee;q=0.8,en-us;q=0.5,en;q=0.3 keep-alive JSESSIONID=C687CC4E2B25B8A27DAB4A5F30980583; __utma=111872281.1173964669.1316410792.1318315398.13 38294258.52; oracle.uix=0^^GMT+3:00^p localhost:8080 Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0 HttpServletRequest: cookies Cookie[] cookies = request.getCookies(); cookie.getName(); cookie.getValue(); cookie.setValue(“new value”); Cookie JSESSIONID C687CC4E2B25B8A27DAB4A5F30980583 C687CC4E2B25B8A27DAB4A5F30980583 utma 111872281.1173964669.13...318315398.1338294 111872281.1173964669.13...318315398.1338294258.52 258.52 oracle.uix 0^^GMT 3:00^p 0^^GMT+3:00^p HttpServletResponse Allows to set response information response.setHeader("Content-Type", "text/html"); response.addCookie(new Cookie("name", "value")); Response Headers Content-Language Content-Type Date Server Transfer-Encoding et text/html;charset=UTF-8 Mon, 11 Mar 2013 06:48:54 GMT Apache-Coyote/1.1 chunked HttpServletResponse: content response.getWriter().println("..."); Write text response.getOutputStream().write(...) ; Write binary Problem with servlets Writing HTML in Java is hideous PrintWriter writer = resp.getWriter(); writer.println("<html><head><title>Hello</title></head><body>"); writer.println("<p>Hello World!</p>"); writer.println("<p>Current time: " + new Date() + "</p>"); writer.println("</body></html>"); Java Server Pages (JSP) Write standard markup Add dynamic scripting elements Add Java code JSP example war/WEB-INF/jsp/hello.jsp <%@page import="java.util.Date"%> <html> <head><title>Hello</title></head> <body> <p>Hello World!</p> <p>Current time: <%= new Date() %></p> </body> </html> JSP mapping In web.xml <servlet> <servlet-name>hello2</servlet-name> <jsp-file>/WEB-INF/jsp/hello.jsp</jsp-file> </servlet> <servlet-mapping> <servlet-name>hello2</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> The JSP Model 2 architecture http://en.wikipedia.org/wiki/JavaServer_Pages JSP life cycle http://www.jeggu.com/2010/10/jsp-life-cycle.html Dynamic content Expression <p>Current time: <%= new Date() %></p> Scriptlet <p>Current time: <% out.println(new Date()); %></p> package org.apache.jsp.WEB_002dINF.jsp.document; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import java.util.Date; public final class testdokument_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public void _jspInit() { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } public void _jspDestroy() { } public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null; final java.lang.Object page = this; javax.servlet.jsp.JspWriter _jspx_out = null; javax.servlet.jsp.PageContext _jspx_page_context = null; try { response.setContentType("text/html; charset=UTF-8"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("\r\n"); out.write("\r\n"); out.write("<p>Current time: "); out.print( new Date() ); out.write("</p>"); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { out.clearBuffer(); } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); else throw new ServletException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } } Dynamic content Declaration <%! private Date currentDate(){ return new Date(); } %> <p>Current time: <%= currentDate() %></p> JSP Eeldefineeritud muutujad request- HttpServletRequest response – HttpServletResponse out – Writer session – HttpSession application – ServletContext pageContext – PageContext JSP Märgendid jsp:include Veebipäring antakse ajutiselt üle mingile teisele JSP lehele. jsp:forward Veebpäring antakse jäädavalt üle mingile teisele JSP lehele. jsp:getProperty Loeb mingi JavaBeani muutuja väärtuse. jsp:setProperty Määrab mingi JavaBeani muutuja väärtuse. jsp:useBean Loob uue või taaskasutab mingit JSP lehele kättesaadavat JavaBeani. Expression Language (EL) Easy way to access JavaBeans in different scopes Rea summa: ${rida.summa * rida.kogus} Basic Operators in EL Operator Description . Access a bean property or Map entry [] Access an array or List element () Group a subexpression to change the evaluation order + Addition - Subtraction or negation of a value * Multiplication / or div Division % or mod Modulo (remainder) == or eq Test for equality != or ne Test for inequality < or lt Test for less than > or gt Test for greater than <= or le Test for less than or equal >= or gt Test for greater than or equal && or and Test for logical AND || or or Test for logical OR ! or not Unary Boolean complement empty Test for empty variable values http://www.tutorialspoint.com/jsp/jsp_expression_language.htm Scopes Many objects allow you to store attributes ServletRequest.setAttribute HttpSession.setAttribute ServletContext.setAttribute Andmete skoobid ServletContext – veebikontekst, üks ühe rakenduse ja JVM-i kohta Sessioon – üks iga kasutajasessiooni kohta (erinev browser = erinev sessioon) Request – konkreetse päringu skoop Andmete kirjutamiseks/lugemiseks on meetodid setAttribute/getAttribute Scopes http://java.sun.com/developer/onlineTraining/JSPIntro/contents.html Scopes <% application.setAttribute("subject", "Web information systems"); session.setAttribute("topic", "Servlets"); request.setAttribute("lector", "Roman"); pageContext.setAttribute("lector", "Roman"); %> Subject: ${subject} Topic: ${topic} Lector: ${lector} Väljund: Subject: Web information systems Topic: Servlets Lector: Roman Scopes <% application.setAttribute("subject", "Web information systems"); session.setAttribute("topic", "Servlets"); request.setAttribute("lector", "Roman"); pageContext.setAttribute("lector", "Roman"); pageContext.setAttribute("subject", "Meie uus teema"); application.setAttribute("subject", "Meie järgmine teema"); %> Subject: ${subject} Topic: ${topic} Lector: ${lector} Mis on väljundiks? Scopes <% application.setAttribute("subject", "Web information systems"); session.setAttribute("topic", "Servlets"); request.setAttribute("lector", "Roman"); pageContext.setAttribute("lector", "Roman"); pageContext.setAttribute("subject", "Meie uus teema"); application.setAttribute("subject", "Meie järgmine teema"); %> Subject: ${subject} Topic: ${topic} Lector: ${lector} Subject: Meie uus teema Topic: Servlets Lector: Roman Scopes <% application.setAttribute("subject", "Web information systems"); session.setAttribute("topic", "Servlets"); request.setAttribute("lector", "Roman"); pageContext.setAttribute("lector", "Roman"); Less visible %> Subject: ${subject} Topic: ${topic} Lector: ${lector} JavaBeans public class Person implements Serializable { Implements Serializable private String name; public Person() {} Public default constructor public String getName() { return name; } getX and setX methods for each property X public void setName(String name) { this.name = name; } } JavaBeans in EL Person person = new Person(); person.setName("Roman"); request.setAttribute("person", person); <p>Person: ${person.name}</p> Java Standard Tag Library (JSTL) Set of standard tools for JSP <% List<String> lectors = Arrays.asList("Siim", "Roman", "Margus"); pageContext.setAttribute("lectors", lectors); %> <c:set var="guestLector" value="Margus" /> <c:forEach var="lector" items="${lectors}"> Name: ${lector} <c:if test="${lector eq guestLector}“>(guest)</c:if> <br /> </c:forEach> Problem with JSP Writing Java in JSP is hideous <p>Current time: <%= currentDate() %></p> Model-View-Controller (MVC) http://java.sun.com/blueprints/patterns/MVC-detailed.html Servlet controller, JSP view Controller gets invoked protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setAttribute("currentDate", new Date()); Model data req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req, resp); } Servlet controller, JSP view Controller gets invoked protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setAttribute("currentDate", new Date()); req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req, resp); Select and invoke view } Servlet controller, JSP view WEB-INF/jsp/hello.jsp <html> ... <body> <p>Current time: ${currentDate}</p> View uses the </body> data from model </html> Filters Allows you to do something before, after or instead of servlet invocation. Filter chain http://docs.oracle.com/javaee/5/tutorial/doc/bnagb.html Filter example public class LoggingFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long start = System.currentTimeMillis(); chain.doFilter(request, response); long end = System.currentTimeMillis(); System.out.println("Time spent: " + (end - start)); } } Filter example public class LoggingFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long start = System.currentTimeMillis(); chain.doFilter(request, response); Invoke next filter in chain or the servlet if this was the last filter long end = System.currentTimeMillis(); System.out.println("Time spent: " + (end - start)); } } Filter declaration Before Servlet 3.0 in web.xml <filter> <filter-name>loggingFilter</filter-name> <filter-class>example.LoggingFilter</filter-class> </filter> <filter-mapping> <filter-name>hello</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> Filter declaration In Servlet 3.0 via annotation @WebFilter("/*") public class LoggingFilter implements Filter { ... Life cycle event listeners javax.servlet.ServletContextListener javax.servlet.ServletContextAttributeListener javax.servlet.ServletRequestListener javax.servlet.ServletRequestAttributeListener javax.servlet..http.HttpSessionListener javax.servlet..http.HttpSessionAttributeListener Listener example public class LoggingRequestListener implements ServletRequestListener { @Override public void requestInitialized(ServletRequestEvent event) { System.out.println("Received request from " + event.getServletRequest().getRemoteAddr()); } @Override public void requestDestroyed(ServletRequestEvent event) {} } Listener declaration Before Servlet 3.0 in web.xml <listener> <listener-class> example.LoggingRequestListener </listener-class> </listener> Listener declaration In Servlet 3.0 via annotation @WebListener public class LoggingRequestListener implements ServletRequestListener { ... Should I bother? • There are a lot of fancy Java web frameworks that simplify application building. • Should I still learn these basic technologies, will I ever use them? Should I bother? • You are still going to deploy your application to a web container. • Most traditional frameworks use JSP as the view technology. What about servlets? • Most frameworks are based on the Servlet API • You will probably still encounter things like HttpSession, HttpServletRequest etc inside your code. • You might want to write filters and listeners. • You probably won’t write much servlets. But sometimes they can still be handy for simple tasks. Sources of wisdom Tutorial http://docs.oracle.com/javaee/6/tutorial/doc/ http://docs.oracle.com/javaee/5/tutorial/doc/ API http://docs.oracle.com/javaee/6/api/ http://docs.oracle.com/javaee/5/api/