SpringMVC框架--我的笔记

SpringMVC学习


  • SpringMVC概述

Spring 为展现层提供的基于 MVC 设计理念的优秀的Web 框架,是目前最主流的 MVC 框架之一
Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架
Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请 求的控制器,而无须实现任何接口。
支持 REST 风格的 URL 请求
采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性

  • SpringMVC知识准备

1、引入jar包

spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
		
	
    	org.springframework
    	spring-webmvc
   		 4.3.20.RELEASE
	

2、配置web.xml

配置 DispatcherServlet :DispatcherServlet 默认加载 /WEB- INF/.xml 的 Spring 配置文件, 启动 WEB 层 的 Spring 容器。可以通过 contextConfigLocation 初始化参数自定 义配置文件的位置和名称





	
		springDispatcherServlet
		org.springframework.web.servlet.DispatcherServlet
		
			contextConfigLocation
			classpath:applicationcontext-springmvc.xml
		
		1
	

	
	
		springDispatcherServlet
		/
	


3、配置自动扫描的包和视图解析器以及静态资源处理器









	
	
	
	








4、使用 @RequestMapping 映射请求

Spring MVC 为控制器指定可 以处理哪些 URL 请求使用 @RequestMapping 注解
• 在控制器的类定义及方法定义处都可标注
@RequestMapping
类定义处:提供初步的请求映射信息。相对于 WEB 应用的根目录
方法处:提供进一步的细分映射信息。相对于类定义处的 URL。若 类定义处未标注 @RequestMapping,则方法处标记的 URL 相对于 WEB 应用的根目录
DispatcherServlet 截获请求后,就通过控制器上
@RequestMapping 提供的映射信息确定请求所对应的处理 方法。

SpringMVC框架--我的笔记_第1张图片

5、映射请求参数、请求方法或请求头

@RequestMapping 除了可以使用请求 URL 映射请求外,
还可以使用请求方法、请求参数及请求头映射请求
@RequestMapping 的 value、method、params 及 heads 分别表示请求 URL、请求方法、请求参数及请求头的映射条 件,他们之间是与的关系,联合使用多个条件可让请求映射 更加精确化
params 和 headers支持简单的表达式
– param1: 表示请求必须包含名为 param1 的请求参数
– !param1: 表示请求不能包含名为 param1 的请求参数
– param1 != value1: 表示请求包含名为 param1 的请求参数,但其值 不能为 value1
– {“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1
	/**
	    @RequestMapping
	 * value:请求路径,默认不写
	 * method:用于指定请求的方法
	 * params:指定参数规则
	 * –	param1: 表示请求必须包含名为 param1 的请求参数
	   –	!param1: 表示请求不能包含名为 param1 的请求参数
	   –	param1 != value1: 表示请求包含名为 param1 的请求参数,但其值  不能为 value1
	   –	{“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2  的两个请求参数,且 param1 参数的值必须为 value1

	 */

SpringMVC框架--我的笔记_第2张图片

	/**
	 * –	?:匹配文件名中的一个字符
	   –	*:匹配文件名中的任意字符
	   –	**:** 匹配多层路径  包括0层
	 */
	@RequestMapping("/index/**/??")
	public String index() {
		return "login";
	}

6、@PathVariable映射 URL 绑定的占位符

带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的 意义
通过 @PathVariable 可以将 URL 中占位符参数绑定到控 制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过
@PathVariable(“xxx”) 绑定到操作方法的入参中。
	/**
	 * 	传递参数的方式:
	 * 	第一种,采用路径直接传递参数
	 * @PathVariable 获取URL中的参数
	 */
	@RequestMapping("/del/{id}")
	public String testPathVar(@PathVariable("id") String id) {
		System.out.println(id);
		return "login";
	}

7、使用 @RequestParam 绑定请求参数值

• 在处理方法入参处使用 @RequestParam 可以把请求参 数传递给请求方法
– value:参数名
– required:是否必须。默认为 true, 表示请求参数中必须包含对应 的参数,若不存在,将抛出异常
	/**
	 * 	传递参数的方式:
	 * 	第二种,采用以往的传递参数的形式
	 * @RequestParam value:指定参数的名称
	 * 	required:默认为true,代表必须传参数
	 */
	@RequestMapping("/testRequestParam")
	public String testRequestParam(@RequestParam(value="id",required=true) String id) {
		System.out.println(id);
		return "login";
	}

8、使用 POJO 对象绑定请求参数值

• Spring MVC 会按请求参数名和 POJO 属性名进行自动匹 配,自动为该对象填充属性值。支持级联属性。
	/**
	 *	使用POJO方式获取参数,注入到Java对象中,但对象的属性名必须与参数名相同
	 * 
	 */
	@RequestMapping("/dologin2")
	public String dologin(LoginUser user) {
		System.out.println(user.getUsername()+user.getPassword());
		System.out.println(user);
		return "success";
	}

9、使用 Servlet API 作为入参

/**
	 * 	使用原始的servlet拿参数信息
	 * 
	 */
	@RequestMapping("/testServlet")
	public void testServlet(HttpServletRequest request,HttpServletResponse response,HttpSession session) throws IOException {
		System.out.println(request.getParameter("id"));
		response.sendRedirect("http://www.baidu.com");
	}
	

10、使用 @RequestHeader 绑定请求报头的属性值、使用 @CookieValue 绑定请求中的 Cookie

	/**
	 * 	获取头文件
	 * @RequestHeader:指定参数的名称获取值
	 * 
	 */
	@RequestMapping("/testRequestHeader")
	public String testRequestHeader(@RequestHeader("Accept-Encoding")String Encoding) {
		System.out.println(Encoding);
		return "login";
	}
	
	/**
	 * 	获取cookie值
	 * @CookieValue:指定参数的名称获取值
	 * 
	 */
	@RequestMapping("/testCookie")
	public String testCookie(@CookieValue("JSESSIONID")String cookie) {
		System.out.println(cookie);
		return "login";
	}

11、MVC 的 Handler 方法可以接受哪些 ServletAPI 类型的参数

HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer

12、处理模型数据

• Spring MVC 提供了以下几种途径输出模型数据:
ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加模型数据
Map 及 Model: 入参为 org.springframework.ui.Model、org.springframework.ui. ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。

ModelAndView

• 控制器处理方法的返回值如果为 ModelAndView, 则其既 包含视图信息,也包含模型数据信息。
• 添加模型数据:
MoelAndView addObject(String attributeName, Object  attributeValue)
ModelAndView addAllObject(Map modelMap)
• 设置视图:
void setView(View view)
void setViewName(String viewName)

SpringMVC框架--我的笔记_第3张图片

	/**
	 *  向页面传递模型数据1
	 */
	@RequestMapping("/testModelAndView")
	public ModelAndView testModelAndView() {
		ModelAndView modelAndView = new ModelAndView(); 
		LoginUser loginUser = new LoginUser();
		loginUser.setUsername("1234");
		loginUser.setPassword("123456");
		//键值对传参
		modelAndView.addObject("loginuser", loginUser);
		//向哪个页面传入参数
		modelAndView.setViewName("success");
		return modelAndView;
	}
	

Map 及 Model

Spring MVC 在内部使用了一个 org.springframework.ui.Model 接口存 储模型数据
• 具体步骤
– Spring MVC 在调用方法前会创建一个隐 含的模型对象作为模型数据的存储容器。
如果方法的入参为 Map 或 Model 类 型,Spring MVC 会将隐含模型的引用传 递给这些入参。在方法体内,开发者可以 通过这个入参对象访问到模型中的所有数 据,也可以向模型中添加新的属性数据

SpringMVC框架--我的笔记_第4张图片

	/**
	 *  向页面传递模型数据2
	 */
	@RequestMapping("/testMap")
	public String testMap(Map map) {
		LoginUser loginUser = new LoginUser();
		loginUser.setUsername("张三 ");
		loginUser.setPassword("123456");
		map.put("loginuser", loginUser);
		return "success";
	}

13、关于重定向转发

一般情况下,控制器方法返回字符串类型的值会被当成逻 辑视图名处理
如果返回的字符串中带 forward: 或 redirect: 前缀 时,SpringMVC 会对他们进行特殊处理:将 forward: 和 redirect: 当成指示符,其后的字符串作为 URL 来处理
redirect:success.jsp:会完成一个到 success.jsp 的重定向的操作
forward:success.jsp:会完成一个到 success.jsp 的转发操作
/**
	 *  转发和重定向
	 * 仅仅只需要返回字符串中包含forward或redirect
	 */
	@RequestMapping("/testforward")
	public String testforward() {
		return "forward:hello";
	}
	@RequestMapping("/testredirect")
	public String testredirect() {
		return "redirect:hello";
	}

14、处理 JSON

SpringMVC框架--我的笔记_第5张图片

15、文件上传

Spring MVC 为文件上传提供了直接的支持,这种支持是通 过即插即用的== MultipartResolver ==实现的。Spring 用 Jakarta Commons FileUpload 技术实现了一个 MultipartResolver 实现类:CommonsMultipartResovler
Spring MVC 上下文中默认没有装配 MultipartResovler,因 此默认情况下不能处理文件的上传工作,如果想使用 Spring 的文件上传功能,需现在上下文中配置 MultipartResolver

配置 MultipartResolver

defaultEncoding: 必须和用户 JSP 的 pageEncoding 属性 一致,以便正确解析表单的内容
为了让 CommonsMultipartResovler 正确工作,必须先 将 Jakarta Commons FileUpload 及 Jakarta Commons io 的类包添加到类路径下。



	

文件上传实例

FileUploadAction.java

package com.hqyj.action;

import java.io.File;
import java.io.IOException;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

/**
 *  1、引入文件上传相关的包io/upload
 *  2、Spring配置文件中,配置      
 *  	
			
		
 *  3、form表单:post请求形式,enctype="multipart/form-data"
 *  4、后台接收文件MultipartFile.保存文件调用的是transferTo方法将文件传递到硬盘上
 */


@Controller
public class FileUploadAction {
	
	/**
	 * 文件上传案例
	 */
	
	@RequestMapping("/testupload")
	public String jump() {
		return "upload";
	}
	
	
	@RequestMapping("/upload")
	public String upload(@RequestParam("file") MultipartFile file) {
		
		/**
		 * transferTo()上传文件位置,文件名
		 */
		
		try {
			file.transferTo(new File("d:\\SpringMvc-upload\\"+file.getOriginalFilename()));
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return "success";
	}
}

upload.jsp

	
	
	

16、异常处理

Spring MVC 通过 HandlerExceptionResolver 处理程序 的异常,包括 Handler 映射、数据绑定以及目标方法执行 时发生的异常。
SpringMVC 提供的 HandlerExceptionResolver 的实现类

SpringMVC框架--我的笔记_第6张图片

ExceptionHandlerExceptionResolver

主要处理 Handler 中用 @ExceptionHandler 注解定义的 方法。
@ExceptionHandler 注解定义的方法优先级问题:例如发 生的是NullPointerException,但是声明的异常有 RuntimeException 和 Exception,此候会根据异常的最近 继承关系找到继承深度最浅的那个 @ExceptionHandler 注解方法,即标记了 RuntimeException 的方法
ExceptionHandlerMethodResolver 内部若找不 到@ExceptionHandler 注解的话,会找
@ControllerAdvice的@ExceptionHandler 注解方法

异常处理实例

Testexception.java

package com.hqyj.action.exception;

import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Testexception {
	
	@RequestMapping("/testException")
	public String testException(@RequestParam("id") int id) {
		int i=10/id;
		return "success";
	}

}

GlobeException.java全局配置注解

package com.hqyj.action.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * 全局异常处理类
 */

@ControllerAdvice
public class GlobeException {

	@ExceptionHandler(value= {ArithmeticException.class})
	public ModelAndView handlException(Exception e) {
		ModelAndView mv = new ModelAndView("error");
		System.out.println("算术异常");
		mv.addObject("error",e);
		return mv;
	}
	
	@ExceptionHandler(value= {RuntimeException.class})
	public String handlRuntimeException() {
		System.out.println("运行时异常");
		return "error";
	}
}

error.jsp


出错了${error}

结果

SpringMVC框架--我的笔记_第7张图片


  • SpringMVC的使用实例

pom.xml


  4.0.0
  com.hqyj
  1809_spring-springmvc
  0.0.1-SNAPSHOT
  war
  
  	
	
		
			org.springframework
			spring-context
			4.3.20.RELEASE
			runtime
		

		
		
		
			org.aspectj
			aspectjweaver
			1.9.2
		
		
		
		
			aopalliance
			aopalliance
			1.0
		

		
		
			mysql
			mysql-connector-java
			5.1.40
		

		
		
		
			org.springframework
			spring-jdbc
			4.3.20.RELEASE
		

		
		
		
			com.mchange
			c3p0
			0.9.5.2
		
		
		
		

    org.springframework
    spring-webmvc
    4.3.20.RELEASE





    com.fasterxml.jackson.core
    jackson-core
    2.9.7





    com.fasterxml.jackson.core
    jackson-databind
    2.9.7





    commons-fileupload
    commons-fileupload
    1.3.3


	
  
  
  

web.xml






	
		springDispatcherServlet
		org.springframework.web.servlet.DispatcherServlet
		
		
			contextConfigLocation
			classpath:applicationcontext-springmvc.xml
		
		
		1
	

	
	
		springDispatcherServlet
		/
	



applicationcontext-springmvc.xml全局配置









	
	

	
	
	
	
	










	





LoginUser.java(实体类)

package com.hqyj.action;

public class LoginUser {
	private String username;
	private String password;
	private Dept dept;
	//、、、、、、、、、
	//此处省略get和set方法,toString方法,无参构造方法
	
}

Dept.java

package com.hqyj.action;

public class Dept {
	private int id;
	private String deptname;
	//、、、、、、、、、
	//此处省略get和set方法,toString方法,无参构造方法
}

LoginAction.java(控制层)

package com.hqyj.action;

import java.io.IOException;
import java.util.Map;

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/login")
//@RequestMapping放在类上,一般表示一个模块,这样的话再访问下面的方法,可以写"/login/hello"
public class LoginAction {
	
	/**
	 * value:请求路径,默认不写
	 * method:用于指定请求的方法
	 * params:指定参数规则
	 * –	param1: 表示请求必须包含名为 param1 的请求参数
	   –	!param1: 表示请求不能包含名为 param1 的请求参数
	   –	param1 != value1: 表示请求包含名为 param1 的请求参数,但其值  不能为 value1
	   –	{“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2  的两个请求参数,且 param1 参数的值必须为 value1

	 */

/*@RequestMapping(value:请求地址,
 * method=RequestMethod.POST(以post方式请求),
 * params"userid"(必须有userid参数且可以用表达式限制))
 * header={"Connection=keep-alive"}
 * */
	
	public LoginAction() {
		super();
		// TODO Auto-generated constructor stub
		System.out.println("构建控制器");
	}
	
	//响应请求的注解
	@RequestMapping("/hello")
	//响应一个hello的请求
	public String login() {
		return "login";
	}
	
	/**
	 * –	?:匹配文件名中的一个字符
	   –	*:匹配文件名中的任意字符
	   –	**:** 匹配多层路径  包括0层
	 */
	@RequestMapping("/index/**/??")
	public String index() {
		return "login";
	}
	
	
	/**
	 * 	传递参数的方式:
	 * 	第一种,采用路径直接传递参数
	 * @PathVariable 获取URL中的参数
	 */
	@RequestMapping("/del/{id}")
	public String testPathVar(@PathVariable("id") String id) {
		System.out.println(id);
		return "login";
	}
	
	/**
	 * 	传递参数的方式:
	 * 	第二种,采用以往的传递参数的形式
	 * @RequestParam value:指定参数的名称
	 * 	required:默认为true,代表必须传参数
	 */
	@RequestMapping("/testRequestParam")
	public String testRequestParam(@RequestParam(value="id",required=true) String id) {
		System.out.println(id);
		return "login";
	}
	
	/**
	 * 	获取头文件
	 * @RequestHeader:指定参数的名称获取值
	 * 
	 */
	@RequestMapping("/testRequestHeader")
	public String testRequestHeader(@RequestHeader("Accept-Encoding")String Encoding) {
		System.out.println(Encoding);
		return "login";
	}
	
	/**
	 * 	获取cookie值
	 * @CookieValue:指定参数的名称获取值
	 * 
	 */
	@RequestMapping("/testCookie")
	public String testCookie(@CookieValue("JSESSIONID")String cookie) {
		System.out.println(cookie);
		return "login";
	}
	
	/**
	 * 	传统使用注解获取参数
	 * 	每传一个参数都要使用@RequestParam去获取,效率非常低下
	 * 
	 */
	
	@RequestMapping("/dologin1")
	public String testdologin(@RequestParam("username")String username,@RequestParam("password")String password) {
		System.out.println(username);
		System.out.println(password);
		return "success";
	}
	
	/**
	 *	使用POJO方式获取参数,注入到Java对象中,但对象的属性名必须与参数名相同
	 * 
	 */
	@RequestMapping("/dologin2")
	public String dologin(LoginUser user) {
		System.out.println(user.getUsername()+user.getPassword());
		System.out.println(user);
		return "success";
	}
	
	
	/**
	 * 	使用原始的servlet拿参数信息
	 * 
	 */
	@RequestMapping("/testServlet")
	public void testServlet(HttpServletRequest request,HttpServletResponse response,HttpSession session) throws IOException {
		System.out.println(request.getParameter("id"));
		response.sendRedirect("http://www.baidu.com");
	}
	
	
	
	
	
	
	/**
	 *  向页面传递模型数据1
	 */
	@RequestMapping("/testModelAndView")
	public ModelAndView testModelAndView() {
		ModelAndView modelAndView = new ModelAndView(); 
		LoginUser loginUser = new LoginUser();
		loginUser.setUsername("1234");
		loginUser.setPassword("123456");
		//键值对传参
		modelAndView.addObject("loginuser", loginUser);
		//向哪个页面传入参数
		modelAndView.setViewName("success");
		return modelAndView;
	}
	
	
	/**
	 *  向页面传递模型数据2
	 */
	@RequestMapping("/testMap")
	public String testMap(Map map) {
		LoginUser loginUser = new LoginUser();
		loginUser.setUsername("张三 ");
		loginUser.setPassword("123456");
		map.put("loginuser", loginUser);
		return "success";
	}
	
	/**
	 *  转发和重定向
	 * 仅仅只需要返回字符串中包含forward或redirect
	 */
	@RequestMapping("/testforward")
	public String testforward() {
		return "forward:hello";
	}
	@RequestMapping("/testredirect")
	public String testredirect() {
		return "redirect:hello";
	}
	
}

login.jsp


	

登录

用户名: 密码:

success.jsp


	登录成功
	欢迎你,${loginuser.username}

*上面代码因为太多结果所以没有一一演示,但代码一定是正确的,大家可以通过访问不同的@RequestMapping("")的值来看结果


  • 使用SpringMVC向页面返回json数据

AjaxAction.java

package com.hqyj.action;

import java.util.ArrayList;
import java.util.List;

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

@Controller
public class AjaxAction {
	
	@RequestMapping("/testajax")
	public String ajax() {
		return "ajax";
	}
	
	@RequestMapping("/doajax")
	@ResponseBody//响应体,必须走响应体,否则返回的值会返回给处理器
				//类似于response.getWriter().print()
	public String testjaxdata() {
		return "ok";
	}
	
	@RequestMapping("/doajaxjson")
	@ResponseBody//响应体
	public List testajaxjson() {
		List users = new ArrayList<>();
//		users.add(new LoginUser("zhangsan","123456"));
//		users.add(new LoginUser("zhangsan2","123456"));
//		users.add(new LoginUser("zhangsan3","123456"));
		for(int i = 0;i<3;i++) {
			LoginUser user = new LoginUser("zhangsan"+i,"123456");
			Dept dept = new Dept();
			dept.setId(i);
			dept.setDeptname("ceshi"+i);
			user.setDept(dept);
			users.add(user);
		}
		
		return users;
	}
	
	
}

ajax.jsp




用户名 密码 部门编号 部门名称

结果

SpringMVC框架--我的笔记_第8张图片


总结,SpringMVC的简单学习就到这里,SpringMVC就是Spring的一个子框架,这里介绍的都是常用,更多学习请参照官方文档

你可能感兴趣的:(JavaEE框架篇)