spring3.1 mvc+spring

11年前

学习了一段时间的spring mvc,个人觉得在配置方面相比struts更为简单。RESTful URL、几乎0配置、不需要实现任何接口或继承任何类的Controller、方法级别的拦截,一个方法对应一个url、灵活的方法参数和返回值、多种view、处理ajax的请求更是方便...

lib 如下:


web.xml如下:

<?xml version="1.0" encoding="UTF-8"?>  <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">   <filter>    <filter-name>encodingFilter</filter-name>    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>    <init-param>     <param-name>encoding</param-name>     <param-value>UTF-8</param-value>    </init-param>    <init-param>     <param-name>forceEncoding</param-name>     <param-value>true</param-value>    </init-param>   </filter>   <filter-mapping>    <filter-name>encodingFilter</filter-name>    <url-pattern>*.htm</url-pattern>   </filter-mapping>   <servlet>    <servlet-name>spring3</servlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <load-on-startup>1</load-on-startup>   </servlet>   <servlet-mapping>    <servlet-name>spring3</servlet-name>    <url-pattern>*.htm</url-pattern>   </servlet-mapping>   <error-page>    <error-code>404</error-code>    <location>/error/e-404.html</location>   </error-page>   <error-page>    <error-code>500</error-code>    <location>/error/e-500.jsp</location>   </error-page>   <welcome-file-list>    <welcome-file>index.jsp</welcome-file>   </welcome-file-list>  </web-app>

子上下文文件声明:
1、不写,使用默认值:/WEB-INF/<servlet-name>-servlet.xml
2、<param-value>/WEB-INF/classes/springMVC.xml</param-value>
3、<param-value>classpath*:springMVC-mvc.xml</param-value>
4、多个值用逗号分隔
注:我们这里默认/WEB-INF/spring3-servlet.xml

父子上下文说明:

Spring会创建一个WebApplicationContext上下文,称为父上下文(父容器) ,保存在 ServletContext中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。

可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);

 

DispatcherServlet是一个Servlet,可以同时配置多个,每个 DispatcherServlet有一个自己的上下文对象(WebApplicationContext),称为子上下文(子容器),子上下文可以访问父上下文中的内容,但父上下文不能访问子上下文中的内容。 它也保存在 ServletContext中,key是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。当一个Request对象产生时,会把这个子上下文对象(WebApplicationContext)保存在Request对象中,key是DispatcherServlet.class.getName() + ".CONTEXT"。

可以使用工具类取出上下文对象:RequestContextUtils.getWebApplicationContext(request);

 

说明 :Spring 并没有限制我们,必须使用父子上下文。我们可以自己决定如何使用。我们这里用的是自上下文。

上下文配置:

<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-3.0.xsd               http://www.springframework.org/schema/context                http://www.springframework.org/schema/context/spring-context-3.0.xsd"   default-autowire="byName">   <!-- 如果有多个 DispatcherServlet 请把关于数据库和server部分的bean在web.xml中使用spring 的 listener加载-->   <!-- 自动扫描controller bean,把作了注解的类转换为bean -->   <context:component-scan base-package="com.springdemo" />   <!-- 事务  -->   <bean id="transactionManager"    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource" ref="dataSource" />   </bean>   <!-- 数据源 -->    <bean id="dataSource"    class="org.apache.commons.dbcp.BasicDataSource">    <property name="driverClassName"     value="oracle.jdbc.driver.OracleDriver">    </property>    <property name="url"     value="jdbc:oracle:thin:@127.0.0.1:1521:orcl">    </property>    <property name="username" value="test"></property>    <property name="password" value="test"></property>   </bean>   <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->   <bean    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />   <!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->   <bean    class="org.springframework.web.servlet.view.InternalResourceViewResolver"    p:prefix="/WEB-INF/view/" p:suffix=".jsp">    <property name="order" value="0"/>   </bean>   <!-- 自定义exception处理 -->   <bean id="exceptionResolver" class="com.springdemo.core.CommonExceptionHandler"/>   <!-- 国际化 -->   <bean id="messageSource"    class="org.springframework.context.support.ResourceBundleMessageSource">    <property name="basenames">     <list>      <value>i18n/messages</value>     </list>    </property>    <property name="useCodeAsDefaultMessage" value="true" />   </bean>   <!-- 国际化 end-->    </beans>  

spring也支持了jndi(这里就不再讲解jndi了):

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">       <property name="jndiName">        <value>myTestDataSource</value>   </property>   <!-- 如果你不想使用 'java:comp/env/'前缀的话请设置下面的值为true, 默认值为false -->   <property name="resourceRef">       <value>false</value>   </property>  </bean>

 好了到这里我们的配置基本上就完了。。在编写业务代码前还有一些知识需要大家去学习一下:

常用注解:

@Controller 声明Action组件
@Service    声明Service组件    @Service("myMovieLister")
@Repository 声明Dao组件
@Component   泛指组件, 当不好归类时.
@RequestMapping("/menu")  请求映射
@Resource  用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName")
@Autowired 用于注入,(srping提供的) 默认按类型装配
@Transactional( rollbackFor={Exception.class}) 事务管理
@ResponseBody
@Scope("prototype")   设定bean的作用域


contorller代码:

package com.springdemo.module.usermgr.controller;    import java.util.List;    import javax.servlet.http.HttpSession;    import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Controller;  import org.springframework.ui.ModelMap;  import org.springframework.web.bind.annotation.PathVariable;  import org.springframework.web.bind.annotation.RequestMapping;  import org.springframework.web.bind.annotation.RequestMethod;  import org.springframework.web.servlet.ModelAndView;    import com.springdemo.core.ActionException;  import com.springdemo.core.BaseContoller;  import com.springdemo.core.ServiceException;  import com.springdemo.module.usermgr.service.UserMgrService;  import com.springdemo.module.usermgr.vo.SUser;  /**   * 用户登录管理   * @author joe   * @date  2011-10-24 下午03:34:39   */  @Controller  public class UserLoginMgr extends BaseContoller{   @Autowired   private UserMgrService userMgrService;      @RequestMapping(value="saveLogin.htm",method=RequestMethod.POST)      public ModelAndView saveLogin(HttpSession session,SUser user,ModelMap modelMap){    if(user!=null){     String userName = user.getUserName();     try {      SUser dbuser = userMgrService.getUserByUserName(userName);      if(dbuser==null){       //成功后重定向的欢迎界面,防止重复提交       return new ModelAndView("login",COMMON_FAIL_ALERT_KEY,"用户不存在!");      }      if(!dbuser.getPwd().equals(user.getPwd())){              return new ModelAndView("login",COMMON_FAIL_ALERT_KEY,"密码错误!");      }            session.setAttribute(USER_SESSION_KEY, dbuser);     } catch (ServiceException e) {      e.printStackTrace();     }    }    //成功后重定向的欢迎界面,防止重复提交    return new ModelAndView("redirect:login_succ.htm");      }   //获取   @RequestMapping(value="get/{id}.htm",method=RequestMethod.GET)      public ModelAndView get(@PathVariable Integer id) throws Exception{    SUser sUser = userMgrService.getUserById(id);     if(sUser==null){     throw  new ActionException("用户["+id+"]不存在!");     }    return new ModelAndView("user_detail","user",sUser);      }   //列表   @RequestMapping(value="list.htm",method=RequestMethod.GET)      public ModelAndView list() throws ServiceException{    List<SUser> users = userMgrService.getUsers();    return new ModelAndView("/test/user_list","users",users);      }   //注册成功   @RequestMapping(value="login_succ.htm")   public  String signuoSucc(HttpSession session,ModelMap map){    SUser user = (SUser) session.getAttribute(USER_SESSION_KEY);    if(user==null){     return "redirect:login.htm";    }    map.put("user", user);    return "index";   }   @RequestMapping("logout.htm")   public String logout(HttpSession session){    session.invalidate();    return "redirect:login.htm";   }   //首页   @RequestMapping(value="index.htm")   public  String index(){    return "forward:login_succ.htm";   }  }


service代码:

 

package com.springdemo.module.usermgr.service;    import java.util.Date;  import java.util.List;    import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.dao.EmptyResultDataAccessException;  import org.springframework.stereotype.Service;    import com.springdemo.core.BaseService;  import com.springdemo.core.ServiceException;  import com.springdemo.module.usermgr.dao.UserMgrDao;  import com.springdemo.module.usermgr.vo.SUser;  @Service("userMgrService")  public class UserMgrService extends BaseService{     @Autowired   private UserMgrDao userMgrDao;   public void signUp(SUser user) throws ServiceException{    try {     user.setSignUpTime(new Date());     userMgrDao.addUser(user);    } catch (Exception e) {     throw new ServiceException("注册失败", e);    }       }   public SUser getUserById(Integer id) throws ServiceException{    try {     return userMgrDao.getUserByColunm("id",id);    } catch (Exception e) {     throw new ServiceException("获取失败", e);    }   }   public List<SUser> getUsers() throws ServiceException{    try {     return userMgrDao.getUsers();    } catch (Exception e) {     throw new ServiceException("获取失败", e);    }   }   public SUser getUserByUserName(String userName) throws ServiceException {    try {     return userMgrDao.getUserByColunm("userName",userName);    } catch (Exception e) {     if(e instanceof EmptyResultDataAccessException){      return null;     }     throw new ServiceException("获取失败", e);    }   }  }

model 代码:
package com.springdemo.module.usermgr.dao;    import java.util.List;    import org.springframework.jdbc.core.BeanPropertyRowMapper;  import org.springframework.stereotype.Repository;    import com.springdemo.core.BaseDao;  import com.springdemo.module.usermgr.vo.SUser;    @Repository("userMgrDao")  @SuppressWarnings("unchecked")  public class UserMgrDao extends BaseDao{     public SUser addUser(final SUser sUser){      sUser.setId(super.saveAndReturnKey(sUser).intValue());      return sUser;    }     public List<SUser> getUsers() {    return getJdbcTemplate().query("select *  from suser", new BeanPropertyRowMapper(SUser.class));   }   public SUser getUserByColunm(String columnName, Object value) {    return getJdbcTemplate().queryForObject("select *  from suser where "+columnName+"=?", new BeanPropertyRowMapper(SUser.class),value);   }  }

jap 代码:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  <html>    <body>    <h3>用户登录</h3>    ${fail_key }<br/>      <form action="<%=request.getContextPath() %>/saveLogin.htm" method="post">        username:<input type="text" name="userName" ><br/>        password:<input type="password" name="pwd"/><br/>        <input type="submit"/>      </form>      <br/>     <a href="javascript:void(0);"      onclick="javascript:self.location='<%=request.getContextPath() %>/usermgr/signup.htm'">注册</a>    </body>  </html>
这里附件太大 有需要实例的留邮箱~