Spring的MVC web框架学习笔记

1、Spring web 框架的核心:DispatcherServlet

DispatcherServlet 用于接收请求。是使用Spring框架的入口。在web.xml中,需要配置该servlet。在配置该Servlet的时候url-pattern你可以使用你自己想使用的形式,如*.aspx,*.do,*.htm,*.action,用以混淆客户端对服务器架构的认识。

另外,该Servlet在容器中还会加载一个APPlicationContext的xml文件。默认加载的是[servlet-name]-servlet.xml。例如,你在web.xml中配置的servlet如下:

<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>*.form</url-pattern>
</servlet-mapping>
</web-app>
该Servlet就会在服务器启动时,加载example-servlet.xml。当然,你也可以自己来指定加载文件。
要看看DispatcherServlet真面目,打开源文件,发现定义了很多BeanName的常量,如本地化解析器beanname,主题解析器beanname,视图解析器beanname,上传文件解析的multipart解析器beanname。
等:
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
这个类怎么使用这些bean呢?以上面的exexample-servlet.xml为例,我们定义的名字为example的DispatcherServlet使用example-servlet.xml的配置。在example-servlet.xml里,我们可以配置名字上面的beanName的bean,来让servlet加载这些bean。
这下明白了,servlet.xml该怎么配置,该配置什么了。
好了,看完了最重要的servlet的配置问题,我们再看下一个重要的接口:Controller。至于上面servlet要使用的什么什么解析器啦,我们稍后在分析。
 
2、Controller
我们的请求提交到DispacherServlet后,会转给Controller。怎么找Controller?通过使用handlerMapping。如果没有设置handlerMapping,spring使用默认的BeanNameUrlHandlerMapping来找Controller。
BeanNameUrlHandlerMapping?顾名思义,就是通过bean的name属性来映射controller。bean的name请求是一个url,如果请求的是logout.do,在example-servlet.xml中定义一个名字(name)为login.do的Controller.

<bean name="/logout.do" class="com.jy.bookshop.web.spring.LogoutController">
    </bean>

再插一句话,在handlerMapping中,我们可以使用请求拦截器来对请求进行拦截处理。该拦截器怎么使用这里暂且不表,有机会再讨论。

ok,现在我们创建一个LogoutController来让他处理请求,让他实现Controller吧:

public class LogOutController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest req,
            HttpServletResponse res) throws Exception {
          …
        return new ModelAndView(new RedirectView("login.do"));
    }
}
看看这个Controller接口的定义,发现这个接口只定义了一个handleRequest方法。在这个方法中,返回一个ModelAndView。
先说ModelAndView。我们知道MVC,那么ModelAndView就是 MV了。Controller就是C。这样MVC全了。呵呵。
继续说ModelAndView,要了解他的结构,那自然要看看他的源代码了:
/** View instance or view name String */
private Object view; 

/** Model Map */
private ModelMap model;

   

    只关注我们关注的,里面包含了一个View对象和model对象。model对象是一个Map,这里不再说了。关键看看view,奇怪,怎么是一个Object,太抽象了。再继续看源代码的话,会更加明白:

 

public ModelAndView(String viewName, String modelName, Object modelObject) {
        this.view = viewName;
        addObject(modelName, modelObject);
    }
public void setViewName(String viewName) {
        this.view = viewName;
    }

<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> 原来这个view可以指向一个View对象,也可以指向String对象啊。View一个接口,如果看doc的话,他的实现类有AbstractExcelView, AbstractJasperReportsSingleFormatView, AbstractJasperReportsView, AbstractJExcelView, AbstractPdfStamperView, AbstractPdfView,AbstractTemplateView, AbstractUrlBasedView, AbstractView, AbstractXsltView, ConfigurableJasperReportsView, FreeMarkerView, InternalResourceView,JasperReportsCsvView, JasperReportsHtmlView, JasperReportsMultiFormatView, JasperReportsPdfView, JasperReportsXlsView, JstlView, RedirectView,TilesJstlView, TilesView, TilesView, VelocityLayoutView, VelocityToolboxView, VelocityView, XsltView(诚实的说,这些View是拷doc的)。

现在可以知道,我们的Controller返回一个View和Model,来让Spring框架来创建一个回应。

现在奇怪的还有一点,我吧view设置为字符串,Spring框架怎么处理?在ModelAndView中,如果view是一个字符串,则会将这个值交给DispatcherServlet的viewResovler来处理。记得上面提到的viewResovler了吗?呵呵,派上用场了。

view的问题解决了,然后再说model吧。在ModelAndView添加了一些对象,Spring是怎么处理的呢?总应该把这些对象给弄到request对象里,让jsp页面来使用吧。让View使用?那么看看View接口吧:

public interface View {

    String getContentType();

    void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception;

}
render函数需要带一个model变量。再找找view的实现类,看看是怎么工作的。不过view有那么多,对于一些像什么pdf啦,excel了他们都不需要在request中添加这个model。
最终呢,我们在jstlView的父类InternalResourceView中的renderMergedOutputModel函数发现他把model放在了request里面了。
 
OK,现在我们明白了,controller返回的modelandview交给Servlet进行处理,来生成一个页面。
最简单的Controller介绍完毕。现在看看Spring提供的一些controller的实现,Spring提供了很多controller的实现,继承的结构如下:

 

org.springframework.web.servlet.mvc.AbstractController (implements org.springframework.web.servlet.mvc.Controller)

  • org.springframework.web.servlet.mvc.AbstractUrlViewController
    • org.springframework.web.servlet.mvc.UrlFilenameViewController
  • org.springframework.web.servlet.mvc.BaseCommandController
    • org.springframework.web.servlet.mvc.AbstractCommandController
    • org.springframework.web.servlet.mvc.AbstractFormController
      • org.springframework.web.servlet.mvc.AbstractWizardFormController
      • org.springframework.web.servlet.mvc.SimpleFormController
        • org.springframework.web.servlet.mvc.CancellableFormController
  • org.springframework.web.servlet.mvc.ParameterizableViewController
  • org.springframework.web.servlet.mvc.ServletForwardingController (implements org.springframework.beans.factory.BeanNameAware)
  • org.springframework.web.servlet.mvc.ServletWrappingController (implements org.springframework.beans.factory.BeanNameAware, org.springframework.beans.factory.DisposableBean, org.springframework.beans.factory.InitializingBean)
AbstractController是Controller的第一个实现。其他的Controller都是继承这个Controller的。我们先看比较重要的Controller。
先说UrlFilenameViewController。不如我们自己来部署一个吧。
在example-servlet.xml中增加如下的配置:

<bean name="/error.do"  class="org.springframework.web.servlet.mvc.UrlFilenameViewController">
    </bean>

OK,当/error.do的请求上来后,urlFileNameViewController将他变成/error。然后返回个View,这个view的name就是/error,然后使用viewresolver来进行解析,可以解析成/jsp/error.jsp。
另外还有比较重要的controller是baseCommandController,将请求参数转换为一个对象,并对对象参数合法性进行验证。另外,SimpleFormController可以对表单进行处理。
关于各个controller的分析。未完待续。。

 

 
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>

 

<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值