SpringMVC框架第二天

SpringMVC框架第二天

##SpringMVC大纲
1.SpringMVC返回分类
2.SpringMVC重定向和转发
3.SpringMVC实现JSON数据处理
4.SpringMVC文件上传
5.SpringMVC异常处理器定义
6.SpringMVC拦截器

重点:
	掌握SpringMVC文件上传
	掌握ModelAndView使用
	掌握@ResponseBody的使用
	掌握异常处理器定义
	掌握拦截器的定义和使用

第1章:响应数据和结果视图

1.1 返回值分类

#####1.1.1 返回字符串

Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。

@RequestMapping(value="/hello")
public String sayHello() {
	System.out.println("Hello SpringMVC!!");
	// 跳转到XX页面
	return "success";
}

具体的应用场景

@Controller
@RequestMapping("/user")
public class UserController {
	
	/**
	 * 请求参数的绑定
	 */
	@RequestMapping(value="/initUpdate")
	public String initUpdate(Model model) {
		// 模拟从数据库中查询的数据
		User user = new User();
		user.setUsername("张三");
		user.setPassword("123");
		user.setMoney(100d);
		user.setBirthday(new Date());
		model.addAttribute("user", user);
		return "update";
	}
	
}

<h3>修改用户</h3>
${ requestScope }
<form action="user/update" method="post">
	姓名:<input type="text" name="username" value="${ user.username }"><br>
	密码:<input type="text" name="password" value="${ user.password }"><br>
	金额:<input type="text" name="money" value="${ user.money }"><br>
	<input type="submit" value="提交">
</form>

#####1.1.2 返回值是void

如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。

可以使用请求转发或者重定向跳转到指定的页面

@RequestMapping(value="/initAdd")
public void initAdd(HttpServletRequest request,HttpServletResponse response) throws Exception {
	System.out.println("请求转发或者重定向");
	// 请求转发
	// request.getRequestDispatcher("/WEB-INF/pages/add.jsp").forward(request, response);
	// 重定向
	// response.sendRedirect(request.getContextPath()+"/add2.jsp");
	
	response.setCharacterEncoding("UTF-8");
	response.setContentType("text/html;charset=UTF-8");
	
	// 直接响应数据
	response.getWriter().print("你好");
	return;
}

#####1.1.3 返回值是ModelAndView对象

ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图。

一会案例中我们将使用JSTL输出,所以需要引入jstl依赖包

在工程中引入jstl依赖
<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

具体的代码如下

/**
 * 返回ModelAndView对象
 * 可以传入视图的名称(即跳转的页面),还可以传入对象。
 * @return
 * @throws Exception
 */
@RequestMapping(value="/findAll")
public ModelAndView findAll() throws Exception {
	ModelAndView mv = new ModelAndView();
	// 跳转到list.jsp的页面
	mv.setViewName("list");
	
	// 模拟从数据库中查询所有的用户信息
	List<User> users = new ArrayList<>();
	User user1 = new User();
	user1.setUsername("张三");
	user1.setPassword("123");
	
	User user2 = new User();
	user2.setUsername("赵四");
	user2.setPassword("456");
	
	users.add(user1);
	users.add(user2);
	// 添加对象
	mv.addObject("users", users);
	
	return mv;
}

<%@ page language="java" contentType="text/html; charset=UTF-8"

	pageEncoding="UTF-8"%>

	<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

	<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

	<html>

	<head>

	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

	<title>Insert title here</title>

	</head>

	<body>

	<h3>查询所有的数据</h3>

	<c:forEach items="${ users }" var="user">

		${ user.username }

	</c:forEach>

	</body>

	</html>

####1.2 SpringMVC框架提供的转发和重定向

#####1.2.1 forward请求转发
controller方法返回String类型,想进行请求转发也可以编写成

/**
 * 使用forward关键字进行请求转发
 * "forward:转发的JSP路径",不走视图解析器了,所以需要编写完整的路径
 * @return
 * @throws Exception
 */
@RequestMapping("/delete")
public String delete() throws Exception {
	System.out.println("delete方法执行了...");
	// return "forward:/WEB-INF/pages/success.jsp";
	return "forward:/user/findAll";
}

#####1.2.2 redirect重定向

controller方法返回String类型,想进行重定向也可以编写成

/**
 * 重定向
 * @return
 * @throws Exception
 */
@RequestMapping("/count")
public String count() throws Exception {
	System.out.println("count方法执行了...");
	return "redirect:/add.jsp";
	// return "redirect:/user/findAll";
}

#####1.2.3 ResponseBody响应json数据

######1.2.3.1 DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置

mvc:resources标签配置不过滤

1. location元素表示webapp目录下的包下的所有文件
2. mapping元素表示以/css开头的所有请求路径,如/css/a 或者/css/a/b


例如:将根目录/js目录下的所有文件映射成/js/**,也就说根目录下的js目录下文件都可以通过/js/xx来访问,例如:/js/1.jpg
<mvc:resources location="/js/" mapping="/js/**"/>

<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/>  <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/>  <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/>  <!-- javascript -->

######1.2.3.2 使用@RequestBody获取请求体数据
客户端往服务器传输数据的格式:

  1. “name=value&name=value&name=value…”
  2. ‘{“name”:“value”,“name”:“value”…}’

从前台传输一个和Address实体Bean对应的数据到后台,后台通过@RequestBody接收。实现流程如下:

创建Address

public class Address {
	private String addressName;
	private Integer addressNum;
	//get..set..
}

创建AddressController,使用@RequestBody接收数据。

@Controller
@RequestMapping(value = "/address")
public class AddressController {

    /***
     * 使用@RequestBody接收整个提交内容体
     * @param body
     */
    @RequestMapping(value = "/add")
    public void add(@RequestBody String body){
        System.out.println(body);
    }
}

创建index.jsp,引用jQuery,同时给按钮一个点击事件,点击按钮的时候,发送数据到后台。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>@RequestBody注解</title>
    <script src="/js/jquery-2.2.3.min.js"></script>
    <script>
        $(function () {
            
            //点击按钮发送请求参数
            $('#btn').click(function () {
                $.ajax({
                    url:'/address/add',
                    type:'post',
                    contentType:'application/json;charset=utf-8',
                    data:'{"addressName":"深圳市","addressNum":998}',
                    dataType:'json',
                    success:function (data) {
                        alert(data)
                    }
                });
            });
        });
    </script>
</head>
<body>
<button type="button" id="btn">发送请求</button>
</body>
</html>

######1.2.3.3 使用@RequestBody注解把json的字符串转换成JavaBean的对象
使用@RequestBody注解把json的字符串转换成JavaBean对象,此时需要引入jackson相关依赖包,当然,不一定非得用jackson的包,也可以用fastjson。

引入依赖

<!--用于JSON数据转换-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.6</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.6</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.6</version>
</dependency>

修改上面案例的add方法

/***
 * 使用@RequestBody接收整个提交内容体,并转换成Address对象
 * @param address
 */
@RequestMapping(value = "/add")
public void add(@RequestBody Address address){
    System.out.println(address);
}

######1.2.3.4 使用@ResponseBody注解把JavaBean对象转换成json字符串,直接响应

我们把上面的案例稍微修改一下,在add方法上加上注解@ResponseBody,这样就能响应JSON数据了。页面就能拿到JSON数据。

修改add方法

/***
 * 使用@RequestBody接收整个提交内容体,并转换成Address对象
 * 方法上加上@ResponseBody注解,每次响应数据为JSON数据
 * @param address
 */
@ResponseBody
@RequestMapping(value = "/add")
public Address add(@RequestBody Address address){
    System.out.println(address);
    return address;
}


修改jsp的js代码,直接输出addressName结点的值

//点击按钮发送请求参数
$('#btn').click(function () {
    $.ajax({
        url: '/address/add',
        type: 'post',
        contentType: 'application/json;charset=utf-8',
        data: '{"addressName":"深圳市","addressNum":998}',
        dataType: 'json',
        success: function (data) {
            alert(data.addressName)
        }
    });
});

如果使用RestController注解代替Controller注解,那么我们就可以不写ResponseBody注解了。

关于json的小结:首先保证项目中有json解析框架

  1. 将json类型的请求参数转换成JavaBean
    1. JavaBean的属性名和json中的key相同
    2. 给方法的JavaBean参数添加RequestBody注解
  2. 将方法返回的JavaBean转换成json字符串输出到客户端
    1. JavaBean的属性名和json中的key相同
    2. 给方法/类添加ResponseBody注解
    3. 或者将Controller注解改成RestController注解

第2章:SpringMVC实现文件上传

####2.1 Web上传文件
导入文件上传的jar包

commons-fileupload
commons-fileupload
1.3.1


commons-io
commons-io
2.4

编写文件上传的JSP页面

<h3>文件上传</h3>

<form action="/user/fileupload" method="post" enctype="multipart/form-data">
	选择文件:<input type="file" name="upload"/><br/>
	<input type="submit" value="上传文件"/>
</form>


编写文件上传的Controller控制器

/**
 * 文件上传
 * @throws Exception 
 */
@RequestMapping(value="/fileupload")
public String fileupload(HttpServletRequest request) throws Exception {
	// 先获取到要上传的文件目录
	String path = request.getSession().getServletContext().getRealPath("/uploads");
	// 创建File对象,一会向该路径下上传文件
	File file = new File(path);
	// 判断路径是否存在,如果不存在,创建该路径
	if(!file.exists()) {
		file.mkdirs();
	}
	// 创建磁盘文件项工厂
	DiskFileItemFactory factory = new DiskFileItemFactory();
	ServletFileUpload fileUpload = new ServletFileUpload(factory);
	// 解析request对象
	List<FileItem> list = fileUpload.parseRequest(request);
	// 遍历
	for (FileItem fileItem : list) {
		// 判断文件项是普通字段,还是上传的文件
		if(fileItem.isFormField()) {
			
		}else {
			// 上传文件项
			// 获取到上传文件的名称
			String filename = fileItem.getName();
			// 上传文件
			fileItem.write(new File(file, filename));
			// 删除临时文件
			fileItem.delete();
		}
	}
	
	return "success";
}

####2.2 SpringMVC文件上传

SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的name属性名称相同。

代码如下

/**
 * SpringMVC方式的文件上传
 * 
 * @param request
 * @return
 * @throws Exception
 */
@RequestMapping(value="/fileupload2")
public String fileupload2(HttpServletRequest request,MultipartFile upload) throws Exception {
	System.out.println("SpringMVC方式的文件上传...");
	// 先获取到要上传的文件目录
	String path = request.getSession().getServletContext().getRealPath("/uploads");
	// 创建File对象,一会向该路径下上传文件
	File file = new File(path);
	// 判断路径是否存在,如果不存在,创建该路径
	if(!file.exists()) {
		file.mkdirs();
	}
	// 获取到上传文件的名称
	String filename = upload.getOriginalFilename();
	String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
	// 把文件的名称唯一化
	filename = uuid+"_"+filename;
	// 上传文件
	upload.transferTo(new File(file,filename));
	return "success";
}

配置文件解析器对象

<!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<property name="maxUploadSize" value="10485760"/>
</bean>

####2.3 SpringMVC跨服务器方式文件上传

搭建图片服务器

  1. 创建一个存储图片的Web项目,该项目中创建一个images文件夹,用于存放上传的图片
  2. 将其部署到另外一个服务器中,并且启动
  3. 注意俩服务器的端口不要一样

Tomcat默认是只读的,要实现跨服务器文件上传的话,就一定要设置Tomcat的readonly为false

怎么设置,通过修改Tomcat的web.xml文件

往DefaultServlet的配置的servlet标签中添加,下面的内容:
<init-param>
    <param-name>readonly</param-name>
    <param-value>false</param-value>
</init-param>

#####2.3.1 实现SpringMVC跨服务器方式文件上传

导入开发需要的jar包

<dependency>
	<groupId>com.sun.jersey</groupId>
	<artifactId>jersey-core</artifactId>
	<version>1.18.1</version>
</dependency>
<dependency>
	<groupId>com.sun.jersey</groupId>
	<artifactId>jersey-client</artifactId>
	<version>1.18.1</version>
</dependency>

编写文件上传的JSP页面

<h3>跨服务器的文件上传</h3>

<form action="/user/fileupload3" method="post" enctype="multipart/form-data">
	选择文件:<input type="file" name="upload"/><br/>
	<input type="submit" value="上传文件"/>
</form>


编写控制器

/**
 * SpringMVC跨服务器方式的文件上传
 * 
 * @param request
 * @return
 * @throws Exception
 */
@RequestMapping(value="/fileupload3")
public String fileupload3(MultipartFile upload) throws Exception {
	System.out.println("SpringMVC跨服务器方式的文件上传...");
	
	// 定义图片服务器的请求路径
	String path = "http://localhost:9090/day02_springmvc5_02image/uploads/";
	
	// 获取到上传文件的名称
	String filename = upload.getOriginalFilename();
	String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
	// 把文件的名称唯一化
	filename = uuid+"_"+filename;
	// 向图片服务器上传文件
	
	// 创建客户端对象
	Client client = Client.create();
	// 连接图片服务器
	WebResource webResource = client.resource(path+filename);
	// 上传文件
	webResource.put(upload.getBytes());
	return "success";
}

第3章:SpringMVC的异常处理

####3.1 异常处理思路

Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行异常的处理。

####3.2 自定义异常处理器
class ExceptionHandler implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object handler, Exception ex) {
        //创建ModelAndView
        ModelAndView md = new ModelAndView();
        //指定友好的错误提示页面
        md.setViewName("error");
        //创建StringWriter
        StringWriter stringWriter = new StringWriter();
        //将错误信息输入进Stringwriter对象中
        ex.printStackTrace(new PrintWriter(stringWriter));
        //输出错误
        System.out.println(stringWriter.toString());
        return md;
    }
}

####3.3 配置异常处理器

###第4章:SpringMVC框架中的拦截器
####4.1 拦截器的概述

  1. SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
  2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
  3. 拦截器和过滤器的功能比较类似,有区别
    1. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
    2. 拦截器是SpringMVC框架独有的。
    3. 过滤器配置了/*,可以拦截任何资源。
    4. 拦截器只会对控制器中的方法进行拦截。
  4. 拦截器也是AOP思想的一种实现方式
  5. 想要自定义拦截器,需要实现HandlerInterceptor接口。

####4.2自定义拦截器步骤

创建类,实现HandlerInterceptor接口,重写需要的方法

/**
* 自定义拦截器1
* @author rt
*/
public class MyInterceptor1 implements HandlerInterceptor{

	/**
	 * controller方法执行前,进行拦截的方法
	 * return true放行
	 * return false拦截
	 * 可以使用转发或者重定向直接跳转到指定的页面。
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("拦截器执行了...");
		return true;
	}

}

####4.3 在springmvc.xml中配置拦截器类

mvc:interceptors
mvc:interceptor

<mvc:mapping path="/user/*"/>



</mvc:interceptor>
</mvc:interceptors>

####4.4 HandlerInterceptor接口中的方法

  1. preHandle方法是controller方法执行前拦截的方法
    1. 可以使用request或者response跳转到指定的页面
    2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
    3. return false不放行,不会执行controller中的方法。
  2. postHandle是controller方法执行后执行的方法,在JSP视图执行前。
    1. 可以使用request或者response跳转到指定的页面
    2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
  3. afterCompletion方法是在JSP执行后执行
    1. request或者response不能再跳转页面了

####4.5 配置多个拦截器

1)再编写一个拦截器的类

2)配置2个拦截器

<!-- 配置拦截器 -->
<mvc:interceptors>
	<mvc:interceptor>
		<!-- 哪些方法进行拦截 -->
		<mvc:mapping path="/user/*"/>
		<!-- 哪些方法不进行拦截 
		<mvc:exclude-mapping path=""/>
		-->
		<!-- 注册拦截器对象 -->
		<bean class="com.itheima.demo1.MyInterceptor1"/>
	</mvc:interceptor>
	
	<mvc:interceptor>
		<!-- 哪些方法进行拦截 -->
		<mvc:mapping path="/**"/>
		<!-- 注册拦截器对象 -->
		<bean class="com.itheima.demo1.MyInterceptor2"/>
	</mvc:interceptor>
</mvc:interceptors>

###MAVEN附录(pom.xml依赖)
<?xml version="1.0" encoding="UTF-8"?>

4.0.0

    <groupId>com.itheima</groupId>
    <artifactId>springmvc-day02-demo1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <!-- 版本锁定 -->
    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--Spring相关依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>




com.fasterxml.jackson.core
jackson-databind
2.9.6


com.fasterxml.jackson.core
jackson-core
2.9.6


com.fasterxml.jackson.core
jackson-annotations
2.9.6

        <!--用于文件上传-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>

        <!--跨服务器上传文件-->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.18.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

        <!--ServletAPI-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

</project>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值