web applications 2 - cw.fel.cvut.cz€¦ · wa2 slide 3 java java me = java micro edition –mobile...
TRANSCRIPT
WA2Slide 1
Web Applications 2
Java EE
Martin Klíma
WA2Slide 2
Web Application Architecture
Web Server
request
response
HTTP
Thin client
(HTML)
controller
HTML
generator
Data
model
(JavaBea
n)
view
(HTML)
Thick client
(non - HTML)
Application Server
App 3
App 2
App 1
Data
WA2Slide 3
Java
Java ME = Java Micro Edition
– Mobile applications
Java SE = Java Standard Edition
– Desktop applications
Java EE = Java Enterprise Edition
– Web & application servers
WA2Slide 4
Java EE
ClientApplicationClient
WebClient
Servlet
Client Tier
Web Tier
Bussiness TierEnterprise Beans
Enterprise Beans
Java EE Server
EIS TierDatabaseServerDatabase Database
WA2Slide 5
Deployment
Each JEE application is packed into a standard format
It contains
– Functional components like EJB, JSP, servlets, applets, static resources, …
– Descriptor
Once packed it can be deployed on any standard server
WA2Slide 6
Servlet
ClientApplicationClient
WebClient
JSP Pages
Client Tier
Web Tier
Bussiness TierEnterpriseBeans
EnterpriseBeans
Java EE Server
EIS TierDatabaseServerDatabase Database
Servlets
WA2Slide 7
Servlets
Servlet is a class that augments the functionality of a server
– This is how we can influence the web pages generation.
All servlets must implement javax.servlet.Servlet interface, which defines the life cycle methods required by the servlet container.
The most common way is to extend javax.servlet.http.HTTPServlet.
A Servlet je mapped to particular URL (one or more)through web.xml file.
WA2Slide 8
Servlets API
<<interface>>Servlet
service()
<<interface>>ServletRequest
<<interface>>ServletResponse
<<interface>>HTTPServlet
service()
WA2Slide 9
Servlet lifecycle
new
init()
service()
ready
destroy()
destroyed
WA2Slide 10
Service method
k
GenericServlet has the service method.
HTTPServlet overloads the service method by a set of methods corresponding to HTTP methods
– doGet– doPost– doPut– doDelete– doOptions– doHead– doTrace
java.lang.Object|+--javax.servlet.GenericServlet
|+--javax.servlet.http.HttpServlet
A
A
WA2Slide 11
The servicing methods parameters
Request is encapsulated
– ServletRequest resp. HttpServletRequest
– see http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletRequest.html andhttp://java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpServletRequest.html
HttpServletRequest – interesting methods
– Object getParameter(String name)
– void setParameter(String name, Object o)
– and many others
WA2Slide 12
The servicing methods parameters II
To generate a response, write
– Into object of type ServletResponse resp. HttpServletResponse
– see http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletResponse.html andhttp://java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpServletResponse.html
HttpServletResponse – interesting methods
– addHeader(String name, String value)
– PrintWriter getWriter()
– void addCookie(Cookie cookie)
– and many others
WA2Slide 13
Form parametersnickname
password
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {out.println("<html>");
out.println("<head>");
out.println("<title>Servlet FirstServlet</title>");
out.println("</head>");
out.println("<body>");
String jmeno = request.getParameter("nickname");
if (null != jmeno) {
out.println("Jméno");
}
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
WA2Slide 14
Usual technique – how to generate a response
Get the output stream
– For text output use PrintWriter
– For binary outpout use ServletOutputStream
Modify headers, set output type, e.g. text/html, (MIME type)
– http://www.iana.org/assignments/media-types/
– method setContentType(String type)
Set buffering
– method setBufferSize(int size)
WA2Slide 15
package cz.cvut.fel;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class FirstServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {out.println("<html>");
out.println("<head>");
out.println("<title>Servlet FirstServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("Ahoj");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}
Overloading the GET method
Write to output stream
WA2Slide 16
WEB XML
WA2Slide 17
Web.xml
Configures the behavior of servlet container
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>cz.cvut.fel.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>FirstServlet</welcome-file>
</welcome-file-list>
</web-app>
Servlet name
Servletimplementing class
URL mapping
The default mapping
Servlet may have multiple mappingsi
WA2Slide 18
Web.xml - parameters<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<context-param>
<param-name>Author</param-name>
<param-value>Martin Klíma</param-value>
</context-param>
<context-param>
<param-name>Affiliation</param-name>
<param-value>ČVUT</param-value>
</context-param>
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>cz.cvut.fel.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/PrvniServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>FirstServlet</welcome-file>
</welcome-file-list>
</web-app>
Parameters are accessible via Contextobject
WA2Slide 19
JAVASERVER PAGES - JSP
WA2Slide 20
JSP
JSP is a text document containing
– static data, usually (X)HTML
– JSP elements that generate dynamic content
Suffix .jsp
Two versions
– standard
– XML
We will use the standard syntax further in the lecture.
WA2Slide 21
The simples jsp page
<%--
Document : stranka1
Created on : 18.2.2008, 11:44:52
Author : xklima
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h2>Hello World!</h2>
</body>
</html>
WA2Slide 22
Servlet Containere
JSP life cycle
JSPServlet
generated fromJSP
comple
HTTP request
if JSP is newer than servletthen
compileelse
execute servlet
WA2Slide 23
MVC
WA2Slide 24
MVC – Bean, JSB, Servlet
Servlet (C) reads http parameters, calls the logic (M).
Parameters reflect what the use wants (form data, etc.)
Finally, when the logic is done, the control is handed over to JSP
Browser
Servlet (C)
Bean (M)
pocetKusu=7&produktID=22
pocetKusuproduktID
JSP (V)
forward use
WA2Slide 25
Java Bean can be used as application logic
StatementController
Servlet - Controller
StatementBean
JavaBean - Model
StatementForm
JSP - view
HTTP requestUse, create
Forward
MVC
WA2Slide 26
JavaBean can be used for information sharing
public class StatementBean implements Serializable {
protected ArrayList <String> statements;
public StatementBean(){
super();
statements = new ArrayList <String>();
}
public synchronized String getStatement(int i) {
return statements.get(i);
}
public synchronized List <String> getAllStatements(){
return statements;
}
public synchronized void addStatement (String statement) {
if (!statements.contains(statement)) {
statements.add(statement);
}
}
public synchronized int getStatementCount() {
return statements.size();
}
}
WA2Slide 27
Form for adding statements statementForm.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Statements</title>
</head>
<body>
<h2>List</h2>
<jsp:useBean id="statements" scope="session"
class="cz.cvut.fel.StatementBean" />
<%
for (String statement : statements.getAllStatements()) {
out.println(statement + "<br/>");
}
%>
<form action="StatementController" method="GET">
<input type="text" name="statement"/>
<input type="submit" value="Submit" name="submit"/>
</form>
</body>
</html>
WA2Slide 28
Controller - servlet
protected void processRequest(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
if (request.getParameter("statement") != null) {
StatementBean sb = (StatementBean)
request.getSession().getAttribute("statements");
if (sb == null) {
sb = new StatementBean();
}
sb.addStatement((String)request.getParameter("statement"));
request.getSession().setAttribute("statements", sb);
}
} finally {
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher("/statementForm.jsp");
dispatcher.forward(request, response);
}
}
WA2Slide 29
Serialization in Java
Value transfer and storage (marshal, unmarshal)
java.io.Serializable
transient is excluded from serialization
serialVersionUID
NotSerializableException
MarshalException, UnmarshalException
private void writeObject(ObjectOutputStream oos)
throws IOException;
private void readObject(ObjectInputStream oos)
throws IOException, ClassNotFoundException;
WA2Slide 30
APPLICATION SERVER
WA2Slide 31
Web application architecture – application server
Web Server
request
response
HTTP
Thin client
(HTML)
controller
HTML
generator
Data
model
(JavaBean)
view
(HTML)
Thick client
(non - HTML)
Application
Server
App 3
App 2
App 1
Data
WA2Slide 32
Enterprise Beans
A component running on application server
Managed by EJB container
Accessible from a stand-alone application (RMI)
Accessible from web application (Servlet container – RMI)
Architecture ready to use
– session management
– transaction management
– db connection management
– use authentication, authorization
– asynchronous messaging
WA2Slide 33
Enterprise beans
Several types of EJB
Session bean
– Stateless
– Singleton (since EJB 3.1)
– Statefull
Entity bean
Message driven bean
EJB 3.0 ->Entity
WA2Slide 34
Session beans
Represent application logic
Two types:
– Bound to a particular client (statefull)• !!!not a HTTP session
– Client independent (stateless)
WA2Slide 35
Entity
Objects representing a persistent element (ORM)
Bound to database
Transactions, search
Object
OP approach to data persistency
Relations to other entities
WA2Slide 36
Message driven bean
Event driven application logic
Events generated by other applications
B2B
Asynchronous
Typically very short lifetime
Not bound to persistant data
Stateless
WA2Slide 37
EJB 3.x
POJO = Plain Old Java Object
Container is driven by annotations provided
Container controls their livecycle
Local and remote interface
Registered in JNDI (registry)
– Serach by name
– Remote access
WA2Slide 38
Example@Stateless (mappedName = "Repeater")
public class RepeaterSessionBean implements RepeaterSessionBeanRemote,
RepeaterSessionBeanLocal {
public String repeatNormalLocal(final String text) {
return text;}
public String repeatNormalRemote(final String text) {
return text;}
public String repeatReverseRemote(final String text) {
return getReverseString(text);}
public String repeatReverseLocal(final String text) {
return getReverseString(text);}
private String getReverseString(String text) {
StringBuffer b = new StringBuffer(text.length());
for (int i = text.length(); i > 0; i--) {
b.append(text.charAt(i - 1));}
return b.toString();}
}
@Local
public interface RepeaterSessionBeanLocal {
String repeatNormalLocal(final String text);
String repeatReverseLocal(final String text);
}
@Remote
public interface RepeaterSessionBeanRemote {
String repeatNormalRemote(final String text);
String repeatReverseRemote(final String text);
}
Stateless EJBJNDI mapping
WA2Slide 39
Example cont.public class FormBean1 {
@EJB(name="Repeater")
RepeaterSessionBeanLocal repeaterBean;
private String text;
private String reverse;
public FormBean1() { }
public String getText() {
return text; }
public void setText(String text) {
this.text = text; }
public String translate() {
setReverse(repeaterBean.repeatReverseLocal(text));
return null;
}
public String getReverse() {
return reverse; }
public void setReverse(String reverse) {
this.reverse = reverse;
}
}
Injection
Použití
WA2Slide 40
EJB annotations
@Target(TYPE) @Retention(RUNTIME)
public @interface Stateless {
String name() default "";
String mappedName() default "";
String description() default "";
}
@Target(TYPE) @Retention(RUNTIME)
public @interface Stateful {
String name() default "";
String mappedName() default "";
String description() default "";
}
WA2Slide 41
Stateless EJB livecycle
stateless = no memory
WA2Slide 42
Stateful EJB Livecycle
WA2Slide 43
The same image without transactions
WA2Slide 44
Lookup and use
1. Dependency Injection
– Container takes care of the DI
– Annotation helps to do the job
2. JNDI lookup
public class FormBean1 {
@EJB(name="Repeater")
RepeaterSessionBeanLocal repeaterBean;
…
}
static RepeaterSessionBeanRemote repeaterSessionBean;
Context context;
try {
context = new InitialContext();
repeaterSessionBean = (RepeaterSessionBeanRemote) context.lookup("JNDI_NAME");
} catch (NamingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
WA2Slide 45
Calling Stateless EJB from a web application
Same as from stand-alone application
Usong a Stateful EJB is not recommended from a stateless context (HTTPServlet)
Use Stateless EJB whenever possible
WA2Slide 46
Local & Remote interface
RMI is complicated and resource concuming
In same cases the EJB is located in the same VM – can be called locally
Therefore there is a Local Interface
WA2Slide 47
Stateless vs Statefull EJB
Use stateless whenever possible
Stateless are easy to scale
Stateless do not need persistency
Statefull must be stored in memory
Demanding for the server
Do not scale well
Good for big tada processing - transactional
We do not have to care of multithreading
WA2Slide 48
Interceptor
Interceptor is kind of event handler
Similar to event handlers elsewhere in Java (Swing)
Depending on the EJB bean, for example:
WA2Slide 49
Two way to use interceptors
1. Directly in the Bean class
@AroundInvoke
public Object profile(InvocationContext inv) throws Exception {
long time = System.currentTimeMillis();
try {
return inv.proceed();
} finally {
long endTime = time - System.currentTimeMillis();
System.out.println(inv.getMethod() + " took " + endTime + "
milliseconds.");
}
}
WA2Slide 50
In a separate class linked by annotation
@Interceptors(cz.cvut.fel.ejb.interceptors.RepeaterInterceptor.class)
@Stateless(mappedName = "Repeater")
public class RepeaterSessionBean implements RepeaterSessionBeanRemote,
RepeaterSessionBeanLocal {
public String repeatNormalLocal(final String text) {
return text;
}
public String repeatNormalRemote(final String text) {
return text;
}
}
EJB Comma separated list
public class RepeaterInterceptor {
@AroundInvoke
public Object profile(InvocationContext ctx) throws Exception {
try {
System.out.print("Zavolana metoda " + ctx.getMethod().getName());
} finally {
return ctx.proceed();
}
}
}
WA2Slide 51
MESSAGE DRIVEN BEANSMDB
WA2Slide 52
What is MDB?
Components that process messages
Similar to Stateless EJB
– stateless
– interchangeable
…they have different purpose
Messaging is a basic principle of distributed systems
MDB is typically target for messages
WA2Slide 53
MDB
Container
Client
Destination or endpoint MDB
MDBMDB
JNDI assigned
WA2Slide 54
MDB
Two communication modes
– Point to point: queues, FIFO associated with one bean
– Publish / subscribe: topics, distribuce multiple receivers
Implements interface javax.jms.MessageListener
– onMessage method
WA2Slide 55
MDB – Lifecycle
WA2Slide 56
JMS – Java Message Service
JMS message
– Several types of message
Header, properties and body
– Header: delivery mode, msg ID, timestamp, priority, ReplyTo, msg type
– Properties: key, value
– Body: Stream, Map, Text, Object, Bytes
WA2Slide 57
Example MDB
@MessageDriven(mappedName = "jms/school", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-
acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class SchoolMessageBean implements MessageListener {
public SchoolMessageBean() {
}
public void onMessage(Message message) {
TextMessage tm = (TextMessage) message;
String teacher;
try {
teacher = tm.getText();
System.out.println("Prijata informace o pridani ucitele: " + teacher);
} catch (JMSException ex) {
Logger.getLogger(SchoolMessageBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
WA2Slide 58
Client sending message
@Stateless
public class SchoolSessionBean implements SchoolSessionBeanRemote, SchoolSessionBeanLocal {
@Resource(name = "jms/school")
private Queue school;
@Resource(name = "jms/schoolFactory")
private ConnectionFactory schoolFactory;
public PartTimeTeacherEntity addPartTimeTeacher(final String firstName, final String lastName, final float partTime) {
try {
sendJMSMessageToSchool(firstName + ” teacher added”);
} catch (JMSException ex) { Logger.getLogger(SchoolSessionBean.class.getName()).log(Level.SEVERE, null, ex); }
return teacher;
}
private Message createJMSMessageForjmsSchool(Session session, Object messageData) throws JMSException {
TextMessage tm = session.createTextMessage();
tm.setText(messageData.toString());
return tm;
}
… pokračování na dalším slide
WA2Slide 59
Client cont.
private void sendJMSMessageToSchool(Object messageData) throws JMSException {
Connection connection = null;
Session session = null;
try {
connection = schoolFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(school);
messageProducer.send(createJMSMessageForjmsSchool(session, messageData));
} finally {
if (session != null) {
try {
session.close();
} catch (JMSException e) {
Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot close session", e);
}
}
if (connection != null) {
connection.close();
}
}
}
}
WA2Slide 60
References
http://java.sun.com/developer/technicalArticles/ebeans/ejb_30/
http://java.sun.com/products/ejb/docs.html