SpringMVC应用程序架构----高级特性

Web 应用与MVC

目前比较好的MVC,老牌的有StrutsWebwork。新兴的MVC 框架有Spring MVCTapestryJSF等。这些大多是著名团队的作品,另外还有一些边缘团队的作品,也相当出色,如DinamicaVRaptor等。

这些框架都提供了较好的层次分隔能力。在实现良好的MVC 分隔的基础上,通过提供一些现成的辅助类库,同时也促进了生产效率的提高。

如何选择一个合适的框架?什么是考量一个框架设计是否优秀的标准?很难定夺的问题。旁观各大论坛中铺天盖地的论战,往往在这一点上更加迷茫。

从实际Web产品研发的角度而言(而非纯粹设计上,扩展性上,以及支持特性上的比较),目前Struts 也许是第一选择。作为一个老牌MVC FrameworkStruts 拥有成熟的设计,同时,也拥有最丰富的信息资源和开发群体。换句实在点的话,产品基于Struts 构建,如果公司发生人事变动,那么,找个熟悉Struts的替代程序员成本最低。

从较偏向设计的角度出发,WebWork2 的设计理念更加先进,其代码与Servlet API 相分离,这使得单元测试更加便利,同时系统从BS结构转向CS接口也较为简单。另外,对于基于模板的表现层技术(VelocityFreemarkerXSLT)的支持,也为程序员提供了除JSP之外的更多的选择(Struts也支持基于模板的表现层技术,只是实际中不太常用)。而对于Spring而言,首先,它提供了一个相当灵活和可扩展的MVC实现,与WebWork2相比,它在依赖注入方面、AOP 等方面更加优秀,但在MVC 框架与底层构架的分离上又与Webworks 存在着一定差距(Spring MVC Servlet API 相耦合,难于脱离Servlet容器独立运行,在这点的扩展性上,比Webwork2稍逊一筹)。

我们还要注意到,Spring对于Web应用开发的支持,并非只限于框架中的MVC部分。即使不使用其中的MVC实现,我们也可以从其他组件,如事务控制、ORM模板中得益。同时,Spring也为其他框架提供了良好的支持,如我们很容易就可以将Struts Spring 甚至WebWorkSpring 搭配使用(与WebWork 的搭配可能有些尴尬,因为两者相互覆盖的内容较多,如WebWork中的依赖注入机制、AOP机制等与Spring中的实现相重叠)。因此,对于SpringWeb应用中的作用,应该从一个更全面的角度出发。
第一个SpringMVC实例:
下面的实例,实现了一个常见的用户登录逻辑,即用户通过用户名和密码登录,系统对用户名和密码进行检测,如果正确,则在页面上显示几条通知信息。如果登录失败,则返回失败界面。
(
示例中,表示层以JSP2.0实现。)
出于简洁考虑,这里的用户名/密码检测以及通知信息的生成均在代码中以硬编码实现。
首先来看登录界面:
 
对应的index.html:
<form action="login.do" method="post">
      <table>
        <tr>
          <td>
用户名:</td>
          <td><input type="text" name="username" /></td>
        </tr>
       
        <tr>
          <td>
密码:</td>
          <td><input type="password" name="password"></td>
        </tr>
       
        <tr>
          <td colspan="2" align="right"><input type="submit" value="
提交" /></td>
        </tr>
      </table>
      </form>

MVC 关键流程的第一步,即收集页面输入参数,并转换为请求数据对象。这个静态页面提供了一个基本的输入界面,下面这些输入的数据将被发送至何处,将如何被转换为请求数据对象?
现在来看接下来发生的事情:
当用户输入用户名密码提交之后,此请求被递交给Web 服务器处理,上面我们设定form提交目标为"/login.do",那么Web服务器将如何处理这个请求?
显然,标准Http 协议中,并没有以.do 为后缀的服务资源,这是我们自己定义的一种请求匹配模式。此模式在web.xml中设定:
<?xml version="1.0" encoding="UTF-8"?>
<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">
 
 <servlet>
   <servlet-name>Dispatcher</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/Config.xml</param-value>
   </init-param>
 </servlet>
 
 <servlet-mapping>
   <servlet-name>Dispatcher</servlet-name>
   <url-pattern>*.do</url-pattern>
 </servlet-mapping>
 
</web-app>
Config.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="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass">
      <value>org.springframework.web.servlet.view.JstlView</value>
    </property>
  </bean>
 
  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
      <props>
        <prop key="/login.do">LoginAction</prop>
      </props>
    </property>
  </bean>
 
  <bean id="LoginAction" class="com.hit.action.LoginAction">
     <property name="commandClass">
       <value>com.hit.action.LoginInfo</value>
     </property>
    
     <property name="fail_view">
       <value>/WEB-INF/loginFail.jsp</value>
     </property>
    
     <property name="success_view">
       <value>/WEB-INF/loginSuccess.jsp</value>
     </property>
  </bean>
</beans>

View ResolverviewClass参数
这里我们使用JSP页面作为输出,因此,设定为:
org.springframework.web.servlet.view.JstlView
其余可选的viewClass还有:
Ø org.springframework.web.servlet.view.freemarker.FreeMarkerView
(用于基于FreeMarker模板的表现层实现)
Ø org.springframework.web.servlet.view.velocity.VelocityView
(用于基于velocity模板的表现层实现)等。


“urlMapping”
关系映射
可以看到,这里我们将“/login.do”请求映射到处理单元LoginAction<props>节点下可以有多个映射关系存在,目前我们只定义了一个。

LoginAction定义
这里定义了逻辑处理单元LoginAction 的具体实现,这里,LoginAction 的实现类为com.hit.action.LoginAction

LoginAction的请求数据对象
commandClass
参数源于LoginAction 的基类BaseCommandControllerBaseCommandControlle 包含了请求数据封装和验证方法( BaseCommandController.bindAndValidate ),它将根据传入的HttpServletRequest构造请求数据对象。
这里我们指定commandClass com.hit.action.LoginInfo,这是一个非常简单的Java Bean,它封装了登录请求所需的数据内容:
package com.hit.action;

public class LoginInfo {
 
 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;
 }

}

Spring会根据LoginActioncommandClass定义自动加载对应的LoginInfo实例。
之后,对Http 请求中的参数进行遍历,并查找LoginInfo 对象中是否存在与之同名的属性,如果找到,则将此参数值复制到LoginInfo对象的同名属性中.请求数据转换完成之后,我们得到了一个封装了所有请求参数的Java 对象,并将此对象作为输入参数传递给LoginAction

返回视图定义
对于这里的LoginAction 而言,有两种返回结果,即登录失败时返回错误界面,登录成功时进入系统主界面。对应我们配置了fail_viewsuccess_view两个自定义参数。之后,Resolver 会将LoginAction的返回数据与视图相融合,返回最终的显示界面。

LoginAction.java:
public class LoginAction extends SimpleFormController {
 
 private String success_view;
 private String fail_view;

 public String getFail_view() {
  return fail_view;
 }

 public void setFail_view(String fail_view) {
  this.fail_view = fail_view;
 }

 public String getSuccess_view() {
  retiurn success_view;
 }

 public void setSuccess_viiew(String success_view) {
  this.success_view = success_view;
 }

 @Override
 protected ModelAndView onSubmit(HttpServletRequest request,
                           HttpServletResponse response,
                           Object obj,
                           BindException ex) throws Exception {
  request.setAttribute("message", "success");
  return new ModelAndView(this.getSuccess_view());
 }


}

其中:
onSubmit方法
我们在子类中覆盖了父类的onSubmit方法;而onSubmit方法用于处理业务请求。
负责数据封装和请求分发的Dispatcher,将对传入的HttpServletRequest进行
封装,形成请求数据对象,之后根据配置文件,调用对应业务逻辑类的入口方法(这
里就是LoginAction)的onSubmit()方法,并将请求数据对象及其他相关资源引
用传入。
onSubmit
方法包含了两个或者四个参数:Object objBindException ex
前面曾经多次提到请求数据对象,这个名为objObject型参数,正是传入的请求
数据对象的引用。
BindException ex
参数则提供了数据绑定错误的跟踪机制。它作为错误描述工具,
用于向上层反馈错误信息。
Spring MVC中,BindException将被向上层表现层反馈,以便在表现层统一处
理异常情况(如显示对应的错误提示)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
[ 2021年,将Spring全家桶的课程进行Review,确保不再有顺序错乱等问题导致学员看不懂内容,进入2022年,将Spring的课程进行整理,整理为案例精讲的系列课程,并开始逐步增加高阶的Spring Security等内容,课件将逐步进行上传,敬请期待! ]本课程是Spring全家桶案例精讲课程的第二部分Spring MVC,Spring案例精讲课程以真实场景、项目实战为导向,循序渐进,深入浅出的讲解Java网络编程,助力您在技术工作中更进一步。 本课程聚焦Java Spring的Web知识点,主要是关于Spring MVC的应用,包含:表单的增删改查、国际化、过滤器、拦截器、日志Log4j2及slf4j的使用、主题更改网站皮肤及样式、文件上传等的案例讲解,并且最后以一个SSM(Spring+Spring MVC+Mybatis)贯穿前后台的案例作为Spring MVC课程的终奖, 从而使大家快速掌握Spring的基础核心知识,快速上手,为面试、工作等做好充足准备。 由于本课程聚焦于案例,即直接上手操作,对于Spring的原理等不会做过多介绍,希望了解原理等内容的需要通过其他视频或者书籍去了解,建议按照该案例课程一步步做下来,之后再去进一步回顾原理,这样能够促进大家对原理有更好的理解。 【通过Spring全家桶,我们保证你能收获到以下几点】 1、掌握Spring全家桶主要部分的开发、实现2、可以使用Spring MVC、Spring Boot、Spring Cloud及Spring Data进行大部分的Spring开发3、初步了解使用微服务、了解使用Spring进行微服务的设计实现4、奠定扎实的Spring技术,具备了一定的独立开发的能力  【实力讲师】 毕业于清华大学软件学院软件工程专业,曾在Accenture、IBM等知名外企任管理及架构职位,近15年的JavaEE经验,近8年的Spring经验,一直致力于架构、设计、开发及管理工作,在电商、零售、制造业等有丰富的项目实施经验 【本课程适用人群】如果你是一定不要错过!  适合于有JavaEE基础的,如:JSP、JSTL、Java基础等的学习者没有基础的学习者跟着课程可以学习,但是需要补充相关基础知识后,才能很好的参与到相关的工作中。 【Spring全家桶课程共包含如下几门】 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值