Tomcat Interview Questions – 1
How do you create multiple virtual hosts?
If
you want tomcat to accept requests for different hosts e.g.,
www.myhostname.com then you must 0. create ${catalina.home}/www/appBase ,
${catalina.home}/www/deploy, and
${catalina.home}/conf/Catalina/www.myhostname.com
- add a host entry in the server.xml file
1 | < Host appBase = "www/appBase" name = "www.myhostname.com" /> |
- Create the the following file under conf/Catalina/www.myhostname.com/ROOT.xml
1 | <? xml version = "1.0" encoding = "UTF-8" ?> |
4 | docBase = "www/deploy/mywebapp.war" |
5 | reloadable = "true" antiJARLocking = "true" > |
Add any parameters specific to this hosts webapp to this context file
- put your war file in ${catalina.home}/www/deployWhen
tomcat starts, it finds the host entry, then looks for any context
files and will start any apps with a context. To add more sites just
repeat and rinse, all webapps can share the same war file location and
appbase
How will you load properties file?
* Use a ResourceBundle.
See the Java docs for the specifics of how the ResourceBundle class
works. Using this method, the properties file must go into the
WEB-INF/classes directory or in a jar file contained in the WEB-INF/lib
directory.
* Another way is to use the method
getResourceAsStream() from the ServletContext class. This allows you
update the file without having to reload the webapp as required by the
first method. Here is an example code snippet, without any error
trapping:
4 | InputStream is = getServletContext().getResourceAsStream( "/more/cowbell.properties" ); |
5 | Properties p = new Properties(); |
Can I set Java system properties differently for each webapp?
No.
If you can edit Tomcat’s startup scripts, you can add “-D” options to
Java. But there is no way to add such properties in web.xml or the
webapp’s context.
How do I configure Tomcat to work with IIS and NTLM?
Follow the standard instructions for when the isapi_redirector.dll Configure IIS to use “integrated windows security”
In server.xml, make sure you disable tomcat authentication:
1 | < Connector port = "8009" enableLookups = "false" redirectPort = "8443" protocol = "AJP/1.3" tomcatAuthentication = "false" /> |
How can I access members of a custom Realm or Principal?
When
you create a custom subclass of RealmBase or GenericPrincipal and
attempt to use those classes in your webapp code, you’ll probably have
problems with ClassCastException. This is because the instance returned
by request.getUserPrincipal() is of a class loaded by the server’s
classloader, and you are trying to access it through you webapp’s
classloader. While the classes maybe otherwise exactly the same,
different (sibling) classloaders makes them different classes.
This
assumes you created a My“Principal class, and put in Tomcat’s
server/classes (or lib) directory, as well as in your webapp’s
webinf/classes (or lib) directory. Normally, you would put custom realm
and principal classes in the server directory because they depend on
other classes there.
Here’s what you would like to do, but it throws ClassCastException:
1 | MyPrincipal p = request.getUserPrincipal(); |
2 | String emailAddress = p.getEmailAddress(); |
Here are 4 ways you might get around the classloader boundary:
- Reflection
1 | Principal p = request.getUserPrincipal(); |
2 | String emailAddress = p.getClass().getMethod( "getEmailAddress" , null ).invoke(p, null ); |
- Move classes to a common classloaderYou
could put your custom classes in a classloader that is common to both
the server and your webapp – e.g., either the “common” or bootstrap
classloaders. To do this, however, you would also need to move the
classes that your custom classes depend on up to the common classloader,
and that seems like a bad idea, because there a many of them and they a
core server classes.
- Common Interfaces
Rather than move
the implementing custom classes up, you could define interfaces for
your customs classes, and put the interfaces in the common directory.
You’re code would look like this:
1 | public interface MyPrincipalInterface extends java.security.Principal { |
2 | public String getEmailAddress(); |
5 | public class MyPrincipal implements MyPrincipalInterface { |
7 | public String getEmailAddress() { |
12 | public class MyServlet implements Servlet { |
13 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { |
14 | MyPrincipalInterface p = (MyPrincipalInterface)request.getUserPrincipal(); |
15 | String emailAddress = p.getEmailAddress(); |
Notice that this method gives you pretty much the webapp code you wanted in the first place
- Serializing / Deserializing
You might want to try serializing the response of
‘request.getUserPrincipal()’ and deserialize it to an instance of
[webapp]MyPrincipal.
How do I override the default home page loaded by Tomcat?
After
successfully installing Tomcat, you usually test it by loading
http://localhost:8080 . The contents of that page are compiled into the
index_jsp servlet. The page even warns against modifying the index.jsp
files for this reason. Luckily, it is quite easy to override that page.
Inside $TOMCAT_HOME/conf/web.xml there is a section called
<welcome-file-list> and it looks like this:
2 | < welcome-file >index.html</ welcome-file > |
3 | < welcome-file >index.htm</ welcome-file > |
4 | < welcome-file >index.jsp</ welcome-file > |
The
default servlet attempts to load the index.* files in the order listed.
You may easily override the index.jsp file by creating an index.html
file at $TOMCAT_HOME/webapps/ROOT. It’s somewhat common for that file to
contain a new static home page or a redirect to a servlet’s main page. A
redirect would look
like:
This change takes effect immediately and does not require a restart of Tomcat.
How do I enable Server Side Includes (SSI)?
Two things have to be done for tomcat to aknowledge SSI scripts:
- Rename $CATALINA_BASE/server/lib/servlets-ssi.renametojar to $CATALINA_BASE/server/lib/servlets-ssi.jar.
-
Uncomment the section of web.xml found in $CATALINA_BASE/conf/web.xml
that deals with SSI. it looks like this when it is uncommented:
2 | < servlet-name >ssi</ servlet-name > |
4 | org.apache.catalina.ssi.SSIServlet |
7 | < param-name >buffered</ param-name > |
8 | < param-value >1</ param-value > |
11 | < param-name >debug</ param-name > |
12 | < param-value >0</ param-value > |
15 | < param-name >expires</ param-name > |
16 | < param-value >666</ param-value > |
19 | < param-name >isVirtualWebappRelative</ param-name > |
20 | < param-value >0</ param-value > |
22 | < load-on-startup >4</ load-on-startup > |
How do I use DataSources with Tomcat?
When
developing J2EE web applications, the task of database connection
management can be daunting. Best practice involves using a J2EE
DataSource to provide connection pooling, but configuring DataSources in
web application servers and connecting your application to them is
often a cumbersome process and poorly documented.
The usual
procedure requires the application developer to set up a DataSource in
the web application server, specifying the driver class, JDBC URL
(connect string), username, password, and various pooling options. Then,
the developer must reference the DataSource in his application’s
web.xml configuration file, and then access it properly in his servlet
or JSP. Particularly during
development, setting all of this up is tedious and error-prone.
With
Tomcat 5.5, the process is vastly simplified. Tomcat allows you to
configure DataSources for your J2EE web application in a context.xml
file that is stored in your web application project. You don’t have to
mess with configuring the DataSource separately in the Tomcat
server.xml, or referencing it in your application’s web.xml file. Here’s
how:
Install the JDBC Driver
Install the .jar file(s)
containing the JDBC driver in Tomcat’s common/lib folder. You do not
need to put them in your application’s WEB-INF/lib folder. When working
with J2EE DataSources, the web application server manages connections
for your application.
Create META-INF/context.xml
In the
root of your web app directory structure, create a folder named META-INF
(all caps). Inside that folder, create a file named context.xml that
contains a Resource like this:
1 | <? xml version = "1.0" encoding = "UTF-8" ?> |
5 | < Resource name = "jdbc/WallyDB" auth = "Container" |
6 | type = "javax.sql.DataSource" username = "wally" password = "wally" |
7 | driverClassName = "com.microsoft.sqlserver.jdbc.SQLServerDriver" |
This
example shows how to configure a DataSource for a SQL Server database
named mytest located on the development machine. Simply edit the
Resource name, driverClassName, username, password, and url to provide
values appropriate for your JDBC driver.
Access the DataSource in Your Application
From a Servlet
Here’s how you might access the data in a servlet:
1 | InitialContext ic = new InitialContext(); |
2 | DataSource ds = (DataSource) ic.lookup( "java:comp/env/jdbc/WallyDB" ); |
3 | Connection c = ds.getConnection(); |
Notice that, when doing the DataSource lookup, you must prefix the JNDI name of the resource with java:comp/env/
No comments:
Post a Comment