Transcript ppt - CS

Uploading Files with
Servlets
Read more about the FileUpload API
1
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
2
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
3
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
4
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
5
try {
List items = upload.parseRequest(request);
In our exmaple, we
Iterator it = items.iterator();
expect a single
FileItem item = (FileItem) it.next();
parameter
response.setContentType(item.getContentType());
We use an
response.setContentLength((int)item.getSize());
Output
stream and
InputStream is = item.getInputStream();
OutputStream os = response.getOutputStream(); not the out
PrintWriter
byte[] buffer = new byte[4096]; int read = -1;
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.java 6
}}}
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
7
List items = upload.parseRequest(request);
Iterator it = items.iterator();
This time we use a loop
out.println("<ol>");
since there’re 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>");
8
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
• The next example also uses JSTL
9
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.
10
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
11
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);
12
<%@ 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.jsp13
</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
14
Programmatic Security
with Servlets
15
Programmatic-Security Methods
• 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
16
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
17
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>
<security-role>
Roles used in this
<role-name>managers</role-name>
application
</security-role>
(recommended but not a
<security-role>
necessity)
<role-name>employees</role-name>
web.xml
</security-role>
18
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
19
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
20
public class LoginServlet 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>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() LoginServlet.java
calls, the server
tries to put session-cookie as a part of the FORM authorization
21
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
22
public class EndSession extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
HttpSession session = req.getSession(false);
if(session!=null)
Tomcat’s session implementation
session.invalidate();
saves the user details in the session
res.sendRedirect("firm");
but not as attributes.
}
Recovering this data is done by calling
<servlet>
}
EndSession.java
the mentioned request
methods, but
<servlet-name>EndSession</servlet-name>
of course invalidating the session
<servlet-class>EndSession</servlet-class>
leads to logout
</servlet>
<servlet-mapping>
<servlet-name>EndSession</servlet-name>
<url-pattern>/endsession</url-pattern>
23
</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
24
Managing User
Authentication with
Tomcat
25
A Reminder
create table users (
username varchar(30) not null primary key,
pass
varchar(30) not null
);
create table users_roles (
username varchar(30) not null,
role
varchar(30) not null,
primary key (username,role),
foreign key (username) references users(username)
);
26
In tomcat-base/conf/server.xml
<Realm
className="org.apache.catalina.realm.JDBCRealm"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:snoopy/snoopy@sol4:1521:stud"
userTable="users"
userNameCol="username"
userCredCol="pass"
userRoleTable="users_roles"
roleNameCol="role"/>
27
User Tables
• What if we do not have one table that stores
usernames and passwords?
• What if we only have one role for the all users?
• What if we wanted the above information to be
stored in several tables (e.g., users and
administrators)?
• The idea is to use views rather than real tables
28
Creating Views
create view up as
(select username u, pass p from users
union
Unifies the user/password data
from 2 tables
select u,p from admin);
Default role for “simple” users
create view ur as
(select username u, 'myRole' r from users
union
select u, 'admin' r from admin);
Default role for “admin” users
29
Fixing server.xml
<Realm
className="org.apache.catalina.realm.JDBCRealm"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:snoopy/snoopy@sol4:1521:stud"
userTable="up"
userNameCol="u"
userCredCol="p"
userRoleTable="ur"
roleNameCol="r"/>
30