SpringMVC框架使用

一、框架基本使用

1.引入jar包

2.新建配置文件spring-mvc.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"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	">
</beans>

3.配置前端控制器web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	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_3_0.xsd">
  <display-name></display-name>	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
	<servlet>
		<servlet-name>mvc</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>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>mvc</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
</web-app>

4.创建控制器FirstAction.java,实现Controller接口

// action实现Controller接口,并实现handleRequest方法(类似service方法),与JSP内置对象偶合
public class FirstAction implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("传入的数据为");
		String userName=request.getParameter("userName");
		String pwd=request.getParameter("pwd");
		System.out.println("userName:"+userName);
		System.out.println("这里可以调用业务层处理业务。");
		
		//封装数据,可以直接使用request对象,也可以使用封装等方式,真正使用时可以选择一种
		request.setAttribute("rUserName", userName);
		Map<String, String > map=new HashMap<String, String>();
		map.put("mUserName",userName);
		
		//返回视图层,如果使用map封装数据,需要作为(第二个)参数传递,也是request作用域。
		return new ModelAndView("/jsp/first.jsp",map);
		
		//返回视图层,不传递map。
		//return new ModelAndView("/jsp/first.jsp");

                //也可以使用如下方式传递,不使用Map,数据一样是request作用域		
		//return new ModelAndView("/jsp/first.jsp","mUserName",userName);
	}
}

5.修改配置文件spring-mvc.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"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	">
	<!-- 
	1。配置action,实现controler接口
	2。配置映射处理器,用来处理请求与action的映射,可以不用写id,
	3。配置视图解析器:完成ModelAndView的解析
	缺点:
	1。与JSP偶合
	2。只支持属性的注入,不支持封闭后对象注入
	-->
	 
	 <!-- 声明bean的name,因为使用了BeanNameUrlHandlerMapping,所以不是定义id,用户调用的URL将通过bean的name匹配 -->
	<bean name="/first.action" class="cn.itcast.action.FirstAction" />
	<!-- 声明 BeanNameUrlHandlerMapping,使用名称映射-->
	<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
	<!-- 支持servlet与jsp视图解析,可进行进一步处理,此步可省略, -->
	<!-- InternalResourceViewResolver支持servlet与jsp视图解析,没有配置时,默认使用它,此步可省略, -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<!-- 可以加前缀或后缀 -->
		<!-- 
		<property name="prefix" value="/jsp/"/>
		<property name="suffix" value=".jsp"/>	
		 -->
	</bean>

6.新建jsp/first.jsp,展示访问结果

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  
  <body>
    这是/jsp/first.jsp页面.<br/>
    <!-- 获取并展现控制层传递过来的值 -->
    直接通过request传递的值:${requestScope.rUserName}<br/>通过Map传递的值:${requestScope.mUserName}
  </body>
</html>

7.测试index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  
  <body>
     <a href="first.action?userName=zcf&pwd=admin">firstMVC</a>
  </body>
</html>

8.流程分析


客户端发送请求后,由web.xml中的DispatchServlet过滤,再由spring-mvc.xml中的HandlerMapping识别到对应的action控制器,然后访问控制器,控制器处理后返回一个ModelAndView,通过视图解析器ViewResolver解析,跳转到对应的jsp页面。

扫描二维码关注公众号,回复: 2072042 查看本文章

二、URL处理器 

1.BeanNameUrlHandlerMapping:它将收到的HTTP请求映射到bean的名称(这些bean需要在web应用上下文中定义)

<!-- 声明bean的name,因为使用了BeanNameUrlHandlerMapping,所以不是定义id,用户调用的URL将通过bean的name匹配 -->
	<bean name="/first.action" class="cn.itcast.action.FirstAction" />
	<!-- 
		声明 BeanNameUrlHandlerMapping,使用名称映射
	 -->
	<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"	/>

2.SimpleUrlHandlerMapping:它将收到的HTTP请求映射到bean的ID(这些bean需要在web应用上下文中定义)

<!-- 配置URL与ACTION对象ID进行映射 ,<prop key="second.action">second</prop>,其中key匹配url信息,value为action的ID 
	-->
	<bean id="first"  class="cn.itcast.action.FirstAction" />	
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="first.action">first</prop>
			</props>
		</property>
	</bean>

三、视图解析器(默认使用 InternalResourceViewResolver)

1.UrlBasedViewResolver

<!-- 支持servlet与jsp视图解析1,可进行进一步处理,此步可省略, -->
	<!-- viewClass不同的配置,可以解析不同的资源-->
	<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
		<!--
		<property name="prefix" value="/jsp/"/>
		<property name="suffix" value=".jsp"/>	
		-->
</bean>

2.InternalResourceViewResolver:作为UrlBasedViewResolver的子类, 它支持页面jstl处理.

<!-- 支持servlet与jsp视图解析,可进行进一步处理,此步可省略, -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 可以加前缀或后缀 -->		 
		<property name="prefix" value="/jsp/"/>
		<property name="suffix" value=".jsp"/>		 
	</bean>

四、转发forword与重定向redirect(默认 forword)

forward使用转发方式:

return  new ModelAndView("/jsp/first.jsp",map);
		return  new ModelAndView("forward:/jsp/first.jsp",map);
		//控制器采用注解,方法在返回字符串时,可以使用:
		return "forward:/jsp/first.jsp";

redirect使用重定向方式 :

return  new ModelAndView("redirect:/jsp/first.jsp",map);
//控制器采用注解,方法在返回字符串时,可以使用
return "redirect:/jsp/first.jsp";

五、控制器

1.实现controller接口

在spring mvc中控制对象要实现此接口,并且必须实现handRequest方法。此控制器在接收到DispatcherServlet分配置 的请求时,执行handRequest方法,并 返回ModelAndView实例。

public class FirstAction implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
...
}

2. 继承AbstractCommandController类:可以将请求参数值自动设置到command对象中,便于后继的使用。

public class StudentAction extends AbstractCommandController {

	public StudentAction(){		
		//配置student对象可以注入,student对象中定义好了stuName和stuPwd属性
		setCommandClass(Student.class);
	}
	
	@Override
	protected ModelAndView handle(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, BindException arg3)
			throws Exception {
		System.out.println("---接收数据---");
		//方式1接收数据,只能每个属性都分开接收
		String stuName=arg0.getParameter("stuName");
		String stuPwd=arg0.getParameter("stuPwd");
		System.out.println("方式1:"+stuName+","+stuPwd);
		
		//方式2接收数据,实现对象属性注入,传递的数据名必须与被注入对象的属性名相同才能注入
		Student student = (Student)arg2;
		System.out.println("方式2:"+student);		
		
		System.out.println("---调用业务层,进行业务处理,略---");
		
		//封装视图数据,有多种方式 ,这里列表方式 一和方式 二,可以任选一种:
		//方式一,直接采用request对象封装
		arg0.setAttribute("rStudent", student);
		//封装视图数据,方式二,直接采用Map封装,默认作用域是request,需要在return的时候作为参数传递。
		Map<String ,Student > map=new HashMap<String, Student>();
		map.put("mStudent", student);
		
		//默认为forward方式
		return  new ModelAndView("/jsp/main.jsp",map);
		
	}
}

    jsp/main.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
  <head>    
    <title>My JSP 'main.jsp' starting page</title>
  </head>
  <body>
    这是/jsp/main.jsp页面.<br/>
    <!-- 获取并展现控制层传递过来的值 -->
    直接通过request传递的值:${requestScope.rStudent}<br/>通过Map传递的值:${requestScope.mStudent}
  </body>
</html>
    测试
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  <body>
 <a href="student.action?stuName=zcf&stuPwd=admin">test student</a>
  </body>
</html>

3.继承MultiActionController类

public class StudentMultiAction extends MultiActionController {
	//定义方法时,参数规则:(HttpServletRequest request, HttpServletResponse response, [,HttpSession session] [,MyObject]);
	public ModelAndView add(HttpServletRequest request,HttpServletResponse response,Student student){
		System.out.println("add.student:"+student);
		student.setStuName("rename");
		return new ModelAndView("jsp/main","student",student);
	}
	
	//定义方法时,参数规则:(HttpServletRequest request, HttpServletResponse response, [,HttpSession session] [,MyObject]);
	public ModelAndView update(HttpServletRequest request,HttpServletResponse response,Student student){
		System.out.println("update.student:"+student);
		student.setStuName("rename");
		return new ModelAndView("jsp/main","student",student);
	}
	
	//定义方法时,参数规则:(HttpServletRequest request, HttpServletResponse response, [,HttpSession session] [,MyObject]);
	public ModelAndView list(HttpServletRequest request,HttpServletResponse response,Student student){
		System.out.println("list.student:"+student);
		student.setStuName("updateName");
		return new ModelAndView("jsp/main");
	}
}

    修改spring-mvc.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" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	">
	<!-- 配置控制器,并指定通过methodNameResolver方法名调用相关方法处理相关逻辑-->
	<bean id="studentMultiAction" class="cn.itcast.action.StudentMultiAction">
		<property name="methodNameResolver" ref="parameterMethodNameResolver"></property>
	</bean>
	<!-- 定义通过方法名调用控制器相关方法的规则 -->
	<bean id="parameterMethodNameResolver"
		class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
		<!-- 在url中使用do=方法名方式识别相关方法,例如:studentMulti.action?do=add,将调用add方法;这里的do不是固定的,可以改为其它 -->
		<property name="paramName" value="do" />
		<!-- 如果没有指定方法名时,默认 调用控制器的list方法 -->
		<property name="defaultMethodName" value="list" />
	</bean>
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/studentMulti.action">studentMultiAction</prop>
			</props>
		</property>
	</bean>
	<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView"></property>
		<property name="prefix" value="/WEB-INF/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

    测试页面index.jsp

<body>
	<form action="studentMulti.action?do=add" method="post">
		<input type="text" name="stuName"><br> <input
			type="password" name="stuPwd"><br> <input type="submit"
			value="student_add">
	</form>

	<a href="studentMulti.action?do=update&stuPwd=testpwd&stuName=testName">调用修改方法</a>
	<a href="studentMulti.action?&stuPwd=testpwd&stuName=testName">调用默认方法</a>
</body>

    展示页面jsp/main.jsp

<body>
  this is WEB-INF/JSP main jsp<br>
  studentName:${requestScope.student.stuName}<br>  
  </body>

六、基于注解的mvc实现(重点)

1.基于DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter的注解

1)修改spring-mvc.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"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
	">


	<!-- 
	DefaultAnnotationHandlerMapping:支持通过url找到相关的action
	AnnotationMethodHandlerAdapter:支持通过url匹配action定义方法 
	base-package:定 义扫描的范围,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean
	-->	
	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>
	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"></bean>
	<context:component-scan base-package="*"></context:component-scan>

</beans>

2)修改控制类,加入@Controller@RequestMapping注解信息

@Controller:表示当前类是控制器

@RequestMapping("/controllerName"):表示url中通过controllerName可以访问该控制器

@Controller  //用来声明控制器
@RequestMapping("/student") //声明可以访问到的url地址
public class StudentAction {
	public StudentAction(){
		System.out.println("---StudentAction构造方法被调用---");
	}
//访问可用student/save.action,save后边的action是根据web.xml配置来的
	
//如果要添加其它的数据到最后跳转过去的页面,可以在方法中添加ModelMap的参数,例如 : public String save(Student student,ModelMap map){
//...,通过map再存放其它的数据
   @RequestMapping(value="/save")
	public ModelAndView save(Student student){
		System.out.println("save方法注入的student对象:"+student);
		System.out.println("---调用业务逻辑进行业务处理---");
		
		//修改学生名字,跳转到下一页面时看能否显示修改后的名字
		student.setStuName("rename");		
		
		//直接使用字符串,返回视图,进行结果展现等
		return new ModelAndView("forward:/jsp/main.jsp");
	}
	
	//同一个action中可以定义多个方法,方法的返回类型也可以用String
	@RequestMapping(value="/update")
	public String update(Student student,ModelMap paramMap){
		System.out.println("update方法已注入student对象:"+student);
		System.out.println("---调用业务逻辑进行业务处理---");		
		
		paramMap.put("other","testOtherValue");
		//直接使用字符串,返回视图,进行结果展现等
		return "forward:/jsp/main.jsp";
	}
}

3)测试页面,student为控制类中注解@RequestMapping("/student")声明过的controllerName

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  
  <body>
 <a href="student/save.action?stuName=zcf&stuPwd=admin">调用save方法</a> 

4)展示页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
  <head>    
    <title>My JSP 'main.jsp' starting page</title>
  </head>
  <body>
    这是/jsp/main.jsp页面.<br/>
    <!-- 获取并展现控制层传递过来的值 -->
    默认通过request传递的值:${requestScope.student}<br/>
  </body>
</html>

2.基于annotation-driven的注解

<?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"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
	http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
	">
<!-- 
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>
	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"></bean>
	<context:component-scan base-package="*"></context:component-scan>
	-->	
		
	<!-- mvc:annotation-driven,取代了上面的DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter
两个Bean的配置	-->
	<mvc:annotation-driven></mvc:annotation-driven>
	<context:component-scan base-package="*"/>

</beans>

七、springmvc文件上传

1.multipartResolver使用,配置spring-mvc.xml

<!--文件上传使用, 配置multipartResolver,id名为约定好的 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 配置文件(每次上传的所有文件总大小)大小,单位为b, 1024000表示1000kb  -->
		<property name="maxUploadSize" value="1024000" />		
	</bean>

2.中文乱码处理,配置web.xml

<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>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

    若配置完还是乱码,请尝试修改tomcat安装目录下的apache-tomcat安装目录\conf\server.xml文件,修改Connector元素内容,添加URIEncoding="UTF-8" ,修改后内容 如下:

<Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="UTF-8"/>

3.properties文件信息注入,配置spring-mvc.xml

<!--PropertiesFactoryBean对properties文件可用 ,可以用来注入properties配置文件的信息 -->
	<bean id="uploadProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
		<property name="location" value="classpath:xxxxx.properties"></property>
	</bean>

八.拦截器

1.拦截器类

public class LoginInterceptor implements HandlerInterceptor {

	@Override
	public void afterCompletion(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("---访问请求资源后不管理有没有异常都一定执行此方法---");

	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2, ModelAndView arg3) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("---访问请求资源后,如果没有异常,将执行此方法---");

	}

	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("---访问请求资源前执行,如果此方法返回false,将不能访问请求资源---");
		return true;
	}
}

2.spring-mvc.xml配置

<!-- 配置spring mvc拦截器 -->
	<mvc:interceptors>
	<!-- 默认拦截DispatcherServlet指定的后缀(这里是.action) -->
		<bean class="cn.itcast.interceptor.LoginInterceptor"/>
	</mvc:interceptors>

九、json交互(使用注解 @ResponseBody)

@Controller
@RequestMapping(value="/student")
public class StudentAction {

	public StudentAction(){
		System.out.println("---StudentAction构造方法被调用---");
	}

	@RequestMapping("/doAjax")
	@ResponseBody //如果返回json格式,需要这个注解
	public Object doAjax(Student student){
		System.out.println("---doAjax.student:"+student);
		student.setStuName("1001name");
		return student;
	}
}

    访问页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
    <script type="text/javascript" src="${pageContext.request.contextPath}/jquery-1.3.js"></script>
  	<script type="text/javascript">
  		$(
	  		function(){
	  			$("#bt1").click(
	  				function(){
		  				$.post(
		  					"student/doAjax.action",
		  					{stuId:1001,stuName:"name1001",stuPwd:"pwd1001",stuAge:20},
		  					function(json){alert(json.stuName+"||"+json.stuPwd);},
		  					"json"
		  				);
		  			}
	  			);	  			
	  		}
  		);
  	
  	</script>
  
  </head>
  
  <body>
 	<button id="bt1" >testajax</button> 
  </body>
</html>


猜你喜欢

转载自blog.csdn.net/weixin_41762621/article/details/80981264