sping web mvc快速入门 三篇

SpringMVC_快速入门_组件解析 Spring与web环境集成 原始代码部分(通过tomcat启动访问) com.itheima.dao.UserDao public interface UserDao { public void save(); } com.itheima.dao.impl.UserDaoImpl public class UserDaoImpl implements UserDao { public void save() { System.out.println("save r 阅读详情

Basic Spring Web MVC Example

Posted in All by Jon on the February 10th, 2006

You want to get started with a simple web application that utilizes Spring’s web MVC framework. Here’s a simple project that provides such a start. It doesn’t use all of Spring’s features, nor even the best, but it will serve as a discussion point for future blog entries.

Background

When you’re putting together a simple web application, you need a few essentials:

  • A dispatcher servlet, which will intercept incoming requests.
  • A configuration that instructs the web container to route requests to the dispatcher servlet (ie. a servlet mapping)
  • Controllers (the C in MVC) that can perform the business logic and route to particular views (the V) perhaps conveying information models (the M).
  • A way for the dispatcher servlet to know which URLs to map to which controllers - called a url mapping
  • A way to determine, when a controller has done its job, how to get to the view - called a view resolver

The simple application here, skeleton1, doesn’t have a model at all, has a single controller (web.DispatchController), and a single view (myview.jsp)

How to do it and How it works

Download the source for the details. First, we want to use Spring’s DispatcherServlet as the entry point to our web application. You configure this simply in your web.xml:

<servlet>
<servlet-name>dispatch</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<servlet>
<servlet-mapping>
<servlet-name>dispatch</servlet-name>
<url-pattern>/send/*</url-pattern>
</servlet-mapping>

Get it? This says: Create the servlet for me, call it dispatch, and map all incoming URLs that start with send to the dispatch servlet. So for example, a URL such as http://.../skeleton1/send/foobar would activate the dispatch servlet.

The rest of the configuration you do in a Spring web application context. Spring automatically looks for it using the name of the servlet as a hint. Since our servlet is called dispatch, it looks for a file called dispatch-servlet.xml in your WEB-INF directory. This configuration file will have three bits to it: the controller(s), the url mapping and the view resolver. First, the controller:

<bean id="dispatchController"
class="com.memestorm.web.DispatchController">
</bean>

No rocket science there. It’s simply a bean implementing the appropriate interface, which we’ll look at later.

The view resolver tells us how to render the output from a controller. Here’s the one I chose:

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

This uses a Spring-implemented InternalResourceViewResolver which basically maps to like-named views in the /WEB-INF/views directory, adding a .jsp. So for example, if our controller said “Please go to view myview,” then the above resolver would try to find the file myview.jsp in /WEB-INF/views. This is easy and extensible.

The final configuration is the URL mapping, which essentially tells the dispatcher servlet how to behave: Which incoming requests should it map to which controllers? We’ve chickened out:

<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/*">dispatchController</prop>
</props>
</property>
</bean>

This again uses a Spring-supplied URL mapper (isn’t it great, you don’t have to write any code) which, as you can see, maps all requests (/*) to the controller called dispatchController (which we defined above).

The last key to the puzzle is the controller itself. We know now that appropriate URLs (that are mapped to our dispatcher servlet) will be intercepted by the dispatcher servlet. It will then look at the URL, and on the basis of the URL mapper, map it to a particular controller (in this case, it maps all incoming URLs to the same controller), and to do this operationally it needs to invoke a method on the controller. Which method? Well, this particular URL mapper looks at the URL and “lops off” the start bit and uses what’s left. For example, if you went to http:.../skeleton1/send/actionName then it will try to invoke the method actionName() on dispatchController. Nothing too it. So, let’s check out the controller!

public class DispatchController extends MultiActionController {

public ModelAndView actionName(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("myview");
mav.addObject("message", "Hiya");
return mav;
}
}

Pretty simple. This class implements the Spring MultiActionController (which really means we can have multiple control methods defined here), and provides a single control action method called actionName(). Check out the parameters - pretty much like a servlet which isn’t too surprising. The result is: ModelAndView. This is really a wrapper that tells Spring what the model data is (what data do you want to send to your view) and which view to actually send it to. In this case, we want to go to the view myview and send a string along too.

If you’ve been paying attention, you’ll know that our view resolver will look for myview.jsp, and yes, that’s what we have. Here’s a look at it:

Hello, you're in myview.jsp! <br />
The controller sent me some data,
here it is: <%=request.getAttribute("message") %>

Nothing too it. It prints a message, and grabs the model from the appropriately named attribute in the request.

So, if we now invoked http://../skeleton1/send/actionName our action will get invoked, which will eventually forward to this JSP page. You can extend at will, adding additional action methods for example, additional controllers if you like, and of course, additional views.

Downloading

Download the source
skeleton1.zip
and read the installation instructions. Short version: Download Spring (with dependencies, I’m using Spring 2M2), modify one property in our build file to point to the unzipped Spring distribution, run the build with ant, deploy on a web container (I use Tomcat).

Advanced

You’ll note that the code does just a little more than described above. In particular, we create an additional root application context with two beans a,b, and we make sure that we access and call these beans from the controller. Oh, and we use the logging described in Refreshable log4j configuration files.

 


http://www.devx.com/Java/Article/22134

Simplify Your Web App Development Using the Spring MVC Framework
n a previous article, I introduced you to the Spring framework, showed you how to use Spring's basic functionality to create objects, and how to do some simple database interactions. In this follow-up article I will introduce you to the Spring model-view- controller (MVC) framework by walking you through the creation of a simple stock-trading Web application.


MVC is a pattern that helps separate presentation from business logic. In short, in an MVC application all Web requests are handled by controllers. A "controller" is responsible for interpreting the user's request and interacting with the application's business objects in order to fulfill the request. These business objects are represented as the "model" part of the MVC. Based on the outcome of the request execution, the controller decides which "view" to forward the model to. The view uses the data in the model to create the presentation that is returned to the user.

If you've ever worked on a Web application, chances are that you've worked with either a custom MVC framework or an existing framework, such as Struts. Struts is in fairly widespread use in the Java world, but the Spring MVC framework promises to provide a simpler alternative to Struts.

In this article I will walk you through the development of a Web-based stock-trading application. This application will have three primary workflows each of which will cover a different type of controller available in Spring. After reading this article, you should have enough technical and business knowledge to build a full-fledged stock-trading application and compete head-on with existing discount brokerage firms. … OK, not really, but you will at least have enough knowledge to get you started on your own Web projects using Spring.

You can download the Spring distribution from http://www.springframework.org/download.html. If you want to see the application in action, download the source code for this article, which includes a deployable war file.

Author's Note: The code in this article has only been tested on Tomcat 5.5.
The Platform
There are many different Web application servers and development environments to choose from. I won't describe any single environment here because I want to focus the discussion on the Spring framework and not the underlying tools. However, I developed this sample application using Tomcat 5.5, Java 1.5, Spring 1.1, and Eclipse 3.0 using the Sysdeo Tomcat plugin. I have used Spring with other application servers and with different versions of Java 1.4.x without any big surprises, so you should be safe if you have a slightly different environment.

Getting Started
Before diving into Spring, set up a mechanism for deploying your application code into your Web server and set up an application context if necessary. In Tomcat 5.5, the application context automatically takes on the name of the war file (or expanded war directory) that you deploy. My war file is called "tradingapp.war" and my context is consequently "/tradingapp."

Here is the basic directory structure that you need to create for your Web app:


/WEB-INF
/src (java classes will go in here)
/jsp (application jsps will go in here)
/lib (jar files that our app depends on will go in here)
/classes (compiled class files will go in here)
In order to test out the application server setup, create a file called index.jsp (as follows) and put it in the root of your application directory:

/index.jsp
<html>
<head><title>Trading App Test</title></head>
<body>
Trading App Test
</body>

Accessing a Controller
Like in other Web frameworks, Spring uses a servlet called DispatcherServlet to route all incoming requests (this pattern is sometimes called the Front Controller pattern). This servlet should be defined in the Web deployment descriptor as shown here:

/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
'http://java.sun.com/dtd/web-app_2_3.dtd'>

<web-app>
<servlet>
<servlet-name>tradingapp</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>tradingapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
In the web.xml file I've defined a servlet mapping that forces any URL
that ends in .htm to reroute to the tradingapp Servlet (the
DispatcherServlet). This servlet analyzes the request URL and
determines which controller to pass control on to by using a URL
mapping defined in a Spring XML file. This Spring XML file must exist
in the /WEB-INF directory and it must have the same name as the servlet
name that you defined in the web.xml with a "-servlet.xml" appended to
it. Thus, we will create a file in the /WEB-INF directory called
The Portfolio Page
I first want to change the index.jsp page to redirect to my portfolio page by going through the PortfolioController. I'll also create a JSP called include.jsp that all of my JSP files can include in order to inherit a common set of properties and tag library definitions.

/index.jsp
<%@ include file="/WEB-INF/jsp/include.jsp" %>

<core:redirect url="/portfolio.htm"/>


Now I'll create a simple portfolio view and have my controller route to it just to make sure everything is working.


/WEB-INF/jsp/portfolio.jsp
<%@ include file="/WEB-INF/jsp/include.jsp" %>

<html>
<head><title>Portfolio Page</title></head>
<body>
Portfolio Page
</body>
</html>


Before writing the Controller, you should add a few jar files to your /WEB-INF/lib directory:
The Logon Page
Now you know how to create a page with dynamically updated content, but what good is a Web application that has no way to capture user input from an HTML form? We could implement the Controller interface in order to do form processing, but that would require us to do a lot of manual processing or request parameters and storing things on the session. Personally, I've hand coded more form-processing code in this fashion than I ever hope to again. Thus, out of sheer laziness, I will show you how Spring simplifies form handling via the SimpleFormController by building a logon page.
advertisement

Listing 4 shows the logon JSP. The <spring:bind> tag and the <spring:hasBindErrors> tag are in the spring.tld tag library descriptor that comes with Spring. Add this file to your WEB-INF directory and then add the following to your web.xml and include.jsp files.


/WEB-INF/web.xml
<taglib>
<taglib-uri>/spring</taglib-uri>
<taglib-location>/WEB-INF/spring.tld</taglib-location>
</taglib>

/WEB-INF/jsp/include.jsp
<%@ page session="false"%>

<%@ taglib prefix="core" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<%@ taglib prefix="str" uri="http://jakarta.apache.org/taglibs/string-1.1" %>
<%@ taglib prefix="spring" uri="/spring" %>
The bind tag tells Spring to bind the enclosed form element to the bean property specified by the path attribute. For example the username input parameter will be bound to the username field on a bean named "credentials." The credentials bean is a special type of bean called a "command" or a "form-backing bean." Spring uses command beans for data binding while processing forms. The name used to reference this bean and its class type is defined in the tradingapp-servlet.xml file in the logonForm bean (see Listing 5).

I've also added a new entry to the handler mapping to point to our logon form when the user navigates (or is routed) to the logon.htm URL. The logon form has several properties:

  • commandClass—the class of the object that will be used to represent the data in this form.
  • commandName—the name of the command object.
  • sessionForm—if set to false, Spring uses a new bean instance (i.e. command object) per request, otherwise it will use the same bean instance for the duration of the session.
  • validator—a class that implements Spring's Validator interface, used to validate data that is passed in from the form.
  • formView—the JSP for the form, the user is sent here when the controller initially loads the form and when the form has been submitted with invalid data.
  • successView—the JSP that the user is routed to if the form submits with no validation errors.
Here is the code for the Controller:

/WEB-INF/src/com/devx/tradingapp/web/LogonFormController.java
package com.devx.tradingapp.web;

import javax.servlet.ServletException;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;

public class LogonFormController extends SimpleFormController {
public ModelAndView onSubmit(Object command) throws ServletException {
return new ModelAndView(new RedirectView(getSuccessView()));
}

}
There's really not much to it. All the FormController does is forward to the success view. The validator takes care of authenticating the user. If the user provides an invalid username or password, the validator will return the user to the form and display an error message. Listing 6 shows the code for the validator.

The validator has a supports method and a validate method. The supports method is called to see if the validator supports a given object type. We want our validator to be able to validate objects of the type Credentials, because that is the command object that we are using for this form.

The validate method does some checks and calls the rejectValue method on the Errors class if validation fails. This method takes four parameters: the name of the field that failed validation, the key value of the error message that exists in a resource file (I'll explain in a second), a string array of values to substitute into the error message in the resource file, and the default error message that should be displayed if the resource file cannot be found. If any errors are found on the Errors object after validate is done running, Spring will forward control back to the original form JSP so that the errors can be displayed.

You may have noticed above that I also added a ResourceBundleMessageSource bean definition to the tradingapp-servlet.xml file. This is a reference to a properties file that contains application messages that can be defined and accessed throughout the application. These messages can be accessed in many ways, including being directly accessed from JSPs or, as we just saw, by the Errors object to provide error messages. This file must exist in the top level of your classpath, so I just put it in the WEB-INF/classes directory. I've jumped the gun and included all the error messages that our application will use in the file:


/WEB-INF/classes/messages.properties
error.login.not-specified=User credentials not specified (try guest/guest).
error.login.invalid-user=Username not valid, try 'guest'
error.login.invalid-pass=Password not valid, try 'guest'
error.trade.insufficient-funds=You do not have enough money to place this order
error.trade.not-enough-shares=You do not have that many shares
error.trade.dont-own=You don't own this stock
error.trade.invalid-symbol=Invalid ticker symbol: {0}
Here is the code for the infamous Credentials class (the command/form-backing object):

WEB-INF/src/com/devx/tradingapp/business/Credentials.java
package com.devx.tradingapp.business;

public class Credentials {
private String username;

private String password;

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;

}
}
Now you can change the index.jsp page in the root directory to point to logon.htm.

/index.jsp
<%@ include file="/WEB-INF/jsp/include.jsp" %>

<core:redirect url="/logon.htm"/>
Now if you load index.jsp, you will see the logon page, as shown in Figure 4.

Figure 4. Validating: When the logon page does not validate correctly, the user is returned to the form page where the validation errors are displayed.

In summary, here is the flow through this form:

  1. The user goes to the logon.htm page.
  2. He is routed to the dispatcher servlet (because all .htm pages are directed to the dispatcher Servlet).
  3. The DispatcherServlet loads the tradingapp-servlet.xml file and routes the user to the LogonFormController.
  4. The LogonFormController loads the command bean (form-backing object) and routes the user to the page defined in the formView (logon.jsp).
  5. The user fills out the form and submits it.
  6. The user is directed back to the controller and in turn the validator.
  7. If the validator fails, the user is sent back to the form view and error messages are displayed (back to logon.jsp and step 5).
  8. If the validator doesn't fail, the controller's onSubmit method is called and the user is forwarded to the successView JSP (portfolio.jsp).


Jar Description Source
spring.jar Main spring jar file [spring-dist]/dist
log4j-1.2.8.jar log4j logging package [spring-dist]/lib/log4j
commons-logging.jar Jakarta Commons logging package [spring-dist]/lib/jakarta-commons
jstl.jar Java standard tag library [spring-dist]/lib/j2ee
standard.jar Jakarta standard tag library [spring-dist]/lib/jakarta-taglibs
taglibs-string.jar Jakarta tag library used for String manipulation http://jakarta.apache.org/taglibs/
commons-lang-2.0.jar Jakarta Commons language API http://jakarta.apache.org/commons
jfl.jar Financial library used to get stock-quotes online http://www.neuro-tech.net/archives/000032.html

Most of these jars are available in the Spring distribution. All of them are available with the downloadable code for this article.

Now create a class called PortfolioController:

/WEB-INF/src/com/devx/tradingapp/web/PortfolioController.java package com.devx.tradingapp.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; public class PortfolioController implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) { return new ModelAndView("/WEB-INF/jsp/portfolio.jsp"); } } The Controller interface defines a single method signature: public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws java.lang.Exception;
Figure 2. Back to the Portfolio: The index.jsp page should now redirect you to the Portfolio Page.

The object that is returned by the handleRequest method is of the type ModelAndView. As you probably guessed, the ModelAndView object represents the Model and View in the MVC pattern. ModelAndView has several contructors. The one we're using right now just takes a string that represents the view that we want to forward to. Because our portfolio.jsp page doesn't have any dynamic content (yet), we don't need to return a model object.

Compile the PortfolioController and make sure the compiled file is under the WEB-INF/classes directory structure (i.e. /WEB-INF/classes/com/devx/tradingapp/web/PortfolioController.class). Now you can deploy your application and pull up the index.jsp page again. Go to http://localhost:8080/tradingapp/index.jsp and you should see what is shown in Figure 2.

Now I'll make it a little easier to specify views from within the Controller objects. The goal is to avoid having to type out the full path to a JSP inside of my Controller code. I can achieve this through use of a ViewResolver that I'll define in my tradingapp-servlet.xml file. The ViewResolver appends a prefix and suffix to the view that the Controller returns.

/WEB-INF/tradingapp-servlet.xml <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property> <property name="prefix"><value>/WEB-INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> </bean> Now I can simplify my PortfolioController: /WEB-INF/src/com/devx/tradingapp/web/PortfolioController.java package com.devx.tradingapp.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; public class PortfolioController implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) { return new ModelAndView("portfolio"); } } Just to make sure that the Portfolio Page still loads after this change, reload the page in your Web browser (you may have to reload the application context or restart your application server if your application server does not support hot-deploy functionality).

Now I want to make the portfolio page more interesting! First, I'll add some custom-tag library definitions to the include.jsp file. Using custom tags helps me keep my presentation logic separate from the presentation itself.

/WEB-INF/jsp/include.jsp <%@ page session="false"%> <%@ taglib prefix="core" uri="http://java.sun.com/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> <%@ taglib prefix="str" uri="http://jakarta.apache.org/taglibs/string-1.1" %> Next, update your PortfolioController (see the code in Listing 1).

In the new version of the Controller, I've added a model. I use the three-argument constructor for ModelAndView that takes the view, the string name that the JSPs will use to refer to the model, and the model object itself. In Spring, a model is usually just a java.util.Map object. I put two elements on the model, a cash amount, and a list of portfolio line items. Each line item is of type PortfolioItemBean, a JavaBean that I created. This bean is primarily for View purposes and is created using data from the underlying business object called Portfolio. Listing 2 shows these classes.

You'll also notice that I'm using a class called QuoteFactory to obtain a Quote object using a stock symbol. These classes are part of the Neurotech Java Financial Library, a simple, open source API that can be used to retrieve stock quotes from the Web as well as other simple financial tasks.

Listing 3 shows the updated tradingapp-servlet.xml file and the portfolio.jsp file. If all goes well, when you deploy and reload the page you should see something very similar to Figure 3.

Figure 3. Improving the Portfolio: The portfolio view uses custom tags to display model data that is provided by the PortfolioController.

The cool thing is that the PortfolioController retrieves quotes from the Web using the Java Financial Library, so if you keep refreshing the page during trading hours, you'll get updated quotes.

In summary, here is the flow to this page:

  1. The user goes to the portfolio.htm page.
  2. He is routed to the dispatcher Servlet (because all .htm pages are directed to the dispatcher Servlet).
  3. The DispatcherServlet loads the tradingapp-servlet.xml file and routes the user to the PortfolioController.
  4. The PortfolioController creates the model and view and passes control back to the DispatcherServlet.
  5. The DispatcherServlet makes the model data accessible via session or request parameters.
  6. The DispatcherServlet routes to the JSP pages.
  7. The JSP is rendered and the presentation is sent back to the user.


/WEB-INF/jsp/include.jsp
<%@ page session="false"%>

"tradingapp-servlet.xml."

Here is the Spring XML file that the DispatcherServlet will use:

/WEB-INF/tradingapp-servlet.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="portfolioController" class="com.devx.tradingapp.web.portfolio.PortfolioController"> </bean> <!-- you can have more than one handler defined --> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="urlMap"> <map> <entry key="/portfolio.htm"> <ref bean="portfolioController" /> </entry> </map> </property> </bean> </beans> I called the bean urlMapping, but Spring should pick up the mapping regardless of what you name it. In fact, you can have multiple handler-mapping objects defined. The SimpleUrlHandlerMapping class has a map property called urlMap that maps URLs to objects that implement the Controller interface. When the DispatcherServlet looks in this bean definition file, it will load the mapping and use it to determine which controller to route to. I've created a reference to the PortfolioController.

There are several different types of controllers available in the Spring framework. In this article, I will show you three different types:

  1. For the portfolio page, I will create the simplest type of controller: one that implements the Controller interface directly.
  2. Next I'll create a logon form that will use a SimpleFormController class.
  3. Last, I'll create a trade wizard using the AbstractWizardFormController class.

</web-app>

</html>
Figure 1. Clear the Deck: Pull up the index.jsp page to make sure that you can retrieve a simple JSP page.

Try to pull up the page by going to http://localhost:8080/tradingapp/index.jsp (see Figure 1). (The port may vary depending on the application server you are using.)

On most application servers, users can access files in the root directory of the context. Hence, you were able to hit the index.jsp file directly. In an MVC architecture, you want the controller to handle all incoming requests. In order to do this, it is a good idea to keep your JSP files in a place where they are not directly accessible to the user. That is why we will put all of our application JSP files in the WEB-INF/jsp directory. We'll come back to this soon, but for now let's find out how to access a Spring controller.

Page 1 of 5

The Trade Wizard
Often times we have more than one screen that a user interacts with in order to complete a given task. This sequence of screens is often called a "wizard." The last MVC component I will introduce you to is the AbstractWizardFormController. This controller allows you to carry the same command object through an entire flow of Web pages, thus allowing you to break up the presentation into multiple stages that act on the same model.

For the example, I'll create a wizard that allows a user to trade stock. This wizard will start with a page that takes the order and then goes to a confirmation page where the user will choose to either execute or cancel the order. If the order is cancelled, the user will be returned to the portfolio page, if the order is executed the user is sent to an acknowledgement page to tell them that their order was filled.

First I need a way to get to the trade page, so I'll put a link to the trade page on the portfolio page.


/WEB-INF/jsp/portfolio.jsp
<br>
<a href="<core:url value="trade.htm"/>">Make a trade</a><br/>
<a href="<core:url value="logon.htm"/>">Log out</a>
<br>
</body>
</html>
Now I'll update the tradingapp-servlet.xml so that it knows what to do when the user clicks on the trade.htm link.

/WEB-INF/tradingapp-servlet.xml
<bean id="tradeForm" class="com.devx.tradingapp.web. TradeFormController">
<constructor-arg index="0">
<ref bean="portfolio"/>
</constructor-arg>
</bean>

<!-- you can have more than one handler defined -->
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/portfolio.htm">
<ref bean="portfolioController" />
</entry>
<entry key="/logon.htm">
<ref bean="logonForm"/>
</entry>
<entry key="/trade.htm">
<ref bean="tradeForm"/>
</entry>
</map>
</property>
</bean>
The TradeFormController should exist as /WEB-INF/src/com/devx/tradingapp/web/TradeFormController.java. But there is a lot to the TradeFormController, so I'll explain it in segments.


public class TradeFormController extends AbstractWizardFormController {

private Portfolio portfolio;

public TradeFormController(Portfolio portfolio) {
this.portfolio = portfolio;
setPages(new String[] { "trade", "trade-confirm" });
setCommandName("trade");
}
The TradeFormController extends AbstractWizardFormController. I pass in a Portfolio object so that the trade form knows what my buying limit is and can add and remove stock from the portfolio. The setPages method in the constructor tells the form the sequence of pages we are going to call.

The strings in this array relate to views that are resolved by the ViewResolver just like in the other controllers. These pages are indexed by Spring starting at 0. Thus the trade view is index 0 and the trade-confirm view is index 1. The indexes exist because we may have an event that causes us to skip or go back to a previous page. The setCommandName method sets the name of the command object that we are going to use for this form. This object will be created in the formBackingObject method.


protected Object formBackingObject(HttpServletRequest request) {
Trade trade = new Trade();
trade.setBuySell(Trade.BUY);
return trade;
}
This method will create the command object and set it in its initial state. This method is called before the user is directed to the first page of the wizard. Subsequent submits will call several methods on the abstract controller. The main methods that are called are onBind, validatePage, and getTargetPage.

onBind
protected void onBind(HttpServletRequest request, Object command,
BindException errors) {

Trade trade = (Trade) command;

if (symbolIsInvalid(trade.getSymbol())) {
errors.rejectValue("symbol", "error.trade.invalid-symbol",
new Object[] { trade.getSymbol() },
"Invalid ticker symbol.");
} else {
Quote quote = null;
try {
quote = new QuoteFactory().getQuote(trade.getSymbol());
} catch (QuoteException e) {
throw new RuntimeException(e);
}
trade.setPrice(quote.getValue());
trade.setSymbol(trade.getSymbol().toUpperCase());
}
}
The onBind method is called before any validation occurs for each submit. I override the onBind method in order to get a quote on the symbol the user is trying to purchase and set the price and symbol on the command object. Keep in mind that even if onBind adds errors to the BindException, the validatePage method will still be called.

protected void validatePage(Object command, Errors errors, int page) {
Trade trade = (Trade) command;

if (tradeIsBuy(trade)) {
if (insufficientFunds(trade)) {
errors.reject("error.trade.insufficient-funds",
"Insufficient funds.");
}
} else if (tradeIsSell(trade)) {
if (portfolio.contains(trade.getSymbol()) == false) {
errors.rejectValue("symbol", "error.trade.dont-own",
"You don't own this stock.");
} else if (notEnoughShares(trade)) {
errors.rejectValue("quantity", "error.trade.not-enough-shares",
"Not enough shares.");
}
}
}
validatePage
The validatePage method is called after the onBind method. It acts in the same way as the validator did in the logon controller. The validatePage method is passed the page number for the page in the flow that you are validating. This can be used if you need to do custom validation for each page in the flow. If you wanted to, you could create validator objects for each page and use the validatePage method to delegate to the appropriate validator based on the page index that was passed in.

getTargetPage
The getTargetPage method will be called in order to find out which page to navigate to. This method can be overridden in your controller, but I use the default implementation, which looks for a request parameter starting with "_target" and ending with a number (e.g. "_target1"). The JSP pages should provide these request parameters so that the wizard knows which page to go to even when the user uses the Web-browser's back button.

The processFinish method is called if there is a submit that validates and contains the "_finish" request parameter. The processCancel method is called if there is a submit that contains the "_cancel" request parameter.


protected ModelAndView processFinish(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors) {
Trade trade = (Trade) command;

if (trade.isBuySell() == Trade.BUY) {
portfolio.buyStock(trade.getSymbol(), trade.getShares(), trade
.getPrice());
} else {
portfolio.sellStock(trade.getSymbol(), trade.getShares(), trade
.getPrice());
}
return new ModelAndView("trade-acknowledge", "trade", trade);
}

protected ModelAndView processCancel(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors) {
return new ModelAndView(new RedirectView("portfolio.htm"));



 
	


}
Listing 7 is the code for the Trade class (our command for this form). And now all you need are the JSP pages (see Listing 8 for the three JSP pages).

As you can see in the code, the Spring-specific request parameters are specified in the submit button name attribute. If all goes well, you should be able to pull up the first page of the trade wizard by going to http://localhost:8080/tradingapp/trade.htm (see Figure 5).

Figure 5. Ready to Trade: The first page of the trade wizard allows you place an order for a stock trade.

In summary, here is the flow through this form:

  1. The user goes to the trade.htm page.
  2. He is routed to the dispatcher servlet (because all .htm pages are directed to the dispatcher servlet).
  3. The DispatcherServlet loads the tradingapp-servlet.xml file and routes the user to the TradeFormController.
  4. The TradeFormController loads the command bean by calling the formBackingObject method and routes the user to the first page defined in the setPages call in the constructor (trade.jsp).
  5. The user fills out the form and submits it.
  6. The user is directed back to the controller, which parses the target page off of the request parameters from trade.jsp, binds and validates the command object, and forwards the user to the next page in the wizard.
  7. If the validator fails, the user is sent back to the form view and error messages are displayed (back to trade.jsp).
  8. If the validator doesn't fail, the controller forwards to the trade-confirm.jsp page.
  9. The user submits an execute or cancel command, which will in turn tell the controller to execute either the processFinish or processCancel commands, respectively.
  10. The user is forwarded to the page that the processFinish or processCancel command sends them to.

I've gone over three different types of controllers provided by Spring, which should be enough to get you started on your own Web projects. The Spring framework contains quite a few more features than those I have gone over in this article and its predecessor. I have found Spring to be a very valuable tool in my software development toolbox, and I urge you to discover its vast utility for yourself.


 

Javid Jamae consults for Valtech, a global consulting group
specializing in delivering advanced technology solutions. Valtech
endeavors to help its
customers through its global delivery model to create and/or maintain
an affordable competitive advantage.


 

http://blog.youkuaiyun.com/paddyhuang/archive/2004/08/17/76488.aspx

Handler Mapping在Spring的MVC中

说到Mapping问题。。我就想到了Controller Front模式(请见:http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html)

所以说呢,Mapping问题主要就是要解决要调用哪一个Action的问题。。

主要有两个Mapping Handler方式:

1. BeanNameUrlHandlerMapping

这个其实也就是默认方式,只要你不要**-servlet.xml中定义其mapping方式的话,Spring会自动选择其方式

它是根据其所定义的Action的ID进行调用:

比如:

<beans>
  <bean id=”mapping” class=”org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping”/>
  <!-- 定义几个Action bean -->
  <bean id=”/addUser.html” class=”org.springframework.web.mvc.SimpleFormController”>
    <property .................../>设置其SimpleFormControl的一些属性
 </bean>
<bean id=”/logout.html” class=”saoo.MyController”/>
</beans>

所以,它所对应要增加一个新的User的URL就是/addUser.html
而一但用户想登出系统的话,就可以通过URL:/logout.html来实现

 

2. SimpleUrlHandlerMapping

它是通过原先配置好的一对一对放入到其一个Map mappings的属性里面
比如:
<beans>
  <bean id=”mapping” class=”org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping”/>
  <!-- 定义几个Action bean -->
  <bean id=”/addUser.html” class=”org.springframework.web.mvc.SimpleFormController”>
    <property .................../>设置其SimpleFormControl的一些属性
 </bean>
<bean id=”/logout.html” class=”saoo.MyController”/>
</beans>
可以改成:
<beans>
  <bean id=”mapping” class=”org.springframework.web.servlet.handler.SimpleUrlHandlerMapping”>
    <props><!--因为其属性是Map-->
      <prop key="/addUser.html">AddUserController</prop><!--因对应的是Action Bean的id-->
      <prop key="/logout.html">Logout</prop><!--对应Logout的Action-->
    </props>
  </bean>
  <!-- 定义几个Action bean -->
  <bean id=”AddUserController” class=”org.springframework.web.mvc.SimpleFormController”>
    <property .................../>设置其SimpleFormControl的一些属性
 </bean>
<bean id=”Logout” class=”saoo.MyController”/>
</beans>

过时候再与一些关于Action的东东。。呵呵


 

注意:mapping controller的时候,有个路径的问题。

如果

  <servlet-mapping>
    <servlet-name>processconfig</servlet-name>
    <url-pattern>/pc/agr/*</url-pattern>
</servlet-mapping>

那么

<bean id="urlMapping"
        class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/app">tGuiderConf</prop>
        </props>
    </property>
    </bean>

将把

http://../pc/agr/app映射到tGuiderConf这个controller。

而不是

http://../app。

快速掌握Spring MVC开发指南 MVC(Model-View-Controller)是一种设计模式,旨在将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。模型负责数据和业务逻辑,视图负责展示数据,而控制器处理用户的输入,并将模型和视图关联起来。在Spring MVC框架中,模型(Model)是应用程序中用来封装业务对象以及传递数据给视图(View)的部分。模型的主要职责是与业务逻辑层进行交互,获取数据,并将数据以一种形式呈现给视图层进行展示。 阅读详情

相关推荐

利用Matlab绘制非线性系统相图:从理论到实践

本文详细介绍了如何利用Matlab进行非线性系统的相图绘制与相平面分析。从理论基础的状态空间转换出发,通过无阻尼线性谐振子和范德波尔振荡器等实例,手把手演示了使用ode45求解器绘制相图、分析平衡点与极限环的完整流程,并分享了方向场绘制、参数分岔探索及常见错误解决方案等高级技巧,为动力学系统分析与控制设计提供了直观强大的可视化工具。

yhn456789的博客 907

Cannot render error page for request [/xxx/xxx/xxx] and exception [nested exception is org.apache.

Cannot render error page for request [/xxx/xxx/xxx] and exception [nested exception is org.apache.ibatis.builder.BuilderException,纯纯语法错误!!!!

Chao_nengli的博客 7976

Facebook登录协议逆向实战:从加密参数到完整流程解析(附Python代码)

本文深入解析了Facebook登录协议的逆向工程实战,详细拆解了从关键加密参数(如`lgndim`、`encpass`)定位到完整登录流程的实现。文章提供了Python代码示例,重点阐述了加密逻辑的深度解析、加密函数的本地化实现,并解决了Crypto.js异步调用等常见问题,为研究Web安全和协议逆向的开发者提供了实用参考。

metal的博客 1314

关于Cannot forward to error page for request [/strategy/list/] 。。。的问题

 今天遇到这个一个错误:Cannot forward to error page for request [/wechat/wechatCheck/forgetPsd] as the response has already been committed. As a result, the response may have the wrong status code. If your appli...

qq_33551131的博客 3万+

基于Super-Jacoco的精准测试实践之路

灵魂拷问这个版本的影响范围到底有多大?研发改动了代码,为什么不通知测试?测试用例真的全面覆盖了吗?测试同学的测试覆盖情况该怎么评估?什么是精准测试概念借助技术手段、通过辅助算法对软件测试过...

咻咻ing的专栏 5842

基于Ardupilot/PX4固件,APM/PIXhawk硬件的VTOL垂直起降固定翼软硬件参数调试(第二篇)软硬件参数调试

基于Ardupilot/PX4固件,APM/PIXhawk硬件的VTOL垂直起降固定翼软硬件参数调试(第二篇) 本文内容大部分来自Kris,我们的K大,在VTOL领域的大牛,在此,非常感谢K大。能引用K大的成果也是自己的荣幸,不便之处还请K大多多包涵,在此引用只是为方便自己日常学习,部分参数表里根据自身情况,增加了修改环节和相应参数。 垂直起降固定翼 中文教程-参数设置 垂直起降固定翼是由 多轴+...

u011322358的博客 2万+

整合篇:零基础学习与使用WebMVC

目录1、WEB开发1.1、静态资源处理1.2、欢迎页的支持1.3、错误页的支持1.4、网站图标支持1.5、RESTful 风格1.6、原生组件注册1.6.1、注解形式1.6.2、注册形式1.7、支持异步请求1.8、支持定时任务2、日志记录2.1、创建工程2.2、日志使用2.3、日志设置 配套资料,免费下载 1、WEB开发 1.1、静态资源处理 静态资源目录 只要静态资源放在类路径下中的:/static、/public、/resources、/META-INF/resources目录中,均可以被访问。 访问

轻松的小希 2700

玩转Matlab-Simscape(初级)-01-从一个简单模型开始学习之旅

本文从初学者的角度分享的关于Matlab simscape 的基础内容,简单分享了Simscape搭建模型,创建子系统,修改定义参数等内容,为将来深入学习和使用simscape做铺垫。

万金油笑匠的博客 6524

Sping Web MVC入门

xkroy的博客 298

基于STM32的馆藏文物保存环境监测系统设计与实现

针对馆藏文物保存环境中温湿度、光照、有害气体等参数波动易导致文物损坏的问题,本文设计了一种基于STM32微控制器的馆藏文物保存环境监测系统。该系统以STM32L431RCT6为核心,集成高精度传感器实现多参数实时采集,通过有线与无线结合的通信方式构建监测网络,具备数据存储、异常预警、远程监控等功能。测试结果表明,系统温湿度测量精度分别达±0.2℃、±2%RH,光照与有害气体检测误差≤5%,可满足文物保存环境的高精度监测需求,为文物保护提供科学的数据支撑。

m0_74026776的博客 1543

SAP 联产品测试

最近领导一直要求研究一下SAP联产品的使用场景,之前只是自己摸索过一次,这个重新对联产品进行一个测试。 1、首先准备好物料主数据 注意主数据中需要勾选联产品标识。 设置好物料的分摊的百分比。 2、检查BOM 在BOM中也需要维护联产品的标识 只有当组件数量未负数时,才能勾选联产品的标识。如果组件数量正值,勾选联产品的标识时会报错。 3、我们创建生产订单 可以看到按正常的生产订单下达时,系统就报错了,问题点在于离散制造的生产订单基本是结算到物料的。但是联产品是按订单结算的, 所以需要对订单类型中的结算参

我小时候很黑的博客 2111

什么是Spring与SpringBoot?什么是MVC与SpringMVC?

Spring本身是一个非常强大的企业级应用框架,它可以提高项目开发效率,降低可侵入性,将“高内聚,低耦合”的软件设计思路发挥到了极致。但也有很多缺点,如下:1.Spring框架需要依赖很多jar包,程序开发人员每次搭建 Spring框架都要下载十多个jar 包。由于 Spring 版本频繁地更新,导致不同版本的 Spring 对于依赖的jar 包有着严格的版本要求。即使程序开发人员拥有早期版本的jar 包,也会因为与 Spring 更新后的版本不兼容而导致项目无法运行。

2301_79575831的博客 1382

AI Agent开发第84课-paddleocr-vl全网唯一最全本地化布署教程

本文详解 PaddleOCR-VL 本地化布署全过程,指出为何在真实生产环境中 PaddleOCR-VL 更稳定、更易部署、更贴近工程落地。同时还会详细比较与 DeepSeek-OCR 的核心差异,为全网独家介绍paddleocr-vl的本地部署实战指南。

打造全国最全的AI Agent开发知识领域的博客 5968

Sping、SpringMVC、SpringBoot的对比

原文链接:https://dzone.com/articles/spring-boot-vs-spring-mvc-vs-spring-how-do-they-compare 作者: Ranga Karanam 译者:Yunooa 推荐关注公众号: 锅外的大佬 每日推送,专注分享国外最新技术内容,帮助每位开发者更优秀地成长 在本文中,你将获取到有关于Spring,Spring MVC和Sprin...

liululee的博客 395

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Sping6知识点概述(带你快速入门和回顾)

spring6学习笔记!

weixin_44729515的博客 1281

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Spring MVC快速入门

今天给大家介绍一下Spring MVC,让我们学习一下如何利用Spring MVC快速的搭建一个简单的web应用。 更深入地学习Spring MVC,请大家参考Spring MVC实战入门训练。 参考代码请戳右上角,下载下来后可以在Eclipse或者IntelliJ中导入为一个Maven项目。 环境准备 一个称手的文本编辑器(例如Vim、Emacs、Sublime Text

klayer_cong的博客 1452

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Spring MVC 与 Spring Boot

Spring MVC 是 "工具":解决 Web 层的请求处理问题,是 Spring 生态的 Web 核心。Spring Boot 是 "加速器":基于 Spring MVC 等 Spring 组件,简化开发流程,让开发者更专注于业务逻辑而非配置。Spring Boot = Spring MVC + 自动配置 + 起步依赖 + 嵌入式服务器 + ...,它是使用 Spring MVC 的最佳实践方式。

2502_92141759的博客 759

Springboot1学习(一)快速入门

拖了好久,终于学开始springboot,馒馒来吧。 看了看还有好多没学完… 先学springboot1吧,磨刀不误砍柴功 文章目录springboot概述快速入门第二种启动方式静态资源访问全局异常捕获FreeMarker页面渲染 springboot概述 支离破碎的语言随便写一下吧,反正都不看的。捂脸 目前spingboot主流 敏捷开发 无需tomcat,内置了tomcat 减少xml配置,改用properties springcloud+springboot微服务技术 springboot底层封

qq_19841133的博客 452

sping MVC框架

上次介绍了一下ssh框架,  这次就简单的介绍一下MVC框架。 Spring MVC 介绍 Spring的一部分 Spring springmvc 无缝衔接 SpringMVC 是一个web层框架。  用来接收参数,和响应请求 快速搭建: 需是web项目,还要web.xml去配置一个springmvc核心接收参数的类,springMVC用的是servlet开发的      1. 创建...

weixin_42108509的博客 236

sping boot基础

通过本文的介绍,你对 Spring Boot 的基础概念和基本使用方法有了一个初步的了解。Spring Boot 以其简洁高效的开发方式,在 Java 企业级应用开发中得到了广泛的应用。它不仅大大简化了项目的初始搭建过程,还通过自动配置等特性提高了开发效率,让开发者能够更加专注于业务逻辑的实现。在后续的学习中,你可以进一步深入了解 Spring Boot 的更多高级特性,如数据库访问、安全管理、缓存机制等,以构建更加完善和强大的应用系统。

2401_84461036的博客 506

【spring】Spring、Spring MVC、Spring Boot、Spring Cloud?

Spring、Spring MVC、Spring Boot、Spring Cloud?

weixin_46589153的博客 650

Spring MVC快速体验

Spring MVC 快速体验的五个步骤: 1. 配置web.xml 2. 创建Spring配置文件applicationContext.xml 3. 创建model 4. 创建controller 5. 创建视图文件userlist.jsp 6. 创建Servlet配置文件Spring-servlet.xml

栋先生 612

Idea 七步建立Spring Mvc 的web项目,极其简单

Idea 7步建立Spring Mvc 的web项目 1.新建项目 新建的结构是这样的 2.添加controller的包、文件;添加jsp的文件夹和jsp文件 文件名为HelloWorldController ,代码在下方 文件名为hello.jsp,代码在下方 完整的目录结构如下: 代码 package test.con...

weixin_30483697的博客 216
上一篇: 软件项目版本号的命名格式
下一篇: 关于java和web项目中的相对路径问题
yethyeth
博客等级 码龄21年 140粉丝 265原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值