Transcript ppt

Servlets:
Leftover Odds and Ends
(Most apply to JSPs as
well, duh….)
1
A Warning: Don’t Panic…
• Many of the examples in this presentation are
using various features not discussed throughout
this course.
• There is not need to understand them in a deeper
extent than the understanding of the relevant
examples.
• They are there to give you a general idea of what
these feature names refer to and what can be
done with them.
• Google these features if you want / ever need to...
2
Exceptions
• Exceptions are caught by the server
• You can find them in the log file under
$CATALINA_BASE/logs/
• The result shown in the browser depends on the
buffer state
• Check the example on the next slide…
• Find the exceptions in the log
3
public class ExceptionServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
int nLines = Integer.parseInt(request.getParameter("nlines"));
out.println("<html><head></head><body>");
for (int i = 0; i < nLines; ++i) {
out.println("<p> bla bla bla " + i + "</p>"); }
out.println("</body></html>");
out.println(" " + 1/0 + " "); }}
This line causes an
exception
Run :
http://localhost/dbi/exception?nlines=10
http://localhost/dbi/exception?nlines=1000
4
Uploading Files with
Servlets
Read more about the FileUpload API
5
Handling Uploads with Package
Commons FileUpload
• Commons FileUpload is a package of Apache for
handling uploaded files in the Servlet side
• Files are sent in the body of post requests
• Using this package, uploaded files are
temporarily written into the memory or the disk
(depending on the file size)
• You can set the size threshold beyond which files
This is not a configuration parameter in
are written to disk
web.xml but a part of the API as we’ll
see in the next slides
6
Handling Uploads with Package
Commons FileUpload
• Servlets read the file from the disk or memory
• In Tomcat, the default temporary directory is
$CATALINA_BASE/temp/
• However, you can specify a temporary directory
of your own (e.g., /tmp)
• What if a very big file is uploaded?
- You can define the maximal size of uploaded files
- Exception is thrown for larger files
7
Example 1
Sends the client the
uploaded file
<html>
<head>
<title>Upload Files and Parameters</title>
</head>
<body>
<form action="upload1" method="post"
enctype="multipart/form-data">
This is the right encoding type for
files uploading
<h2>File:<input type="file" name="file1"/></h2>
<h2><input type="submit" value="send" /></h2>
</form>
</body>
</html>
upload1.html
8
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.*;
import org.apache.commons.fileupload.*;
public class Upload1 extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory();
//factory.setRepository(new File("/tmp"));
Sets the repository
factory.setSizeThreshold(1000);
Sets the memory vs.
disk threshold (bytes)
directory
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(60000);
Sets the maximum file size (bytes).
Bigger files generate exceptions
Upload1.java
9
try {
In our example, we
expect a single
List items = upload.parseRequest(request);
parameter
Iterator it = items.iterator();
Makes life
FileItem item = (FileItem) it.next();
much easier
response.setContentType(item.getContentType());
We use an
response.setContentLength((int)item.getSize());
Output
stream and
InputStream is = item.getInputStream();
not the out
OutputStream os = response.getOutputStream(); PrintWriter
byte[] buffer = new byte[4096]; int read = -1;
(why?)
while((read=is.read(buffer))>=0) os.write(buffer,0,read);
}
catch (FileUploadException exp) {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body><b>Error</b>: <i>" +
exp.getMessage() + "</i></body></html>");
Upload1.java10
}}}
Example 2
Mixed parameter types
<html>
<head>
<title>Upload Files and Parameters</title>
</head>
<body>
<form action="upload2" method="post"
enctype="multipart/form-data">
<h2>Parameter x: <input type="text" name="x" /></h2>
<h2>File: <input type="file" name="file1" /></h2>
<h2>Parameter y: <input type="text" name="y" /></h2>
<h2><input type="submit" value="send" /></h2>
</form>
</body>
</html>
upload2.html
11
List items = upload.parseRequest(request);
Iterator it = items.iterator();
This time we use a loop
out.println("<ol>");
since there are several
while (it.hasNext()) {
parameters
FileItem item = (FileItem) it.next();
if (item.isFormField())
out.println("<li><b>Field</b>: " + item.getFieldName()
+ " = " + item.getString() + "</li>");
else
out.println("<li><b>File</b>"
+ ": parameter name: " + item.getFieldName()
+ ", file name: " + item.getName()
+ ", file size: " + item.getSize()
+ " bytes, file type: " + item.getContentType()
+ "</li>");
}
Upload2.java
out.println("</ol>");
12
Example 3
• The latter example reflected a common design problem:
combining complex HTML code and Java code in a
Servlet or a JSP
- Java code for processing parameters and uploaded files
- HTML code for generating the (dynamic) response
• An accepted solution is to process the parameters in a
Servlet, and forward the request to a JSP for generating
the response
- Attributes can be sent to the JSP via the request object.
• The next example also uses JSTL
13
JSTL
• JSTL stands for JSP Standard Tag Library
• This is a regular tag library that can be imported
to your page, like the ones we created in the past
• This library includes some standard actions that
are common in JSP, like iteration and conditions
over EL expressions, parsing/manipulation of
XML and database access
• More details can be found in Sun's J2EE Tut.
14
Example 3
<html>
<head>
<title>Upload Files and Parameters</title>
</head>
<body>
<form action="upload3" method="post"
enctype="multipart/form-data">
<h2>Parameter x: <input type="text" name="x" /></h2>
<h2>File: <input type="file" name="file1" /></h2>
<h2>Parameter y: <input type="text" name="y" /></h2>
<h2><input type="submit" value="send" /></h2>
</form>
</body>
</html>
upload3.html
15
Upload3.java
List formParams = new LinkedList();
List files = new LinkedList();
We’ll store parameters and fileitems
in those lists
List items = upload.parseRequest(request);
Iterator it = items.iterator();
while (it.hasNext()) {
FileItem item = (FileItem) it.next();
if (item.isFormField())formParams.add(item);
else files.add(item);
}
Attach the lists to the request
request.setAttribute("formParams",formParams);
request.setAttribute("files",files);
this.getServletContext().getRequestDispatcher
("/WEB-INF/jsp/upload3.jsp").forward(request,response);
16
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page isELIgnored="false" %>
<html><head><title>Submitted Parameters</title></head>
<body><h1>Submitted Parameters:</h1><ol>
<c:forEach var="item" items="${formParams}">
<li><b>Parameter</b>:
name:<i>${item.fieldName}</i>,
value:<i>${item.string}</i></li>
</c:forEach>
<c:forEach var="item" items="${files}">
<li><b>File</b>:
name:<i>${item.name}</i>,
length:<i>${item.size}</i>,
size:<i>type:${item.contentType}</i></li>
</c:forEach>
/WEB-INF/jsp/upload3.jsp17
</ol></body></html>
A Question
• What is the advantage of redirecting to JSP
pages that are under WEB-INF?
- Pages under the WEB-INF are not accessible
- You can make sure no one invokes the JSP directly
- You can hide the implementation
18
Programmatic Security
with Servlets
19
Programmatic-Security Methods
• The Servlet API contains several accessories for
handling programmatic security:
- getRemoteUser()
- isUserInRole(String role)
Returns the authenticated user or
null if none exists
- getAuthType()
• These are all methods of HttpServletRequest
• To enable user authentication (even for public URLs),
provide a link to some protected page
20
An Example: Security Constraints
in web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Firm People</web-resource-name>
<url-pattern>/login.html</url-pattern>
</web-resource-collection>
Some secured
<auth-constraint>
resources
<role-name>employees</role-name>
<role-name>managers</role-name>
</auth-constraint>
Roles that can view those
</security-constraint>
web.xml
resources
Roles, some users and their roles are defined in /conf/tomcat-users.xml
21
An Example: Security Constraints
in web.xml
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login</form-login-page>
<form-error-page>/login?fail=fail</form-error-page>
</form-login-config>
</login-config>
Roles used in this
<security-role>
application
<role-name>managers</role-name>
(not required)
</security-role>
<security-role>
<role-name>employees</role-name>
web.xml
</security-role>
22
public class FirmServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse
res) throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("<html><head><title>Firm</head><body>");
out.println("<h1>Hello.</h1>");
String username = req.getRemoteUser();
Returns the authenticated user or
null if none exists
if(username==null) {
out.println("<p><img src=\"images/visitor.gif\"/></p>");
out.println("<h3><a href=\"login.html\">Login</a></h3>");
out.println("</body></html>");
return; }
FirmServlet
23
This is ugly. This is why attributes in HTML can be single- or
double-quoted. Same goes for strings in many scripting
languages (watch out for escaping differences, though!)
if(req.isUserInRole("employees")) {
out.println("<p><img src=\"images/employee.gif\"/></p>");
out.print("<h2>Welcome Employee " + username + "!</h2>");
}
if(req.isUserInRole("managers")) {
out.println("<p><img src=\"images/manager.gif\"/></p>");
out.print("<h2>Executive average salary: 42764NIS!</h2>");
}
out.print("<h3><a href=\"endsession\">Log Out</a></h3>");
out.println("</body></html>");
}
}
FirmServlet
24
public class LoginServlet extends HttpServlet { LoginServlet.java
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("<html><head><title>Login</title></head><body>");
if(req.getParameter("fail")!=null)
out.print("<h2>Login Failed. Try Again.</h2>");
out.println("<form action=\"j_security_check\" method=\"post\">" +
"<p>Login: <input type=\"text\" name=\"j_username\"/></p>" +
"<p>Password: <input type=\"password\" name=\"j_password\"/></p>" +
"<p><input type=\"submit\" value=\"Log In\"/></p>" +
"</form></body></html>");
}
Notice that though this code contains no getSession() calls, the server
tries to put session-cookie as a part of the FORM authorization
25
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
this.doGet(req,res);
}
}
LoginServlet.java
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
web.xml
26
EndSession.java
public class EndSession extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
Tomcat’s session
HttpSession session = req.getSession(false);
implementation
if(session!=null) {
saves the user
session.invalidate();
details in the
session but not as
}
attributes.
res.sendRedirect("firm");
<servlet>
Recovering this data is
}
done by calling the
<servlet-name>EndSession</servlet-name>
mentioned request
<servlet-class>EndSession</servlet-class>
methods, but of
</servlet>
course invalidating
<servlet-mapping>
the session leads to
<servlet-name>EndSession</servlet-name>
logout
<url-pattern>/endsession</url-pattern>
27
</servlet-mapping>
web.xml
<html>
<head>
<title>Logged On</title>
</head>
<body>
<h1>You are logged on!</h1>
<p><a href="firm">Back to the firm page.</a></p>
</body>
</html>
login.html
28
Filters
29
Filters in Servlet API
• Filters are used to dynamically intercept requests
and responses
• A filter that applies to a URL u typically acts as
follows given a request for u
- performs some actions before the processing of u
- passes the request handling to the next filter
- The last filter passes the request to u itself
- performs some actions after the processing of u
30
Client
Request
Response
Container
Filter 1
Filter 2
Filter 3
Servlet/JSP/HTML
31
public class FilterExample implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
...
}
public void destroy() {
...
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
...
Before other elements in
chain.doFilter(request, response);
...
}}
After other elements in way
“up”
way “down”
FilterExample.java
32
Registering a Filter
<filter>
<filter-name>Example Filter</filter-name>
<filter-class>FilterExample</filter-class>
</filter>
You can also add an
<init-param>
<filter-mapping>
<filter-name>Example Filter</filter-name>
<url-pattern>/images/*</url-pattern>
</filter-mapping>
web.xml
element like we
saw in servlets
and JSPs.
33
What Can we Do with Filters?
• Examine and log requests
• Modify request headers and properties
• Modify the response headers and response data
• Block requests
• And more...
Open FilterExample.java.
Check the result of calling http://localhost/dbi/images/image1.gif in
the server’s logs
34
Notes About Filters
• The order of the filters in the chain is the same as the
order that filter mappings appear web.xml
• The life cycle of filters is similar to that of Servlets
• Filters typically do not themselves create responses,
although they can
• The request and response arguments of doFilter are
actually of type HttpServletRequest and
HttpServletResponse
• The FilterConfig interface is used to read initialization
parameters
- Those are set in web.xml
35
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse)response;
HttpServletRequest req = (HttpServletRequest)request;
URI is the part of the URL
String URI = req.getRequestURI();
following the http://host:port
if (URI.endsWith(filterConfig.getInitParameter("type")) &&
(req.getParameter("nofilter") == null)) {
Only for filetypes <type> with no
res.setContentType("text/html");
“nofilter” parameter in the
PrintWriter out = res.getWriter();
query
out.println("<html><head><title>ImageFilter</title></head><body>");
out.println("<h2>Image filename = " + URI + "</h2>\n");
out.println("<img src=\"" + URI.substring(1 + URI.lastIndexOf("/")) +
"?nofilter\" />");
out.println("</body></html>"); }
We have to add the “nofilter” query so that
ImageFilter.java
the filter won’t work
again on the <img>
36
Default filter chaining.
else {chain.doFilter(request, response); }}
This time next element in the
<filter>
chain is not a filter but the
original URL
<filter-name>fImageFilter</filter-name>
<filter-class>ImageFilter</filter-class>The Filter applies only to .gif files
<init-param>
in /dbi/images/ but not for
<param-name>type</param-name>
<param-value>.gif</param-value>
</init-param>
other files on the same
directory such as .txt
A url-pattern of /images2/*.gif
</filter>
doesn’t work.
That’s why we check the suffix in
the Java code
<filter-mapping>
<filter-name>fImageFilter</filter-name>
Open /images2/image1.gif
<url-pattern>/images2/*</url-pattern>
Open /images2/joke1.txt
</filter-mapping>
web.xml
37