JavaWeb——SpringMVC常用方法

一、MVC常用注解

XML,Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>2019-8-30</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- 配置一个前端Servlet控制器 -->
  <servlet>
			  <servlet-name>dispatcherServlet</servlet-name>
			  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
			  <!-- 引入配置文件 -->
			  <init-param>
					  <param-name>contextConfigLocation</param-name>
					  <param-value>classpath:SpringMVC.xml</param-value>
			  </init-param>
  </servlet>
  <servlet-mapping>
			  <servlet-name>dispatcherServlet</servlet-name>
			  <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

SpringMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://www.springframework.org/schema/beans" 
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:mvc="http://www.springframework.org/schema/mvc" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd ">
	
	<!-- 增加包扫描 -->
	<context:component-scan base-package="beer.onexone.controller"/>
	
	<!-- 自动配置参数 --><!-- 添加自定义转换类 -->
	<mvc:annotation-driven   conversion-service="dateConvert"/>

	<!-- 配置视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<!-- 添加请求地址前缀 -->
		<property name="prefix" value="/CallBack/"></property>
		<!-- 添加请求地址后缀 -->
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<!-- 添加自定义的转换器 -->
	<bean id="dateConvert" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!-- 	添加转换器 -->
		<property name="converters">
						<list>
							<bean class="beer.onexone.utils.ConvertDate"></bean>
						</list>
		</property>
	</bean>

	</beans>

接受回参的JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
${message }
</body>
</html>
package beer.onexone.controller;

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

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import beer.onexone.beans.Person;

//标注为控制层
@Controller
//该注解用在类上表示所有该类访问方法默认加一层路径
@RequestMapping("simple")
public class AtMethods {
				
	//简单参数获取
	//访问路径 主机名:端口号/项目名称/请求地址
	//http://localhost:8080/2019-9-2/simple/m1
	@RequestMapping("m1")
	public String m1(Model model) {
		model.addAttribute("message","m1");
		return "M1";
	}
	
	//可以添加多路径访问
	@RequestMapping({"m2","m3"})
	public String m2(Model model) {
		model.addAttribute("message","m2/m3");
		return "M1";
	}
	
	//可规定访问方式为GET或POST
	@RequestMapping(value = "m4",method = RequestMethod.GET)
	public String m4(Model model) {
		model.addAttribute("message","m4");
		return "M1";
	}
	
	//可规定访问时必须携带参数
	//必须携带name参数,并且age必须为22
	@RequestMapping(value = "m5",params = {"name","age=22"})
	public String m5(Model model) {
		model.addAttribute("message","m5");
		return "M1";
	}
	
	//该注解标识返回值自动转换为为json
	//ResponseBody也可放在public后返回值前
	@ResponseBody
	@RequestMapping(value = "m6")
	public List<Person> m6(Model model) {
		List<Person>  list = new ArrayList<Person>();
		list.add(new Person("古一",276,new Date() ));
		list.add(new Person("一",27,new Date() ));
		list.add(new Person("古",76,new Date() ));
		return  list;
	}
	
	/*@ModelAttribute 写在方法的形参列表中 
	 * 将对应的参数 添加到request域中
	 * value值须与传参名一致*/
	@RequestMapping("m7")
	public String m7(@ModelAttribute(value = "message") String message) {
		return  "M1";
	}
	
	@RequestMapping("/{id}/{name}/m8")
	/*
	 * 使用result风格的传参
	 * @PathVariable获取参数
	 */
	public String m8(@PathVariable("id") int id , @PathVariable("name") String name,Model model) {
		model.addAttribute("message",id +"!"+ name);
		return  "M1";
	}	
}
package beer.onexone.controller;

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

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import beer.onexone.beans.Person;

/*作用相当于 @responseBody 和 @Controller 
 * 如果该类下  所有的方法  都是返回json的方法
 * 方法上就不需要加@responseBody  */
@RestController
public class AllJson {
		@RequestMapping("allJ")
		public List<Person>  allJ(Model model) {
			List<Person>  list = new ArrayList<Person>();
			list.add(new Person("古一",276,new Date() ));
			list.add(new Person("一",27,new Date() ));
			list.add(new Person("古",76,new Date() ));
			return  list;
		}
}
package beer.onexone.controller;

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

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

/*
 * @RequestParam 如果页面传递的参数 和形参不一样 来对应参数
 * 
 * @SessionAttribute 将对应的值添加到session中
 */
@Controller
/*不能和注解@ModelAttribute一起使用*/
@SessionAttributes(value = {"id"})
public class AtSession {
		@RequestMapping("atsession")
		public String atse(Model model, String id) {
			model.addAttribute("id",id);
			return  "M1";
		}
		
		@RequestMapping("getsession")
		public String get(Model model,HttpServletRequest request) {
			HttpSession session = request.getSession();
			model.addAttribute("message",session.getAttribute("id"));
			return  "M1";
		}
}

二、SpringMVC静态资源处理

静态资源处理:前提条件:使用result 风格
使用过滤规则 .do .action .xhtml
静态资源: html 页面 .css .img .png .js .txt
/ .jsp 放行的
自动来获取静态资源 将静态资源 交给服务器创建的默认的servlet 来处理

<!-- 开启静态资源自动放行 -->
	<mvc:default-servlet-handler/>
	<!-- 也可以手动放行
		<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
	 -->

三、SpringMVC的文件上传和下载

  1. 表单必须以post方式提交
  2. 并将表单以二进制形式提交,
    添加enctype="multipart/form-data"属性

XML添加配置

	 <!-- 文件上传配置 -->
		<bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 编码类型 -->
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 总的上传文件最大值 -->
		<property name="maxUploadSize" value="10240000"></property>
		</bean>

文件下载访问路径

<a href="downloadList?path=UploadOrDownload">访问下载页面</a>

文件下载JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

			文件夹:<br>
			<c:forEach items="${directory}" var="d">
			<a href="downloadList?path=${originalPath }/${d }">${d }</a><br>
			</c:forEach>
			<hr>
			
			文件:<br>
			
			<c:forEach items="${file}" var="f">
			<a href="startDownload?originalPath=${originalPath }&filename=${f }">${f }</a><br>
			</c:forEach>
			
</body>
</html>

控制层代码

package beer.onexone.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class FileUploadDownload {
				
	@RequestMapping("upload")
	//传入MultipartFile对象
	public String upload(MultipartFile  multipartFile , HttpServletRequest request) {
		//获取上传文件的目录地址
		String realPath = request.getServletContext().getRealPath("/Upload");
		System.out.println(realPath);
		//创建file对象
		File file = new File(realPath);
		//判断文件夹路径是否存在
		if (!file.isDirectory()) {
			file.mkdirs();
		}
		//获取文件原始名称
		String originalFilename = multipartFile.getOriginalFilename();
		//防止文件重复
		String filename = System.currentTimeMillis() + originalFilename;
		//开始将文件写入(文件所在文件夹,文件名)
		File file2 = new File(realPath, filename);
		try {
			multipartFile.transferTo(file2);
			request.setAttribute("message", "成功");
		} catch (IllegalStateException | IOException e) {		
			request.setAttribute("message", "失败");
			e.printStackTrace();
		} 
		return "FileUploadDownload";
	}
	
	//文件下载页面
	@RequestMapping("downloadList")
	public ModelAndView fileList(ModelAndView modelAndView,String path,HttpServletRequest request) {
		//获取下载路径下所有的文件
		File file = new File(request.getServletContext().getRealPath(path));
		//文件夹与文件区分开保存
		List<String> fileList = new ArrayList<String>();
		List<String> directoryList  = new ArrayList<String>();
		File[] listFiles = file.listFiles();
		if (listFiles!=null) {
			for (File f : listFiles) {
				if (f.isFile()) {
					fileList.add(f.getName());
				}else if (f.isDirectory()) {
					directoryList.add(f.getName());
				}
			}
		}
		//将文件名称,路径返回到JSP
		modelAndView.addObject("file", fileList);
		modelAndView.addObject("directory", directoryList);
		modelAndView.addObject("originalPath", path);
		modelAndView.setViewName("downLoad");
		return modelAndView;
	}
	
	@RequestMapping("startDownload")
	public ResponseEntity<byte[]> startDownload(String originalPath,String filename,HttpServletRequest request) throws IOException{
		System.out.println(originalPath);
		System.out.println(filename);
		originalPath = request.getServletContext().getRealPath(originalPath);
		//创建文件对象
		File file = new File(originalPath,filename);
		//设置编码格式,防止文件乱码
		HttpHeaders httpHeaders = new HttpHeaders();
		filename = new String(filename.getBytes("UTF-8"),"ISO-8859-1");
		//在响应头添加附加名
		httpHeaders.setContentDispositionFormData("attachment", filename);
		//设置下载类型
		httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),httpHeaders,HttpStatus.OK);
	}
}

四、SpringMVC拦截器

SpringMVC拦截器的功能与Filter类似
该拦截器通过AOP来实现
创建一个拦截器需要继承接口

SpringMVC.XML添加配置

		<!-- 配置拦截器 -->
		<mvc:interceptors>
				<mvc:interceptor>
				<!-- 拦截路径设置 -->
						<mvc:mapping path="/**"/>
					<!-- 配置拦截器类 -->
						<bean class="beer.onexone.utils.TheHandlerInterceptor"/>
				</mvc:interceptor>
		
		</mvc:interceptors>

拦截器

package beer.onexone.utils;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class TheHandlerInterceptor implements HandlerInterceptor {

	// 该方法在连接请求后,进入Handler之间执行
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("Handler之前");
         	//设置为true标识放行
		return true;
	}

	// 在进入Handler之后,进入视图解析器之前执行
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("Handler之后");
	}

	// 执行视图解析器之后执行,一般用来资源清理
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("解析器之后");
	}

}

按顺序配置三个拦截器,查看运行顺序

Handler之前1
Handler之前2
Handler之前3
Handler之后3
Handler之后2
Handler之后1
解析器之后3
解析器之后2
解析器之后1

preHandle方法顺序运行
postHandle、afterCompletion逆序运行

  • 在拦截器链中,若第一个拦截器返回false,那么之后的所有拦截器以及方法都不会运行
  • 若中间的任何拦截器返回false,那么该拦截器之后的所有拦截器和方法都不会运行,在该拦截器之前已运行的拦截器会执行afterCompletion方法

拦截器 和过滤器 的区别:

  1. 过滤器 是servlet 定义的规则  只能在servlet 下使用
  2. Spring拦截器,可以通过AOP对任何方法进行拦截
  3. 拦截器里面提供了 在handler 执行前 执行后 视图解析去器执行后的方法 可以在任意范围内来编写要添加的内容

五、SpringMVC重定向传参

在MVC中可以使用RedirectAttributes来重定向的时候传递参数

package beer.onexone.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
public class RedirAndDataTr {
	
	//显式重定向传参,该方法重定向时,参数会显示在地址栏
	@RequestMapping("trDataWithRedir")
	public String trDataWithRedir(String name,RedirectAttributes redirectAttributes) {
		redirectAttributes.addAttribute("message",name);
		return "redirect:readTrDataWithRedir";
	}
	//接收显式重定向传参
	@RequestMapping("readTrDataWithRedir")
	public String readTrDataWithRedir(String message,HttpServletRequest request) {
		request.setAttribute("message",message);
		return "M1";
	}
	
	//隐式重定向传参,使用的是session域来传参
	@RequestMapping("trDataWithRedirHide")
	public String trDataWithRedirHide(String name,RedirectAttributes redirectAttributes) {
		redirectAttributes.addFlashAttribute("message",name);
		return "redirect:readTrDataWithRedirHide";
	}
	//接收藏式重定向传参
	@RequestMapping("readTrDataWithRedirHide")
	public String readTrDataWithRedirHide(@ModelAttribute("message")String message,HttpServletRequest request) {
		request.setAttribute("message",message);
		return "M1";
	}
}

JSP:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
SUCCESS!<br>
${message }
<hr>
</body>
</html>

六、SpringMVC统一异常处理

上线项目,不会将错误页面展示给用户,一般会有一个错误提示页面,一旦发生错误就将跳转到该页面。

创建一个类实现HandlerExcetpionResolver接口

package beer.onexone.utils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

public class TheHandlerExcetpionResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object,
			Exception e) {
		//后台发生的错误可以打印控制台,或存到日志文件中
		e.printStackTrace();
		//给用户展示的页面
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("erro");
		modelAndView.addObject("erro","维护中");
		return modelAndView;
	}

}

SpringMVC.XML添加

	<!-- 统一异常处理配置 -->
	 <bean class="beer.onexone.utils.TheHandlerExcetpionResolver"/>

七、JSR303数据校验

使用该校验方法需要在JSP中引入标签

  <%@taglib uri="http://www.springframework.org/tags/form"  prefix="f"%>

JSP代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    	<!-- 添加form标签 -->
    <%@taglib uri="http://www.springframework.org/tags/form"  prefix="f"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
				
					<f:form action="${pageContext.request.contextPath }/register" method="post" modelAttribute="user">
					用户名:<f:input path="name"/><f:errors path="name"/><br><br>
					密码:<f:password path="password"/><f:errors path="password"/><br><br>
					性别:<f:radiobutton path="sex"  value="男" label="男"/>
									<f:radiobutton path="sex"  value="女" label="女"/><f:errors path="sex"></f:errors><br><br>
					邮箱:<f:input path="email"/><f:errors path="email"/><br><br>
					年龄:<f:input path="age"/><f:errors path="age"/><br><br>
					电话:<f:input path="phone"/><f:errors path="phone"/><br><br>
					出生日期:<f:input path="date"/><f:errors path="date"/><br><br>
					<input type="submit" value="Submit">
					</f:form>			
</body>
</html>

注册及验证的控制层代码

package beer.onexone.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;

import beer.onexone.beans.User;

@Controller
public class Register {
	
	//注册的前置方法,将对象传达到到注册页面
	@RequestMapping("theRegister")
	public String theRegister(Model model) {
		model.addAttribute("user",new User());
		return "register";
	}
	
	//注册的方法
	@RequestMapping("register")
	public String register(@Valid User user ,BindingResult bindingResult,Model model) {
		/* 接收页面传递的参数,必须用@Valid 
		 * 创建BindingResult对象,验证数据
		 * 调用hasErrors来判断结果是否正确
		 * */
		if (bindingResult.hasErrors()) {
			//获取所有错误信息,在后台查看
			List<ObjectError> errors = bindingResult.getAllErrors();
			for (ObjectError objectError : errors) {
				System.out.println(objectError);
			}
			return "register";
		}else {
			//无误则调用成功的方法
			model.addAttribute("message","成功");
			return "M1";
		}
		
	}
}

jingsongchan

发表评论

电子邮件地址不会被公开。 必填项已用*标注