可以替代struts 单纯从简单的业务逻辑来说,性能高于struts2
(struts1是基于servlet,struts2是基于Filter)
运行流程:
核心组件:1、DispatcherServlet 分发器:配置在web.xml中,配置一次即可
2、HandlerMapping 功能:类似于struts中的配置文件的功能,将请求的类型根据相应的配置发送给对应的controller(可以自己配置也可以默认:根据beanname)
3、Controller 核心控制。
4、ModelAndView 返回一个modelAndView对象,包含model用来传值。
5、ViewResolver 视图解析器。
6、View JSP页面。
需要关注的是:controller和jsp即可。其他配置好即可。
在开始导入相应的jar包后开始第一个示例:
配置分发器:
<?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">
<!-- 核心分发器DispatcherServlet -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<!-- 与servlet名字相同,配置的映射路径为所有的.action -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
配置好了分发器后:所有的.action的访问都是访问的该分发器了,下一步就需要定义一个Controller
示例:HomeController
package com.itheima.springmvc.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class HomeController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
System.out.println(arg0.getContextPath() + arg0.getServletPath()); //获得url
return new ModelAndView("index"); //返回ModelAndView,传入的参数被称为逻辑名。
}
}
从上例中可以很容易的看出,只要实现了AbstractController抽象类,复写其中的handleRequestInternal方法,在该方法内部实现业务逻辑操作,
然后new一个ModelAndView对象并将返回的逻辑名(其实和struts2中的return到哪里的的概念一样)传入即可。
那么这里定义好了Controller后,返回的逻辑名spring并没有定义和配置,所以这里还需要在配置一个文件。
示例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean name="/h.action" class="com.itheima.springmvc.controller.HomeController">
<!-- name为指定访问时的虚拟路径,即uri 。 class指定控制器,这样spring会自动创建该类实例。分发起会自动访问该类。 -->
</bean>
<!-- 内部资源视图解析器:解析器有好多种,这里只是其中一种 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀 , value中设置值,设置为/时默认是从根目录开始寻找,此配置就是寻找根目录下return中参数的值和后缀拼接后的文件-->
<property name="prefix" value="/"></property>
<!--后缀 -->
<property name="suffix" value= ".jsp"></property>
</bean>
</beans>
*注意*:这里的配置的的名字及路径问题,首先路径必须在web-inf下否则会报io异常。
而名字的格式必须是web.xml中配置的分发器的名字+-servlet.xml,例如本例中名字
必须为:action-servlet.xml。这样才可以正常运行。
这样的方式无疑很死板,下面介绍更灵活的方式。
解决方案:
在web.xml中配置:init-param参数。参数名固定为contextConfigLocation,value配置classpath:对应路径即可。
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
<!-- load-on-startup 配置默认启动的优先级1-10之间 -->
</servlet>
这样配置后就可以将配置文件放在任何地方了,名字也可以随意更改了。原理就是通知spring你的更改而已。
============================================================================================================================================
常用的几个Handler:
<!-- 处理器映射 -->
<!-- BeanNameUrlHandlerMapping处理器映射 ,默认的handler,如果不指定,则自动使用该Handler -->
1、<bean id="beanNameUrlHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="order" value="1"/>
<!--配置此属性的目的是为了解决当出现两个配置都指定一个controller时,优先级的配置
观看源码得知,内部使用sort进行了排序。
-->
</bean>
<!-- SimpleUrlHandlerMapping处理器映射 -->
2、<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/h.action">hc</prop>
<prop key="/a.action">hc</prop>
<prop key="/b.action">hc</prop>
<prop key="/d.action">hc</prop>
</props>
</property>
<property name="order" value="0"/> <!-- 值越小优先级越高 -->
</bean>
3、<!-- 类名处理器映射:规则:得到类名HomeControlller,将Controller去掉,剩下的全部小写。如多个单词也全小写 -->
<bean id="controllerClassNameHandlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
</bean>
============================================================================================================================================
几种常用的Controller:
1、CommandController命令控制器:将参数封装在Command Object对象中
示例:
public class PersonCommandController extends AbstractCommandController {
public PersonCommandController(){
//注册命令类,将commond定义为需要对应的类型。名字用来在页面view层时调用 例:${person.id}
this.setCommandClass(Person.class);
this.setCommandName("person");
}
protected ModelAndView handle(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {
Person p = (Person) command;
System.out.println(p.toString());
return new ModelAndView("index");
}
注意:访问时url多个单词全小写。
============================================================================================================================================
2、SimpleFormController简单表单控制器
该控制器根据请求参数执行的流程会不相同:
当请求方式为get时:经过controller后直接返回回到页面
当请求方式为post时:经过controller后,可以与service层进行交互,然后在返回页面。
示例:
public class PersonFormController extends SimpleFormController {
//注册命令对象
public PersonFormController() {
this.setCommandClass(Person.class);
this.setCommandName("person");
}
protected void doSubmitAction(Object command) throws Exception {
Person p = (Person) command;
System.out.println(p.toString());
}
}
因为两种请求方式,两种结果,需要在配置中声明出来不同的请求方式对应的不同的操作:
spring-mvc.xml
<!-- 表单控制器(处理表单提交) -->
<bean id="personFormController" class="cn.itcast.springmvc.web.controller.PersonFormController">
<!-- 表单视图 post方式 -->
<property name="formView" value=“jPersonCreate"/>
<!-- 成功视图 get方式-->
<property name="successView" value="index"/>
</bean>
============================================================================================================================================
3、WizardFormController向导控制器
示例:
java代码:
public class MyWizardFormController extends AbstractWizardFormController {
public MyWizardFormController() {
this.setCommandClass(Person.class);
this.setCommandName("person");
}
//处理完成时的跳转
protected ModelAndView processFinish(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {
Person p = (Person) command;
System.out.println(p.toString());
return new ModelAndView("index");
}
//处理取消时的跳转
protected ModelAndView processCancel(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {
return new ModelAndView("wizard/jPersonBaseInfo");
}
}
配置:
spring-mvc.xml
<!-- 向导表单控制器 -->
<bean id="myWizardFormController" class="cn.itcast.springmvc.web.controller.MyWizardFormController">
<property name="pages">
<list>
<value>wizard/jPersonBaseInfo</value>
<value>wizard/jPersonEduInfo</value>
<value>wizard/jPersonWorkInfo</value>
</list>
</property>
</bean>
在WEB-INF/jsps下建立wizard目录
在jsp页面中需要注意的地方:
<td>
<input type="submit" name="_target1" value="上一步" />
<input type="submit" name="_cancel" value="取消" />
<input type="submit" name="_finish" value="完成" />
</td>
注意:在页面中的标签中的name为固定写法,对应的相应操作,与list列表的页面想对应。另外请求方式必须是post方式请求才可以。
关于回显:就是model绑定的bean类型,自动会返回页面,直接用this.setCommandName("person");中的参数person或其他调用即可。