Servlets Chapt 4

Download Report

Transcript Servlets Chapt 4

Servlets chapt4
Information retrieval
Handling requests
• To build a successful webapp you
probably need to know about
– The server that will be running your servlets
– And the environment (eg., O.S., hardware,
etc.)
– Specifics about the client and the nature of
the requests
Methods providing servlets with
information
• These methods improve on the CGI environment
variables by allowing stronger type-checking.
• CGI has delays caused by the need to pre-calculate
environment variables whether they are used or not.
• A CGI program acts independently of the server, once it
is launched. Only standard output is available to the
program.
• A servlet may be inside the server, or a connected
process and so can make ad hoc requests for
information from the server.
Type checking comparison, perl, C
and java
• Perl checks a port number with code like
$port =$ENV(‘SERVER_PORT’);
Where $port is untyped.
• A CGI program in C uses,
char *port=getenv(“SERVER_PORT”);
The chance of an accidental error is high, for example if the
environment variable is misspelled, or a datatype mismatch.
• Java code is
int port =req.getServerPort();
And the compiler can insure no spelling errors and correct datatyping.
Table in text pg 73
• Text table shows how servlet functions
map to environment variables.
Partial table
SERVER_NAME
req.getServerName()
SERVER_PROTOCOL
req.getProtocol()
SERVER_PORT
req.getServerPort()
PATH_INFO
req.getPathInfo()
REMOTE_HOST
req.getRemoteHost()
Init parameters
• Init parameters may be associated with specific servlets
by name and are set in web.xml and may be used in
init() to set initial values or customize behavior.
• A servlet uses getInitialParameter() method to access its
initial parameters:
public String ServletConfig. getInitialParameter(String
name)
This method returns the value of the named parameter or
null if it doesn’t exist.
Since GenericServlet implements ServletConfig interface, it
can call the method directly. Initial parameters could be
used to identify details of a database connection for a
servlet. (like port, host, db, user, password, proxy)
Init parameters
import java.io.*;
import java.util.*;
import javax.servlet.*;
public class InitSnoop extends GenericServlet {
// No init() method needed
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println("Init Parameters:");
Enumeration list = getInitParameterNames();
while (list.hasMoreElements()) {
String name = (String) list.nextElement();
out.println(name + ": " + getInitParameter(name));
}
}
}
Servlet tag in web.xml
<servlet>
<servlet-name>InitSnoop</servlet-name>
<description>
A simple servlet that looks for its init parameters.
</description>
<servlet-class>
InitSnoop
</servlet-class>
<init-param>
<param-name>initialguy
</param-name>
<param-value>12345</param-value>
</init-param>
</servlet>
Screenshot of tomcat/initsnoop
ServerSnoop
import java.io.*;
import java.util.*;
import javax.servlet.*;
public class ServerSnoop extends GenericServlet {
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
ServletContext context = getServletContext();
out.println("req.getServerName(): " + req.getServerName());
out.println("req.getServerPort(): " + req.getServerPort());
out.println("context.getServerInfo(): " + context.getServerInfo());
out.println("getServerInfo() name: " +
getServerInfoName(context.getServerInfo()));
out.println("getServerInfo() version: " +
getServerInfoVersion(context.getServerInfo()));
out.println("context.getAttributeNames():");
Enumeration list = context.getAttributeNames();
while (list.hasMoreElements()) {
String name = (String) list.nextElement();
out.println(" context.getAttribute(\"" + name + "\"): " +
context.getAttribute(name)); } }
ServerSnoop slide2
private String getServerInfoName(String serverInfo) {
int slash = serverInfo.indexOf('/');
if (slash == -1) return serverInfo;
else return serverInfo.substring(0, slash);
}
private String getServerInfoVersion(String serverInfo) {
// Version info is everything between the slash and the space
int slash = serverInfo.indexOf('/');
if (slash == -1) return null;
int space = serverInfo.indexOf(' ', slash);
if (space == -1) space = serverInfo.length();
return serverInfo.substring(slash + 1, space);
}
}
ServerSnoop servlet on Tomcat
Creating a temp file using
servletcontext
• Each servlet context gets its own working (temp) directory which is
mapped by the attribute javax.servlet.context.tempdir
//get directory
File
dir=(File)getServletContext().getAttribute(“javax.servlet.context.temp
dir”);
//create a file
File f=File.createTempFile(“xxx”,”.tmp”,dir);
//get ready to write to it
FileOutputStream fout=new FileOutputStream(f);
Here’s the entire WriteToFile servlet
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class WriteToFile extends GenericServlet {
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
File dir=(File)getServletContext().getAttribute("javax.servlet.context.tempdir");
File f=File.createTempFile("xxx",".tmp",dir);
FileOutputStream fout=new FileOutputStream(f);
//now write stuff to file
//and don’t forget to close the file
fout.close();
}
public String getServletInfo() {
return "A servlet that writes to a file in work/ dir";
}
}
Running WriteToFile servlet: note
file path
WriteToFile servlet output to client
File Location- note URL
Get a file’s location
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class FileLocation extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
if (req.getPathInfo() != null) {
out.println("The file \"" + req.getPathInfo() + "\"");
out.println("Is stored at \"" + req.getPathTranslated() + "\"");
}
else {
out.println("Path info is null, no file to lookup");
}
}
}
http://localhost:8080/myservlets/FileLocation/pathinfo/morepathinfo/Hello.txt
Putting a few tricks together
• An init parameter called key can be used
to see if a servlet should be run on a
particular server. The key might “fit” the
server’s IP and port information for
example.
• The KeyedServerLock servlet uses these
tricks.
KeyedServerLock – obviously my version is
pirated
KeyedServerLock
import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
public class KeyedServerLock extends GenericServlet {
// This servlet has no class or instance variables
// associated with the locking, so as to simplify
// synchronization issues.
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
// The piracy check shouldn't be done in init
// because name/port are part of request.
String key = getInitParameter("key");
String host = req.getServerName();
int port = req.getServerPort();
KeyedServerLock
// Check if the init parameter "key" unlocks this server.
if (! keyFitsServer(key, host, port)) {
// Explain, condemn, threaten, etc.
out.println("Pirated!");
}
else {
// Give 'em the goods
out.println("Valid");
// etc...
}
}
// This method contains the algorithm used to match a key with
// a server host and port. This example implementation is extremely
// weak and should not be used by commercial sites.
//
private boolean keyFitsServer(String key, String host, int port) {
if (key == null) return false;
long numericKey = 0;
try {
numericKey = Long.parseLong(key);
}
catch (NumberFormatException e) {
return false;
}
KeyedServerLock
// The key must be a 64-bit number equal to the logical not (~)
// of the 32-bit IP address concatenated with the 32-bit port number.
byte hostIP[];
try {
hostIP = InetAddress.getByName(host).getAddress();
}
catch (UnknownHostException e) {
return false;
}
// Get the 32-bit IP address
long servercode = 0;
for (int i = 0; i < 4; i++) {
servercode <<= 8;
servercode |= hostIP[i];
}
// Concatentate the 32-bit port number
servercode <<= 32;
servercode |= port;
// Logical not
long accesscode = ~numericKey;
// The moment of truth: Does the key match?
return (servercode == accesscode);
}
}
KeyedServerUnlock is the companion
for KeyedServerLock –get the key
Init param holds key… I got the key from the
keyedserverunlock servlet
<servlet>
<servlet-name>
KeyedServerLock
</servlet-name>
<servlet-class>
KeyedServerLock
</servlet-class>
<init-param>
<param-name>key
</param-name>
<param-value>
9151314447111823249
</param-value>
<description>
The key value to unlock the servlet's functionality
</description>
</init-param>
</servlet>
Using serverlock and serverunlock together:
Not sure why keys are off by one!!!
Valid…subtracted one before compare
• Code from serverlock
long servercode = 0;
for (int i = 0; i < 4; i++) {
servercode <<= 8;
servercode |= hostIP[i]; }
// Concatentate the 32-bit port number
servercode <<= 32;
servercode |= port;
• Code from serverunlock
long servercode = 0;
for (int i = 0; i < 4; i++) {
servercode <<= 8;
servercode |= hostIP[i]; }
// Concatentate the 32-bit port number
servercode <<= 32;
servercode |= port;
// The key is the logical not
return ~servercode;
Getting info about the client
machine
• ServletRequest methods getRemoteAddr() and
getRemoteHost() both return strings and can be
used to get some info about the client machine.
• The client IP or remote host name can further
be converted into a java InetAddress using its
method getByName()
• The next example considers whether we should
allow access to restricted material based on the
country from which the request comes.
Getting client information: is this client
allowed to download?
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
// ...Some introductory HTML...then Get the client's hostname
String remoteHost = req.getRemoteHost();
// See if the client is allowed
if (! isHostAllowed(remoteHost)) {
out.println("Access <BLINK>denied</BLINK>"); }
else {
out.println("Access granted");
// Display download links, etc...
} }
// Disallow hosts ending with .cu, .ir, .iq, .kp, .ly, .sy, and .sd.
private boolean isHostAllowed(String host) {
return (!host.endsWith(".cu") &&
!host.endsWith(".ir") &&
!host.endsWith(".iq") &&
!host.endsWith(".kp") &&
!host.endsWith(".ly") &&
!host.endsWith(".sy") &&
!host.endsWith(".sd")); }
Getting client information
Personalized Welcome servlet
• Uses req.getRemoteUser() with a
hashtable to keep track of multiple visits in
order to greet a user by name.
• (I think) in order to send a greeting other
than “welcome” this needs to be combined
with the server requiring a name/pw to
access the resource
Personalized Welcome servlet (doGet())
String remoteUser = req.getRemoteUser();
if (remoteUser == null) {
out.println("Welcome!"); }
else {
out.println("Welcome, " + remoteUser + "!");
Date lastAccess = (Date) accesses.get(remoteUser);
if (lastAccess == null) {
out.println("This is your first visit!");
}
else { out.println("Your last visit was " +
accesses.get(remoteUser));
}
if (remoteUser.equals("PROFESSOR FALKEN")) {
out.println("Shall we play a game?");
}
accesses.put(remoteUser, new Date()); }
Getting user information
Getting parameters
Getting parameters
• <FORM Method=GET
Action="http://localhost:8080/servlet/ParameterS
noop">
• a parameter <input type=text name="word">
• another parameter <input type=text
name="value">
• an another <input type=text name="thing">
• <input type =submit>
• </form>
Parameters, continued
ParameterSnoop.java
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println("Query String:");
out.println(req.getQueryString());
out.println();
out.println("Request Parameters:");
Enumeration enum = req.getParameterNames();
while (enum.hasMoreElements()) {
String name = (String) enum.nextElement();
String values[] = req.getParameterValues(name);
if (values != null) {
for (int i = 0; i < values.length; i++) {
out.println(name + " (" + i + "): " + values[i]); } } } }
More values of same parameters
With more values of parameters
The Form revised
<FORM Method=GET
Action="http://localhost:8080/servlet/ParameterSnoop">
a parameter <input type=text name="word"><p>
same parameter <input type=text name="word">
<p>same again <input type=text name="word"><p>
another parameter <input type=text name="value">
<p>
and same parameter <input type=text name="value">
a final <input type=text name="thing">
<input type =submit>
</form>
What happens to ‘&’ if entered as a
parameter?
Seems to know what to do with
them
Uploading a file
form
• <FORM Method=Post
• ACTION="http://csci345.oneonta.edu:8080/myex
amples/UploadTest"
• ENCTYPE="multipart/form-data">
• Name? <input type=text name=submitter><br>
• what file? <input type=file name=file><br>
• <input type=submit>
• </form>
form in IE after browse and select
UploadTest.java
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
try {
// Blindly take it on faith this is a multipart/form-data request
// Construct a MultipartRequest to help read the information.
// Pass in the request, a directory to save files to, and the
// maximum POST size we should attempt to handle.
// Here we (rudely) write to the server root and impose 5 Meg limit.
MultipartRequest multi =
new MultipartRequest(req, ".", 5 * 1024 * 1024);
out.println("<HTML>");
out.println("<HEAD><TITLE>UploadTest</TITLE></HEAD>");
out.println("<BODY>");
out.println("<H1>UploadTest</H1>");
// Print the parameters we received
out.println("<H3>Params:</H3>");
out.println("<PRE>");
Enumeration params = multi.getParameterNames();
while (params.hasMoreElements()) {
String name = (String)params.nextElement();
String value = multi.getParameter(name);
out.println(name + " = " + value);
}
out.println("</PRE>");
UploadTest.java
// Show which files we received
out.println("<H3>Files:</H3>");
out.println("<PRE>");
Enumeration files = multi.getFileNames();
while (files.hasMoreElements()) {
String name = (String)files.nextElement();
String filename = multi.getFilesystemName(name);
String type = multi.getContentType(name);
File f = multi.getFile(name);
out.println("name: " + name);
out.println("filename: " + filename);
out.println("type: " + type);
if (f != null) {
out.println("length: " + f.length());
}
out.println();
}
out.println("</PRE>");
}
catch (Exception e) {
out.println("<PRE>");
e.printStackTrace(out);
out.println("</PRE>");
}
out.println("</BODY></HTML>");
}
Now what?
• On Tomcat files are copied to bin directory
and you’ll need to go delete them if you
don’t want them.
• You could put a db entry for this file
including size, name, etc and provide for
user download.
The next dozen slides
• I repeated Hunter’s work but used Jakarta
classes.
Jakarta links
• http://commons.apache.org/fileupload/
• http://commons.apache.org/fileupload/using.html
• Each file item has a number of properties that might be
of interest for your application. For example, every item
has a name and a content type, and can provide an
InputStream to access its data. On the other hand, you
may need to process items differently, depending upon
whether the item is a regular form field - that is, the data
came from an ordinary text box or similar HTML field - or
an uploaded file. The FileItem interface provides the
methods to make such a determination, and to access
the data in the most appropriate manner.
• Before you can work with the uploaded items, of
course, you need to parse the request itself.
Ensuring that the request is actually a file upload
request is straightforward. FileUpload providesa
static method to do this.
// Check that we have a file upload request
boolean isMultipart =
ServletFileUpload.isMultipartContent(request);
The simplest usage scenario
• Uploaded items should be retained in memory as long as they are
reasonably small.
• Larger items should be written to a temporary file on disk.
• Very large upload requests should not be permitted.
• The built-in defaults for the maximum size of an item to be retained
in memory, the maximum permitted size of an upload request, and
the location of temporary files are acceptable.
• Handling a request in this scenario couldn't be much simpler:
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List /* FileItem */ items = upload.parseRequest(request);
more control
• If your usage scenario is close to the simplest case, described
above, but you need a little more control, you can easily customize
the behavior of the upload handler or the file item factory or both.
The following example shows several configuration options:
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Set factory constraints
factory.setSizeThreshold(yourMaxMemorySize);
factory.setRepository(yourTempDirectory);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Set overall request size constraint
upload.setSizeMax(yourMaxRequestSize);
// Parse the request
List /* FileItem */ items = upload.parseRequest(request);
To configure the factory all at once
• Of course, each of the configuration methods is
independent of the others, but if you want to
configure the factory all at once, you can do that
with an alternative constructor, like this:
// Create a factory for disk-based file items
DiskFileItemFactory factory = new
DiskFileItemFactory( yourMaxMemorySize,
yourTempDirectory);
Processing the uploaded items
• Once the parse has completed, you will have a List of file items that
you need to process. In most cases, you will want to handle file
uploads differently from regular form fields, so you might process the
list like this:
// Process the uploaded items
Iterator iter = items.iterator(); while (iter.hasNext())
{ FileItem item = (FileItem) iter.next(); if (item.isFormField()) {
processFormField(item); } else { processUploadedFile(item); } }
For a regular form field, you will most likely be interested only in the
name of the item, and its String value. As you might expect,
accessing these is very simple.
// Process a regular form field
if (item.isFormField()) { String name = item.getFieldName(); String
value = item.getString(); ... }
For a file upload
• For a file upload, there are several different
things you might want to know before you
process the content. Here is an example of
some of the methods you might be interested in.
// Process a file upload if (!item.isFormField()) {
String fieldName = item.getFieldName(); String
fileName = item.getName(); String contentType
= item.getContentType(); boolean isInMemory =
item.isInMemory(); long sizeInBytes =
item.getSize(); ... }
process the content as a stream
•
With uploaded files, you generally will not want to access them via memory,
unless they are small, or unless you have no other alternative. Rather, you
will want to process the content as a stream, or write the entire file to its
ultimate location. FileUpload provides simple means of accomplishing both
of these.
// Process a file upload
if (writeToFile) { File uploadedFile = new File(...); item.write(uploadedFile); }
else { InputStream uploadedStream = item.getInputStream(); ...
uploadedStream.close(); }
• Note that, in the default implementation of FileUpload, write() will attempt to
rename the file to the specified destination, if the data is already in a
temporary file. Actually copying the data is only done if the the rename fails,
for some reason, or if the data was in memory.
• If you do need to access the uploaded data in memory, you need simply call
the get() method to obtain the data as an array of bytes.
• // Process a file upload in memory byte[] data = item.get(); ...
Streaming api: Parsing the request
• First of all, do not forget to ensure, that a request
actually is a a file upload request. This is typically done
using the same static method, which you already know
from the traditional API.
• // Check that we have a file upload request
boolean isMultipart =
ServletFileUpload.isMultipartContent(request);
• Now we are ready to parse the request into its
constituent items. Here's how we do it:
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
Parse the request
// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) { FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) { System.out.println("Form field " +
name + " with value " + Streams.asString(stream) + "
detected."); }
else { System.out.println("File field " + name + " with file
name " + item.getName() + " detected.");
// Process the input stream ...
}}
Additional notes
• Many details were omitted from jakarta
commons info… like the need for Jakartacommons-io jar file.
• Try..catch clauses are needed.
• Note imports.
• Only minimal upload service provided.
Success!
And the file really is there…
The servlet… note imports
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.*;
import org.apache.commons.fileupload.util.*;
public class FileUpload extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println(“servlet upload only supports http post operation”<br>”);
out.println("<HTML><BODY>");
out.println("</BODY></HTML>");
}//doGet
Post
public void doPost(HttpServletRequest request, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
String result="";
PrintWriter out = res.getWriter();
// Get the current session object, create one if necessary
out.println("<HTML><BODY>");
// Create a factory for disk-based file items
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Set factory constraints factory.setSizeThreshold(yourMaxMemorySize); factory.setRepository(yourTempDirectory);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Set overall request size constraint upload.setSizeMax(yourMaxRequestSize);
// Parse the request
try{
List /* FileItem */ items = upload.parseRequest(request);
// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext())
{ FileItem item = (FileItem) iter.next();
if (item.isFormField()) { result= processFormField(item); }
else { result =processUploadedFile(item); } }
}//try
catch(Exception e){out.println("upload error"+e.toString());}
out.println(result);
}
utility functions
public String processFormField(FileItem item){
// Process a form field
if (item.isFormField()) { String name = item.getFieldName(); String value = item.getString();
return "name:"+name+"value:"+value;}
else return "";
}
public String processUploadedFile(FileItem item){
// Process a file upload
boolean writeToFile=true;
File dir=(File)getServletContext().getAttribute("javax.servlet.context.tempdir");
//create a file
//File uploadedFile=File.createTempFile("upload",".tmp",dir);
if (writeToFile)
{
try{
File uploadedFile=File.createTempFile("upload",".tmp",dir);
item.write(uploadedFile);
return "successfully written to"+dir+ "upload.tmp";}
catch(Exception e)
{
return e.toString();}
}//
//else { InputStream uploadedStream = item.getInputStream(); ... uploadedStream.close(); }
return "did not write";
}
}
Need to do…
• Multipart
• Stream
• Upload to db--- no documentation
available at Jakarta Commons for this.
Tomcat servlet examples
RequestHeaderExample
RequestHeaderExample
import java.io.*; import java.util.*; import javax.servlet.*;
import javax.servlet.http.*; public class
RequestHeaderExample extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException { response.setContentType("text/html");
PrintWriter out = response.getWriter();
Enumeration e = request.getHeaderNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = request.getHeader(name);
out.println(name + " = " + value); } } }
RequestInfoExample
RequestInfoExample
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>"); out.println("<body>");
out.println("<head>");
out.println("<title>Request Information Example</title>");
out.println("</head>"); out.println("<body>");
out.println("<h3>Request Information Example</h3>");
out.println("Method: " + request.getMethod()); out.println("Request
URI: " + request.getRequestURI()); out.println("Protocol: " +
request.getProtocol());
out.println("PathInfo: " + request.getPathInfo());
out.println("Remote Address: " + request.getRemoteAddr());
out.println("</body>"); out.println("</html>");
}
ViewFile
• I had some problems with this example despite the
demos in the text and Tomcat.
• By changing the servlet mapping to /
which makes ViewFile the default servlet for the context I
did get getPath() etc to work.
• I looked in tomcat’s examples and saw that the url
mapping had to be: /ViewFile/* which allows pathInfo to
be entered after the name of a servlet.
• The next couple of slides just use / for the mapping
which means pathInfo is not available and you need to
use other tricks to find the filename.
http://csci345.oneonta.edu:8080/myexamples/xxx.txt
http://csci345.oneonta.edu:8080/myexamples/.../xxx.txt
Viewing path information, continued
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// Use a ServletOutputStream because we may pass binary information
ServletOutputStream out = res.getOutputStream();
res.setContentType("text/html");
// Get the file to view
String name=getServletName();
out.println("servlet name"+name+"<br>");
String path=req.getServletPath();
out.println("servlet path"+path+"<br>");
String file1 = req.getPathInfo();
out.println("req.getPathInfo()"+file1+"<br>");
String s4=req.getPathTranslated();
out.println("pathtranslated is"+s4+"<br>");
//file=file.substring(1);
// No file, nothing to view
if (file1 == null) {
out.println("No file to view");
return;
}
ShowFile servlet
ShowFile servlet
Servlet code
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// Use a ServletOutputStream because we may pass binary information
ServletOutputStream out = res.getOutputStream();
//servlet name
String name=getServletName();
//possibly other path info
String path=req.getServletPath();
String file=path.substring(1);
if(file.length()>name.length()){
String tmp=file.substring(0,name.length());
if(tmp.equals(name)&&file.charAt(name.length())=='/')
file=file.substring(name.length()+1);
}
if (file == null) {
out.println("No file to view");
return; }
// Get and set the type of the file
String contentType = getServletContext().getMimeType(file);
res.setContentType(contentType);
// Return the file
try {
ServletUtils.returnFile(file, out); }
catch (FileNotFoundException e) {
out.println("File not found"); }
catch (IOException e) {
out.println("Problem sending file: " + e.getMessage());
} }
ShowFile servlet
• File needs to be in tomcat/bin
ViewFile working fine
ViewFile
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.oreilly.servlet.ServletUtils;
public class ViewFile extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// Use a ServletOutputStream because we may pass binary information
ServletOutputStream out = res.getOutputStream();
// Get the file to view
String file = req.getPathTranslated();
// No file, nothing to view
if (file == null) {
out.println("No file to view");
return; }
// Get and set the type of the file
String contentType = getServletContext().getMimeType(file);
res.setContentType(contentType);
// Return the file
try {
ServletUtils.returnFile(file, out); }
catch (FileNotFoundException e) {
out.println("File not found");
}
catch (IOException e) {
out.println("Problem sending file: " + e.getMessage()); } }}
ViewFile mapping: file located in
root of webapp
<servlet-mapping>
<servlet-name>ViewFile</servlet-name>
<url-pattern>/ViewFile/*</url-pattern>
</servlet-mapping>
UnsafeViewResource provides no
protection of server resources
ViewResource
• Uses code in com.oreilly file getResource
to check that the file is not coming from a
path to WEB-INF or META-INF
ViewResource- error trying to get
web.xml
Just a note…unlike browser, java filenames
are case sensitive unless otherwise coded
Hardcoding the content-type
• Hardcoding the content-type to
application-octet-stream should give a pop
up in browser—where to save the fileexcept in ie
• Makes this a generic file server servlet
Ie ignores contenttype and just
displays it
In Netscape, for example
ViewResource: viewing xml
And viewing a gif:
ViewResource
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// Use a ServletOutputStream because we may pass binary information
ServletOutputStream out = res.getOutputStream();
res.setContentType("text/plain"); // sanity default
// Get the resource to view
URL url = null;
try {
url = ServletUtils.getResource(getServletContext(), req.getPathInfo());
catch (IOException e) {
res.sendError(
res.SC_NOT_FOUND,
"Extra path info must point to a valid resource to view: " +
e.getMessage());
return; }
// Connect to the resource
URLConnection con = url.openConnection();
con.connect();
// Get and set the type of the resource
String contentType = con.getContentType();
res.setContentType(contentType);
// Return the resource
try {
ServletUtils.returnURL(url, out); }
catch (IOException e) {
res.sendError(res.SC_INTERNAL_SERVER_ERROR,
"Problem sending resource: " + e.getMessage()); } }
}