SpringMvc学习与使用

问题?SpringMvc学习与使用  SpringMvc的运行流程 SpringMvc是什么? SpringMvc作用是什么?  SpringMvc相比其他框架有什么优势?


一、SpringMvc是什么?

Spring MVC属于SpringFrameWork的后续产品,Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块,使用 Spring 可插入的 MVC架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架。说白了它是基于spring在MVC上的一个框架

二、SpringMvc的作用是什么?

框架的作用都是为了提高代码的质量,也就是高质量的代码,而不是提高代码的性能。各种框架都有各自的性能,各不相同各自有可取之处也有不可取之处。当然,springmvc也有它的优势,它的处理器映射机制、控制器、分发器、处理各个程序之间的处理机制,变得非常容易


三、SpringMvc相比其他框架有什么优势?

打个比较,就s2sh框架和springmvc框架的比较来看,SSH框架的系统从职责上分为四层:表示层、业务逻辑层、数据持久层和域模块层,以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的Web应用程序。


SpringMVC和SSH的比较:

springmvc比较接近原生servlet,灵活度高。而且因为springmvc的controller是单例的,以及没有大量的过滤器,性能要比struts2好。SSH中操作数据库使用的是Hibernate的数据映射,操作的是对象。Hibernate本来就是基于JDBC的封装,所以较之执行原生态SQL效率上肯定比操作对象更快。还有最重要的一点就是springmvc开发起来更加便利,或许在总体性能上来说,不算是最好的。


Struts1使用JSTL EL表达式,但是对集合和索引属性的支持很弱。Struts2采用OGNL
struts2是类级别的拦截, 一个类对应一个request上下文,springmvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应。
Strust1中通常以action访问时.do,struts2、spring mvc 都是以.action做结尾。
spring3 mvc可以认为已经100%零配置了。


注意它是如何保证安全的:springmvc controller是单例模式,整个程序只有一个对象实例。Spring的安全性是通过绑定threadlocal实现


注意:如果想使用Spring来实现Hibernate的功能,那么可以知己封装

               SpringMvc学习与使用_第1张图片

四、SpringMvc的运行流程

1.struts2与springmvc的比较

Stuts2类级别,例如:model,request,response,类中所有的方法都共享
Struts2使用model对象来从页面封装参数到action;从action封装数据到页面;(双向
SpringMVC方法级别,例如:model(MAP),只从action封装数据到页面单向:但是springmvc有办法解决

       SpringMvc学习与使用_第2张图片

从这里就可以看出,springmvc的速度空前的


2.springmvc的工作原理(Struts和springmvc工作原理图比较)

               SpringMvc学习与使用_第3张图片


springmvc:Jsp——>DispatcherServlet分发器——>通过handlerMapping处理器映射找到要处理的controller——>最后处理完返回结果(newModelAndView)并通过视图解析器找到返回路径——>回到Jsp


3.springmvc的核心知识点儿

(1)分发器DispacherServlet是什么,它的作用是什么?

(2)处理器映射handlerMapping是什么?它的工作原理是什么?

(3)如何找到逻辑controller层,有哪几种方式?

(4)试图解析器是ViewResolver什么?如何构造?


4.常用的handlerMapping处理器映射

作用:分发器发过来的请求,通过该处理器映射找到对应的controller层的类及方法,这就是它的作用

1.第一种:BeanNameUrlHandlerMapping(默认)

2.第二种:SimpleUrlHandlerMapping(通过ID访问)

3.第三种:ControllerClassNameHandlerMapping(通过类名访问)


5.常用的控制器有哪些?

1.命令控制器

2.表单控制器

3.向导表单控制器


五、SpringMvc的使用

1.开发步骤,简单体验最简单的springmvc:

(1)、新建web project
(2)、引入jar包
(3)、配置分发器servlet DispatchServlet
(4)、创建控制器类
(5)、配置beans
(6)、创建jsp文件
(7)、发布、测试


jar包下载:Spring-framework官网下载地址:点击打开链接 本地下载还有案例:点击打开链接


   SpringMvc学习与使用_第4张图片


当然如果怕出现错误:你把spring-freamwork的所有包的全部导进去,绝对没问题。

web.xml中配置分发器:

  <servlet>
  	<servlet-name>action</servlet-name><!-- servlet-name和配置文件的前面名字相同 -->
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>action</servlet-name>
  	<url-pattern>*.action</url-pattern><!-- 这里不能换成/*,会出错的 -->
  </servlet-mapping>

创建一个控制类继承了 AbstractController

package cn.itcast.com.controler;

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 request,
			HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		System.out.println(request.getParameter("username"));
		System.out.println(request.getRequestURI());
		System.out.println(request.getRequestURL());
		
		return new ModelAndView("customer/form1");//这里就是逻辑名
	}

}

在WEB-INF下创建action-servlet.xml,必须是这个名字,因为它的源码决定的(当然后期可以更改,改配置文件)。

<?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.0.xsd">
						
	<!-- 1.配置handlerMapping处理器映射 -->
		<!-- 默认:BeanNameUrlHandlerMapping,所以不用配置这个的话,
		        它会找bean的name属性值访问,但是只能找一个,有缺陷) ,在没有配置其他三个映射之前,配不配都一样-->
			<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"
			</bean>

		
	<!-- 配置Controller,检测三个处理器映射-->	
	<bean id="controller1" name="/home.action" class="cn.itcast.com.controler.HomeController"></bean>
	
	
	<!-- 内部资源视图解析器 ViewResolver,由它来解析ModelAndView返回的逻辑名-->
	<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 规则:前缀+逻辑名+后缀   /WEB-INF/pages/index.jsp ,因为逻辑名在controller哪里已经写了,就不用写 了-->
		<property name="prefix" value="/WEB-INF/page/" />
		<property name="suffix" value=".jsp"></property>
	</bean>				
</beans>

运行一下,访问:

      SpringMvc学习与使用_第5张图片

其实springmvc的处理过程就是那么简单,不难.


2.介绍三个处理器映射

保持controller层不变,这里主要介绍,可以通过几种处理器来找controller层:

(1)BeanNameUrlHandlerMapping(默认):这个上面一句介绍了,它是通过name属性找类的

(2)SimpleUrlHandlerMapping(需要配置):通过ID号找类

<!--2. SimpleUrlHandlerMapping: a.action,b.action,c.action
		支持多个访问映射到同一个controller,找bena的ID值来访问,下面那个controller1就是ID-->
			<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
				<property name="mappings">
					<props>
						<prop key="/a.action">controller1</prop>
						<prop key="/b.action">controller1</prop>
						<prop key="/home.action">controller1</prop>
					</props>
				</property>
				<property name="order" value="1"></property>
			</bean>

把默认的那个去掉,在地址栏访问: http://localhost:8080/SpingMvcEg1/a.action?username=1234  试一下


(3)ControllerClassNameHandlerMapping(需要配置): 通过Controller的类名来访问到相应的controller类

<!-- 3.ControllerClassNameHandlerMapping :
		        通过controller类名进行访问的 (因为实例了,所以访问的时候类名第一个字母是小写其他都一样,
		       还有一种是可以写小写的前面几个字母)-->
		<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
			<property name="order" value="0"></property>
		</bean>

注意:用类名访问的时候记得几个单词一起的时候,前几个都要小写,最后一个大写或者不写直接后缀.action

如: http://localhost:8080/SpingMvcEg1/home.action?username=1234

http://localhost:8080/SpingMvcEg1/homeController.action?username=1234

(这里就有一个问题了,跟默认的那个找name相同了,那么它是通过那个呢?这就是上面设置<propertyname="order" value="0"></property>来控制优先级的问题了,看代码即可)

默认顺序是一下顺序,通过控制优先级可以改变:

                       


3.改变一下配置文件action-servlet.action,看看源码我们就知道,为什么是这个名字了

在DispatcherServlet extends FrameworkServlet的父类FranmeworkServlet中的以下东西,组成了这个配置文件的名字。

重点: public static final StringDEFAULT_NAMESPACE_SUFFIX = " -servlet ";

        SpringMvc学习与使用_第6张图片


改变一下,通常这样spring配置文件我们都是放在src下面的,我们也可以改变一下它的名字(但是要配置才能)

              SpringMvc学习与使用_第7张图片

web.xml配置:

<servlet>
  	<servlet-name>action</servlet-name><!-- servlet-name和配置文件的前面名字相同 -->
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>contextConfigLocation</param-name><!-- 这里的名字可不是随便去的,源码中决定的 -->
  		<param-value>classpath:springmvc-servlet.xml</param-value>
  	</init-param>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>action</servlet-name>
  	<url-pattern>*.action</url-pattern>
  </servlet-mapping>

contextConfigLocation说明:

在dispacterServlet的父类org.springframework.web.servlet.FrameworkServlet中有这样一个路径设置set方法,只需要在web.xml中配置contextConfigLocation即可。

            源码:
  


4.介绍几种常见控制器Controller

(1).CommandController命令控制器,就做到了jsp页面封装数据到实体类。

实体类:

package cn.itcast.com.domain;

import java.io.Serializable;

public class Customer implements Serializable{
	private String username;
	private String password;
	private Integer age;
	
	
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	@Override
	public String toString() {
		return "Customer [username=" + username + ", password=" + password
				+ ", age=" + age + "]";
	}
	
	
	
}


在原来的工程上,新建controller类:MyCommendController.java

package cn.itcast.com.controler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractCommandController;

import cn.itcast.com.domain.Customer;

//AbstractCommandController这是命令控制器
public class MyCommendController extends AbstractCommandController{
	
	//在默认的构造器中设置
	public MyCommendController() {
		// TODO Auto-generated constructor stub
		//告诉spingmvc,我给command封装的是这个Customer实体类对象
			this.setCommandClass(Customer.class);
	}
	
	@Override
	protected ModelAndView handle(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		// TODO Auto-generated method stub
		//Object command: 
		//BindException errors:
		Customer customer = (Customer) command;
		System.out.println(customer.toString());
		return null;
	}

}

springmvc-servlet.xml中添加控制器配置

<!-- 配置CommandController命令控制器 -->
	<bean class="cn.itcast.com.controler.MyCommendController"></bean>

访问:

http://localhost:8080/SpingMvcEg1/mycommendController.action?username=1234&password=123&age=2


(2).表单控制器

MyFormController.java

package cn.itcast.com.controler;

import org.springframework.web.servlet.mvc.SimpleFormController;

import cn.itcast.com.domain.Customer;

public class MyFormController extends SimpleFormController{
	
	public MyFormController(){
		this.setCommandClass(Customer.class);
	}
	//当以get方式提交的时候,会直接跳转jsp页面而不会触发doSubmitAction方法,在web.xml中设置
	//以form表单post提交的时候,会自动调用doSubmitAction方法,自动封装到实体类
	@Override
	protected void doSubmitAction(Object command) throws Exception {
		// TODO Auto-generated method stub
		  Customer customer = (Customer)command;
		System.out.println(customer.toString());
	}
  
  
}

这里就有一个问题了?我得先跳到web-inf下面的这个页面才能进行提交,那不是还得重新写一个类进行跳转,不需要,文件中已经配置好,直接访问这个action即可,是否成功的问题它来解决。

<!-- 配置表单控制器 -->
	<!-- 说明:因为视图解析器已经把前缀和后缀已经配置好了,所以只需要逻辑名即可 -->
		<!-- formView:form视图 -->
		<!-- successView:成功视图 -->
	<bean class="cn.itcast.com.controler.MyFormController">
		<property name="formView" value="customer/form1"></property>
		<property name="successView" value="index"></property>
	</bean>

先访问: http://localhost:8080/SpingMvcEg1/myform.action  看看效果是不是跳转到表单页面了

再填写数据,提交到成功页面了。



(3).向导表单控制器

在业务系统中,有时用户要填写的内容很多。51job填写简历,基本信息,教育经历,工作经历。分开填写,加入前面感觉需要修改,但是数据不能丢失(数据回显),可以在原来的基础上进行修改。


做一个例子,如下效果:

                SpringMvc学习与使用_第8张图片


inf.jsp

<span style="font-family:Microsoft YaHei;">  <form action="${pageContext.request.contextPath }/mywizardController.action" method="post">
    	<table>
    		<tr>
    			<td>USER:</td>
    			<td><input type="text" name="username" value="${customer.username }"></td>
    		</tr>
    		<tr>
    			<td><input type="submit" value="下一页" name="_target1"></td>
    			<td><input type="submit" value="取消" name="_cancel"></td>
    		</tr>
    	</table></span>

Edu.jsp

<span style="font-family:Microsoft YaHei;">  <form action="${pageContext.request.contextPath }/mywizardController.action" method="post">
    	<table>
    		<tr>
    			<td>PASS:</td>
    			<td><input type="text" name="password" value="${customer.password }"></td>
    		</tr>
    		<tr>
    			<td><input type="submit" value="上一页" name="_target0"></td>
    			<td><input type="submit" value="下一页" name="_target2"></td>
    			<td><input type="submit" value="取消" name="_cancel"></td>
    		</tr>
    	</table>
    </form></span>

Work.jsp

<span style="font-family:Microsoft YaHei;"><form action="${pageContext.request.contextPath }/mywizardController.action" method="post">
    	<table>
    		<tr>
    			<td>AGE:</td>
    			<td><input type="text" name="age" value="${customer.age }"></td>
    		</tr>
    		<tr>
    			<td><input type="submit" value="上一页" name="_target1"></td>
    			<td><input type="submit" value="取消" name="_cancel"></td>
    			<td><input type="submit" value="完成" name="_finish"></td>
    		</tr>
    	</table>
    </form></span>

MyWizardController.java控制类继承了AbstractWizardFormController

<span style="font-family:Microsoft YaHei;">package cn.itcast.com.controler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractWizardFormController;

import cn.itcast.com.domain.Customer;


/*3、向导表单控制器*/
public class MyWizardController extends AbstractWizardFormController {

	public MyWizardController() {
		// TODO Auto-generated constructor stub
		this.setCommandClass(Customer.class);
		//回显数据的保存,这是关键的地方:
		this.setCommandName("customer");
	}
	
	//成功完成
	@Override
	protected ModelAndView processFinish(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		// TODO Auto-generated method stub
		Customer customer =(Customer) command;
		System.out.println(customer.toString());
		return new ModelAndView("index");
	}
	
	//取消,转向第一个页面重新填写
	@Override
	protected ModelAndView processCancel(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		// TODO Auto-generated method stub
		return new ModelAndView("/wizard/Inf"); 
	}

}
</span>


springmvc-servlet.xml文件

<span style="font-family:Microsoft YaHei;">	<!-- 配置向导表单控制器 -->
	<!-- 按着list顺序执行,这个效果就有点儿像前面的感觉错了,想要回去一步,重新填写,但是要数据回显,这个向导表单就做这个事情 -->
	<bean class="cn.itcast.com.controler.MyWizardController">
		<property name="pages">
			<list>
				<value>wizard/Inf</value>
				<value>wizard/Edu</value>
				<value>wizard/Work</value>
			</list>
		</property>
	</bean></span>

访问:http://localhost:8080/SpingMvcEg1/mywizardController.action


试一试填写信息,分别上一步,下一步,取消,提交。看看效果


六、注解形式开发

1.注解开发

   在sprimgmvc3.0之后,它就全面支持

前面的,写一个类就得在配置文件写bean,很麻烦都体现不出spring的强大之处。用注解的形式进行开发


加必须的jar包,springmv-servlet.xml文件放在src下面,web.xml文件写分发器及spring文件的路径配置,都写好


写一个controller类:HomeController.java,开始运用注解

package com.itcast.control;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class HomeController {

	//1.逻辑处理
	//2.跳转页面
	
	@RequestMapping("home.action")  //访问的URL
	public String goHome(HttpServletRequest request){
		System.out.println(request.getParameter("user"));
		System.out.println(request.getRequestURI());
		return "index";  //逻辑名称,通过视图解析器ViewResolver拼接,找到跳转地址
		
	}
}

配置它的核心配置文件 springmvc-servlet.xml,包自动 扫描这个 controller层的所有类

<?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:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc
						http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
						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">

		<!-- 对所有的Controller包进行扫描 -->
 		<context:component-scan base-package="com.itcast.control"/>
 		
 		<!-- 内部资源视图解析器 ViewResolver,由它来解析ModelAndView返回的逻辑名-->
		<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
			<!-- 规则:前缀+逻辑名+后缀   /WEB-INF/pages/index.jsp ,因为逻辑名在controller哪里已经写了,就不用写 了-->
			<property name="prefix" value="/WEB-INF/page/" />
			<property name="suffix" value=".jsp"></property>
		</bean>
		
		<!-- 配置文件上传的视图解析器 -->
		<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
			<property name="maxUploadSize" value="10485760"></property><!-- 10M -->
		</bean>
		
		
 						
</beans>


配置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">
  <display-name></display-name>	
  
  <!-- 管理spring容器 -->
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:beans.xml</param-value>
  </context-param>
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!-- 管理springmvc -->
  <servlet>
  	<servlet-name>action</servlet-name><!-- servlet-name和配置文件的前面名字相同 -->
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:springmvc-servlet.xml</param-value>
  	</init-param>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>action</servlet-name>
  	<url-pattern>*.action</url-pattern>
  </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
</web-app>

部署并发布:

http://localhost:8080/SpringMvcNoteEg1/home.action?user=李三



2.springmvc自定义的标签库使用

Struts2标签非常丰富,远远超过springmvc

案例中有详细说明


3.文件上传

它的功能跟struts2,案例中有详细说明


4.拦截配置

" *.action "拦截所有URL后缀action资源 , "/" 拦截所有URL请求,包括action,静态资源js/iimages/css
这样就会导致静态资源不会被放行,但是有办法解决,在springmvc-servlet.xml中配置<!-- 静态资源配置  location:共享资源路径  mapping:资源映射  **=子目录+资源-->
<mvc:resources location="/image/"   mapping="/image/**"/>


5.集群认识

Apache+tomcat(集群)   NGnix+tomcat(集群)


静态资源交给Apache/Ngnix解决,而动态资源则交给tomcat管理了。

Apache比tomcat解析资源速度差不多快10倍左右。Ngnix比Apache快100倍左右。大型网站,几乎38%都 是用Ngnix


动静分离时,至少将*.action交给springmvc管理

六、总结

就是以上知识点,多多打代码即可。


你可能感兴趣的:(spring,mvc,springMVC使用,springmvc整合)