JSP Spring app on Tomcat not delivering page
Ok I'm stumped. I am writing a Spring based app that queries a web service for information to load a SELECT object based on the user's id. I've set up the web.xml and servlet xml files, design the initial page and have a redirect from an index.jsp file (the final system will reside under a Tomcat / IIS config) with a hard coded value for the username for the time being.
Every time I try to run it I get a 404 error and nothing in the Tomcat logs. I am relatively new to JSP / Spring so this is driving me nuts as I can't seem to find the problem.
I have tried removing the reference to the web service calls and still the pages to not load.
What am I missing?
Below is the code minus stylesheets and images:
UserDatabaseProject.java
/**
*
*/
package enterprisesearch.domain;
/**
* @author bob
*
*/
public class UserDatabaseProject
{
private String _msUserName = "";
private String _msDatabaseName = "";
private String _msDatabaseDescription = "";
private String _msProjectName = "";
private String _msProjectDescription = "";
public UserDatabaseProject()
{
}
public UserDatabaseProject(String psUserName, String psDatabaseName, String psDatabaseDescription, String psProjectName, String psProjectDescription)
{
this._msUserName = psUserName;
this._msDatabaseName = psDatabaseName;
this._msDatabaseDescription = psDatabaseDescription;
this.setProjectName(psProjectName);
this.setProjectDescription(psProjectDescription);
}
/**
* @return the _msProjectName
*/
public final String getProjectName()
{
return this._msProjectName;
}
/**
* @param _msProjectName the _msProjectName to set
*/
public final void setProjectName(String psProjectName)
{
this._msProjectName = psProjectName;
}
/**
* @return the _msProjectDescription
*/
public final String getProjectDescription()
{
return this._msProjectDescription;
}
/**
* @param _msProjectDescription the _msProjectDescription to set
*/
public final void setProjectDescription(String psProjectDescription)
{
this._msProjectDescription = psProjectDescription;
}
/**
* @return the _msUserName
*/
public final String getUserName()
{
return this._msUserName;
}
/**
* @param _msUserName the _msUserName to set
*/
pu开发者_开发问答blic final void setUserName(String psUserName)
{
this._msUserName = psUserName;
}
/**
* @return the _msDatabaseName
*/
public final String getDatabaseName()
{
return this._msDatabaseName;
}
/**
* @param _msDatabaseName the _msDatabaseName to set
*/
public final void setDatabaseName(String psDatabaseName)
{
this._msDatabaseName = psDatabaseName;
}
/**
* @return the _msDatabaseDescription
*/
public final String getDatabaseDescription()
{
return this._msDatabaseDescription;
}
/**
* @param _msDatabaseDescription the _msDatabaseDescription to set
*/
public final void setDatabaseDescription(String psDatabaseDescription)
{
this._msDatabaseDescription = psDatabaseDescription;
}
}
DouglasService.java
/**
*
*/
package enterprisesearch.domain.service;
import java.io.StringReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import gov.sec.com.IDouglas;
import enterprisesearch.domain.UserDatabaseProject;
/**
* @author bob
*
*/
public class DouglasService
{
private IDouglas _mtDouglas;
private static Map<Integer, UserDatabaseProject> _muspUserDatabaseProjects = new HashMap<Integer, UserDatabaseProject>();
public DouglasService(String psDouglasUrl)
{
//String endPointAddress = "http://localhost:8080/Douglas/services/Douglas?wsdl";
//ApplicationContext acContext = new ClassPathXmlApplicationContext("context.xml");
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(IDouglas.class);
factory.setAddress(psDouglasUrl);
this._mtDouglas = (IDouglas) factory.create();
}
public String getSecurityToken(String psUserId)
{
String sReturn = "";
this._mtDouglas.getSecurityToken(psUserId);
return sReturn;
}
public String getProjectOptions(String psProjectName)
{
String sReturn = "";
this._mtDouglas.getProjectOptions(psProjectName);
return sReturn;
}
public String getDatabaseFilters(String psDatabaseName)
{
String sReturn = "";
this._mtDouglas.getDatabaseFilters(psDatabaseName);
return sReturn;
}
public Collection<UserDatabaseProject> getUserDatabaseProjects(String psUserName)
{
String sReturn = "";
String sResult = this._mtDouglas.getUserDatabaseProjects(psUserName);
XPathFactory xfactory = XPathFactory.newInstance();
XPath xPath = xfactory.newXPath();
StringReader sr = new StringReader(sResult);
NodeList databases = null;
try
{
databases = (NodeList) xPath.evaluate("/douglasresponse/responsedata/databases", new InputSource(new StringReader(sResult)), XPathConstants.NODESET);
for (int i = 0; i < databases.getLength(); i++)
{
Element elDatabase = (Element) databases.item(i);
String sUserName = xPath.evaluate("database/username", elDatabase);
String sDatabaseName = xPath.evaluate("database/databasename", elDatabase);
String sDatabaseDescription = xPath.evaluate("database/databasedescription", elDatabase);
String sProjectName = xPath.evaluate("database/projectname", elDatabase);
String sProjectDescription = xPath.evaluate("database/projectdescription", elDatabase);
this._muspUserDatabaseProjects.put(new Integer(i), new UserDatabaseProject(sUserName, sDatabaseName, sDatabaseDescription, sProjectName, sProjectDescription));
}
}
catch(XPathExpressionException ex)
{
System.out.print(ex.getMessage());
}
return _muspUserDatabaseProjects.values();
}
public String executeTextQuery(String psSecurityToken, String psProjectName, String psDatabase, String psQueryText, String psOptions, String psFilters)
{
String sReturn = "";
this._mtDouglas.executeTextQuery(psSecurityToken, psProjectName, psDatabase, psQueryText, psOptions, psFilters);
return sReturn;
}
public String executeGetContent(String psSecurityToken, String psProjects, String psDatabases, String psOptions)
{
String sReturn = "";
this._mtDouglas.executeGetContent(psSecurityToken, psProjects, psDatabases, psOptions);
return sReturn;
}
public String executeGetSimilar(String psSecurityToken, String psProjects, String psDatabases, String psOptions)
{
String sReturn = "";
this._mtDouglas.executeGetSimilar(psSecurityToken, psProjects, psDatabases, psOptions);
return sReturn;
}
}
SearchController.java
package enterprisesearch.web;
import enterprisesearch.domain.UserDatabaseProject;
import enterprisesearch.domain.service.DouglasService;
import java.util.Collection;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@Controller
public class SearchController
{
//protected final Log logger = LogFactory.getLog(getClass());
private DouglasService dgWebService = new DouglasService("http://localhost:8080/Douglas/services/Douglas");
@RequestMapping("/search.html")
@ModelAttribute("userprojects")
public Collection<UserDatabaseProject> getUserProjects(@RequestParam(value="username", required=true) String psUsername)
{
return this.dgWebService.getUserDatabaseProjects(psUsername);
}
//@RequestMapping("/search.html")
//@ModelAttribute("testmessage")
//public String setMessage()
//{
// return "This is a test!";
//}
}
/WEB-INF/jsp/index.jsp
<jsp:forward page="search.html">
<jsp:param value="lymana" name="username"/>
</jsp:forward>
/WEB-INF/jsp/search.jsp
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Enterprise Search</title>
<link href="assets/style_sheets/main.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" language="javascript" src="assets/scripts/controls.js"></script>
</head>
<body>
<form:form method="post" action="" modelAttribute="search">
<table width="100%" border="0" style="border-collapse:collapse; border-spacing: 0px;" cellspacing="0">
<tr id="pageHeader">
<td id="pageHeaderLeft"><img src="assets/images/OCIE_left-1.jpg" style="float:left;" /></td>
<td id="pageHeaderRight"><img src="assets/images/OCIE_right.jpg" /></td>
</tr>
<tr>
<td valign="top" width="50%">
<div id="leftContainer">
<div class="blockHeader">
Text Search
</div>
<div id="TextBlock" class="blockControl">
<label for="taSearchText">Search Text:</label><br />
<textarea id="taSearchText" cols="60" rows="7" style="margin-bottom: .5em;"></textarea>
<br />
<table border="0" style="border-collapse:collapse; border-spacing: 0px;" cellspacing="0">
<tr>
<td width="30%" style="padding: 0em 0em .5em .5em; text-align:right; vertical-align:middle;">
<label for="sltResultsPerPage">Results per page:</label>
</td>
<td width="30%" style="padding: 0em .5em .5em 0em; text-align:left; vertical-align:middle;">
<select id="sltResultsPerPage">
<option value="10">10 per page</option>
<option value="20">20 per page</option>
<option value="50">50 per page</option>
<option value="100">100 per page</option>
</select>
</td>
<td width="40%" rowspan="3" valign="middle" align="center">
<input id="btnSearch" type="button" value="Search" />
</td>
</tr>
<tr>
<td style="padding: 0em 0em .5em .5em; text-align:right; vertical-align:middle;">
<label for="sltSort">Sort results by:</label>
</td>
<td style="padding: 0em .5em .5em 0em; text-align:left; vertical-align:middle;">
<select id="sltSort">
<option value="relevance">Relevance</option>
<option value="dateAsc">Date (Ascending)</option>
<option value="dateDesc">Date (Descending)</option>
</select>
</td>
</tr>
<tr>
<td style="padding: 0em 0em .5em .5em; text-align:right; vertical-align:middle;">
<label for="sltRelevance">Relevance:</label>
</td>
<td style="padding: 0em .5em .5em 0em; text-align:left; vertical-align:middle;">
<select id="sltRelevance">
<option value="90">90% relevant</option>
<option value="80">80% relevant</option>
<option value="70">70% relevant</option>
<option value="60">60% relevant</option>
<option value="50">50% relevant</option>
</select>
</td>
</tr>
</table>
</div><!-- end of textblock -->
<div class="blockHeader"><img src="assets/images/RightArrowClosed16x16.jpg" onclick="setAdvancedVisible('BooleanBlock');" />
Boolean
</div>
<div id="BooleanBlock" class="blockControl" style="visibility:hidden; display:none;">Boolean Search controls here<br /><br /><br /><br />
</div>
<div class="blockHeader">
<img src="assets/images/RightArrowClosed16x16.jpg" onclick="setAdvancedVisible('ParametricBlock');" />
Parametric
</div>
<div id="ParametricBlock" class="blockControl" style="visibility:hidden; display:none;">Parametric Search controls here<br /><br /><br /><br />
</div>
<div class="blockHeader"><img src="assets/images/RightArrowClosed16x16.jpg" onclick="setAdvancedVisible('ClusterBlock');" />
Cluster
</div>
<div id="ClusterBlock" class="blockControl" style="visibility:hidden; display:none;">Cluster results here<br /><br /><br /><br />
</div>
</div>
</td>
<td valign="top" width="50%">
<div id="rightContainer">
<div class="blockHeader"><img src="assets/images/RightArrowClosed16x16.jpg" onclick="setAdvancedVisible('ProjectsBlock');"/>
Projects
</div>
<div id="ProjectsBlock" class="blockControl">
<label for="sltProjects">Projects:</label><br />
<select id="sltProjects" size="10" onclick="">
<option value="all">All available projects</option>
<c:forEach items="${userprojects}" var="UserDatabaseProject">
<form:option value="${UserDatabaseProject._msProjectName}">${UserDatabaseProject._msProjectDescription}</form:option>
</c:forEach>
</select>
</div>
<div class="blockHeader"><img src="assets/images/RightArrowClosed16x16.jpg" onclick="setAdvancedVisible('DatabasesBlock');"/>
Databases
</div>
<div id="DatabasesBlock" class="blockControl">
<label for="sltDatabases">Databases:</label><br />
<select id="sltDatabases" size="10" onclick="">
<option value="all">All available databases</option>
<option value="dbTCR20">TCR20 Database Primary</option>
<option value="dbTCR20-1">TCR20 Database Secondary</option>
<option value="dbECC">ECC Emails</option>
</select>
</div>
<div class="blockHeader"><img src="assets/images/RightArrowClosed16x16.jpg" onclick="setAdvancedVisible('FiltersBlock');"/>
Filters
</div>
<div id="FiltersBlock" class="blockControl">
<label for="sltFilters">Filters:</label><br />
<select id="sltFilters" size="10" onclick="createInput();" multiple="multiple" >
<option value="Comment">TCR20 - Comment</option>
<option value="TCR Subject">TCR20 - Subject</option>
<option value="From Address">ECC - From Address</option>
<option value="ECC Subject">ECC - Subject</option>
<option value="Message Text">ECC - Message Text</option>
</select>
</div>
<div class="blockHeader"><img src="assets/images/RightArrowClosed16x16.jpg" onclick="setAdvancedVisible('SelectedBlock');"/>
<span>Selected Filters</span>
</div>
<div id="SelectedBlock" class="blockControl">
</div>
</div>
</td>
</tr>
<tr>
<td colspan="2">
<hr />
<div>
<div class="resultsHeader">
Search Results
</div>
<div class="resultsControl" style="margin-bottom: 15px;">
</div>
</div>
</td>
</tr>
<tr>
<td id="footer" colspan="2"><hr />Some footer stuff goes here!</td>
</tr>
</table>
</form:form>
</body>
</html>
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!-- Register a servlet that despatches requests to registered controllers -->
<servlet>
<servlet-name>es</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Send all .html files to the Spring dispatcher servlet -->
<servlet-mapping>
<servlet-name>es</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!-- Define the web application entry point -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
es.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- Auto-detect controllers in this package -->
<context:component-scan base-package="enterprisesearch.web"/>
<!-- Prepend /WEB-INF/jsp/ and append .jsp to the view name -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Your controller is bound to <contextname>/search.html
, not index.html - <contextname>
referring to the context that Tomcat maps your application to, which usually is the name of the WAR file but can be anything if you have configured Tomcat specially.
Turn up Spring's logging and you will see it logging warnings when you request a URL that it has no mapping for.
your controller was worng, you must return a ModalAndView or NameOfView not Collection<UserDatabaseProject>
please try this :
@RequestMapping("/search.html")
@ModelAttribute("userprojects")
public ModelAndMap getUserProjects(@RequestParam(value="username", required=true) String psUsername){
ModelMap modelMap = new ModelMap();
modelMap.put("userprojects", this.dgWebService.getUserDatabaseProjects(psUsername));
return new ModelAndView("index", modelMap);
}
Follow any good tutorial on spring mvc. your return type should be either ModelAndView or its related type (since you are using InternalResourceViewResolved) or the String name of view.
In case of Rest Based approach or ajax you can return the data as collection (which get converted into json). For this approach you need to mark your controller as @RestController on class level or @ResponseBody on method level. This approach is mostly used in Ajax calls in which you need to iterate through the json response received and set the data on that page.
In Spring mvc based approach you need to add all the objects in the ModelAndView and set the view name as below. Then you can access the objects on that view using el.
@RequestMapping("/search.html")
@ModelAttribute("userprojects")
public ModelAndView getUserProjects(@RequestParam(value="username", required=true) String psUsername){
ModelAndView modelAndView = new ModelAndView();
// add all the required data which you need on next view page
modelAndView.addObject("userprojects", this.dgWebService.getUserDatabaseProjects(psUsername));
// set the view name which needs to be displayed
modelAndView.setViewName("search");
return modelAndView
}
In Jsp access the userprojects as:
${userprojects._msProjectName}
精彩评论