Spring 的 Web MVC 框架是围绕 DispatcherServlet 设计的,它把请求分派给处理程序,同时带有可配置的处理程序映射、视图解析、本地语言、主题解析以及上载文件支持。默认的处理程序是非常简单的 Controller 接口,只有一个方法 ModelAndView handleRequest(request, response)。Spring 提供了一个控制器层次结构,可以派生子类。如果应用程序需要处理用户输入表单,那么可以继承 AbstractFormController。如果需要把多页输入处理到一个表单,那么可以继承 AbstractWizardFormController。
核心类与接口:
DispatcherServlet -- 前置控制器
HandlerMapping接口 -- 处理请求的映射
SimpleUrlHandlerMapping 通过配置文件,把一个URL映射到Controller
DefaultAnnotationHandlerMapping 通过注解,把一个URL映射到Controller类上
HandlerAdapter接口 -- 处理请求的映射
AnnotationMethodHandlerAdapter类,通过注解,把一个URL映射到Controller类的方法上
Controller接口 -- 控制器
由于我们使用了@Controller注解,添加了@Controller注解注解的类就可以担任控制器(Action)的职责,并没有用到这个接口。
ModelAndView类
DispatcherServlet说明
使用Spring MVC,配置DispatcherServlet是第一步。DispatcherServlet是一个Servlet,所以可以配置多个DispatcherServlet。DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller(我们写的Action)来处理。
在DispatcherServlet的初始化过程中,框架会在web应用的 WEB-INF文件夹下寻找名为[servlet-name]-servlet.xml 的配置文件,生成文件中定义的bean。
Servlet拦截匹配规则可以自已定义,Servlet拦截哪种URL合适?
当映射为@RequestMapping("/user/add")时:
1、拦截*.do,例如:/user/add.do,弊端:所有的url都要以.do结尾。不会影响访问静态文件。
2、拦截/app/*,例如:/app/user/add,弊端:请求的url都要包含/app,@RequestMapping("/user/add")中不须要包含/app。
3、拦截/,例如:/user/add,弊端:对jpg,js,css静态文件的访问也被拦截不能正常显示。后面有解决办法。
4、拦截/*,可以走到Action中,但转发到jsp时再次被拦截,不能访问到jsp。
<context:component-scan/> 扫描指定的包中的类上的注解,常用的注解有:
@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的作用域
<mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。
并提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。
后面,我们处理响应ajax请求时,就使用到了对json的支持。
后面,对action写JUnit单元测试时,要从spring IOC容器中取DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,来完成测试,取的时候要知道是<mvc:annotation-driven />这一句注册的这两个bean。
<mvc:default-servlet-handler/> 使用默认的Servlet来响应静态文件。
<mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/> 匹配URL /images/** 的URL被当做静态资源,由Spring读出到内存中再响应http。
下面开始讲解springmvc的使用了,在以后的章节会详解springmvc的运行机制
1、添加springmvc的jar文件(会常用这些38个文件,建个springmvcHibernate目录,把这些jar包放在里面):
![15、springMVC+spring+hibernate_第1张图片](http://img.e-com-net.com/image/product/03f548a93b0a4459a212e34745d27310.jpg)
报错:Server Tomcat v8.0 Server at localhost failed to start:关闭eclipse 关闭javaw.exe进程,重启eclipse;
若还不能启动:删除所用servers,及servers左边目录、运行环境;然后再添加运行环境;
报错:java.lang.ClassCastException: Cannot cast org.springframework.web.SpringServletContainerInitializer 类型转换出错:
右击web工程-》属性或Build Path-》Java Build Path->Libraries-> Add Libray...->Server Runtime -》Tomcat Server;切换到Java Build Path界面中的Orader and Export,选择Tomcat。
报错:Connection refused: connect
电脑管理 启动mysql服务;
2、配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<filter>
<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/web-servlet.xml,classpath*:config/dao-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.1、配置web-servlet.xml文件 src/config/
<?xml version="1.0" encoding="UTF-8"?>
<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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<!--扫描基本包src目录下 -->
<context:component-scan base-package="org.springmvc.web"/>
<!--扫描注解 -->
<mvc:annotation-driven />
<!-- 添加视图解析器,添加前缀后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
2.2、配置dao-servlet.xml文件 src/config/
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="org.springmvc.model"/>
<!--相同内容只在一个xml中配置就行 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"></property>
<property name="username" value="root"></property>
<property name="password" value="111122"></property>
<!-- 连接池启动时的初始值 -->
<property name="initialSize" value="3"/>
<!-- dbcp的最大值 -->
<property name="maxActive" value="100"/>
<!-- 最大空闲值,当经历连接高峰后减少连接数到最大空闲连接数时,不再减少连接数-->
<property name="maxIdle" value="2"/>
<!-- 最小空闲值,即使没有数据传输也不让连接关闭-->
<property name="minIdle" value="2"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hiberante.format_sql">true</prop>
</props>
</property>
<!-- hibernate获取pojo对象mapping -->
<property name="configLocations">
<list>
<value>
classpath*:org/springmvc/model/hibernate.cfg.xml
</value>
</list>
</property>
</bean>
</beans>
2.2.1、添加hibernate.cfg.xml文件src/org/springmvc/model/
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="org.springmvc.model.User"/>
</session-factory>
</hibernate-configuration>
3、添加Entity/POJO/VO/model类 src/org.springmvc.model 数据库中原先没有这张表,执行sessionfactory时就创建了这张表,添加get/set方法
package org.springmvc.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
4、添加页面处理ModelAndView类,注解实现Controller接口
package org.springmvc.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ViewController {
@RequestMapping("ok")
public ModelAndView handleRequest(HttpServletRequest arg0,HttpServletResponse arg1) throws Exception {
//返回到web-inf/pages/ok.jsp,建好ok.jsp测试:http://localhost:8080/springmvc/ok
return new ModelAndView("/ok");
}
}
5、添加测试页面/web-inf/pages/ok.jsp
<body>
顶顶顶顶
</body>
上面实现了springmvc+hibernate+spring的搭建;下面将讲解前端页面的操作和对数据库表的操作,这就是配置两个web-servlet.xml和dao-servlet.xml区分管理;
前端页面操作:
1、对页面返回值的管理;
从ModelAndView的构造方法中,view=viewName;转换,并可以传递参数
public ModelAndView(String viewName)
public ModelAndView(View view)
public ModelAndView(String viewName, String modelName, Object modelObject)
public ModelAndView(View view, String modelName, Object modelObject)
给前端传递一个String型对象:更改测试类ViewController 和测试jsp
String s="hello!my friends";
return new ModelAndView("/ok","u",s);
前端用EL表达式接收
${u}
给前端传递一个User对象:更改测试类ViewController 和测试jsp
User u=new User();
u.setId(2);
u.setName("skx"); //没有插入数据表中
return new ModelAndView("/ok","u",u);
${u.id}号: ${u.name}
给前端传递一个List集合对象:更改测试类ViewController 和测试jsp
报错:org.apache.jasper.JasperException: jstl书写有误,仔细检查
List l=new ArrayList();
l.add("str");
l.add("oop");
return new ModelAndView("/ok","u",l);
注意:items是有引号的
<c:forEach var="e" items="${u}">
${e}
</c:forEach>
给前端传递一个Map集合对象:更改测试类ViewController 和测试jsp
Map m=new HashMap();
m.put("w", "will");
m.put("s","skx");
return new ModelAndView("/ok","u",m);
<c:forEach var="e" items="${u}">
${e.key}======${e.value}<br>
</c:forEach>
2、前端传递数据给后台:http://localhost:8080/springmvc/view?name=ok&age=32 //汉字会乱码
@RequestMapping("view")
public ModelAndView view(String name,int age) throws Exception { //这里name和age一定要和前端一致
List l=new ArrayList();
l.add(name);l.add(age);
return new ModelAndView("/ok","u",l);
}
3、ModelAndView 可以用String替代,但要用到内置对象request返回值;http://localhost:8080/springmvc/view2?name=ok&age=3222
@RequestMapping("view2")
public String view2(String name,int age,HttpServletRequest request) throws Exception { //这里name和age一定要和前端一致
List l=new ArrayList();
l.add(name);l.add(age);
request.setAttribute("u", l);
return "/ok";
}
可以强制将前端传来的数据转换类型:(@RequestParam("who")String name)
#4、自动匹对传值给后台model: http://localhost:8080/springmvc/set?name=ok&id=3
@RequestMapping("set")
public String set(User u,HttpServletRequest request) throws Exception { //这里id和name是u的属性,自动封装;
request.setAttribute("u", u);
return "/ok";
}
从4这个例子可以得出:在表单传递给后台时,不用手工封装,容器自动为我们封装;
下面将进行数据库方面的操作(spring 提倡接口编程+事务控制):
获取会话工厂实例的类FactoryService,和操作接口FactoryInterf ;
添加包org.springmvc.service.inter,添加操作接口
import org.springmvc.model.User;
public interface FactoryInterf {
public void insertUser(User u);
public void deleteUser(int i);
public void updateUser(int i);
public void queryByString(String[] str);
public void queryById(int i);
}
添加包org.springmvc.service
package org.springmvc.service;
import org.hibernate.SessionFactory;
import org.springmvc.model.User;
import org.springmvc.service.inter.FactoryInterf;
public class FactoryService implements FactoryInterf {
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
//复写接口方法
}
在dao-servlet.xml中为FactoryService的会话工厂sessionFactory赋值:
<bean id="factoryService" class="org.springmvc.service.FactoryService" >
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
在dao-servlet.xml中添加事务控制:
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
报错:No bean named 'fcatoryService' is defined
1、添加数据:
2
2
2
参考:
http://blog.sina.com.cn/s/blog_a795a96f01016if1.html