Spring MVC 中的 Controller
jopen
12年前
MVC模型中的控制器负责解析用户的输入信息,并将之变换处理后传入一个model,而这个 model则可能被呈现给发起请求的用户。Spring以非常抽象的方式体现了控制器的理念,从而开发人员在创建controller时将有多种选择。 Spring包含了3类controller:处理HTML表单的controller,基于command的controller,和向导风格的 controller。
package org.springframework.web.servlet.mvc; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; public interface Controller { ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception; }
1.
java.lang.Object
|_
*
*
*
*
*
*
package org.springframework.web.servlet.mvc; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.support.WebContentGenerator; import org.springframework.web.util.WebUtils; public abstract class AbstractController extends WebContentGenerator implements Controller { private boolean synchronizeOnSession = false; public final void setSynchronizeOnSession(boolean synchronizeOnSession) { this.synchronizeOnSession = synchronizeOnSession; } public final boolean isSynchronizeOnSession() { return synchronizeOnSession; } public final ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { checkAndPrepare(request, response, this instanceof LastModified); if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { return handleRequestInternal(request, response); } } } return handleRequestInternal(request, response); } protected abstract ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception; }
从上述代码可以看出,AbstractorController的工作流程如下:
1.DispatcherServlet调用handleRequest方法;
2.检查被支持的方法(GET/POST/PUT之一),若不支持则抛出ServletException;
3.若需要发起一个session,则尝试获取一个session,若获取不到,则抛出ServletException;
4.根据cacheSeconds属性,设定缓存头标的数据;
5.调用受保护的抽象方法handleRequestInternal,这个方法应由AbstractController的子类提供实际的功能实现,并返回ModelAndView对象。
package samples; public class SampleController extends AbstractController { public ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView modelAndView = new ModelAndView("hello"); modelAndView.addObject("message", "Hello World!"); return modelAndView; } }
<bean id="sampleController" class="samples.SampleController"> <property name="cacheSeconds" value="120"/> </bean>
2.
UrlFilenameViewControlle
org.springframework.web.servlet.mvc.multiaction,它能将客户请求与处理方法名字映射起来,并触发正确的方法。MultiActionController事实上是AbstractController的一个子类,而在应用中,MultiActionController的实现方式有两种:其一是继承MultiActionController,其二是在配置文件中定义一个代理bean,由它来定义哪个控制器是多动作的。
1.InternalPathMethodNameRe
2.ParameterMethodNameResol
3.PropertiesMethodNameReso
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app 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_5.xsd" version="2.5"> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcherServlet-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="sample.do">sampleMultiActionController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.InternalResourceView</value> </property> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <bean id="sampleMultiActionController" class="com.test.SampleMultiMActionController"> <property name="methodNameResolver"> <ref bean="paraMethodResolver"/> </property> <!--viewName属性将依赖注入sampleMultiActionController类--> <property name="viewName"> <value>showme</value> </property> </bean> <bean id="paraMethodResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> <property name="paramName" value="whichMethod"/> </bean> </beans>
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import java.io.IOException; import java.util.*; import javax.servlet.ServletException; import org.apache.log4j.Logger; import org.springframework.web.bind.*; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; org.springframework.web.servlet.mvc.multiaction.MultiActionController; public class SampleMultiActionController extends MultiActionController { private Logger logger=Logger.getLogger(this.getClass().getName()); private String viewName; //依赖注入一个名为viewName的参数,例如一个JSP文件,作为展示model的视图 public String getViewName (){ return this.viewName; } public void setViewName (String viewName){ this. viewName =viewName; } public ModelAndView insert(HttpServletRequest req, HttpServletResponse res) throws ServletRequestBindingException, IOException { Map model = new HashMap(); model.put("dataList", "新增数据..."); return new ModelAndView(getViewName(),model); } public ModelAndView update(HttpServletRequest req, HttpServletResponse res) throws ServletRequestBindingException, IOException { Map model = new HashMap(); model.put("dataList", "修改数据..."); return new ModelAndView(getViewName(),model); } public ModelAndView delete(HttpServletRequest req, HttpServletResponse res) throws ServletRequestBindingException, IOException { Map model = new HashMap(); model.put("dataList", "删除数据..."); return new ModelAndView(getViewName(),model); } }
<%@page c%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head>MuiltiActionController示例</head> <body> <c:out value="${model.dataList}"/> </body> </html>
http://localhost:8080/sample.do?whichMethod=insert
http://localhost:8080/sample.do?whichMethod=update
http://localhost:8080/sample.do?whichMethod=delete