SpringMVC3 环境搭建

SpringMVC3 环境搭建

下载相关JAR包

链接:https://pan.baidu.com/s/1o83rTwJ7S5YagllFfJcQmg
提取码:ufnk

搭建 SpringMVC3 环境

  1. 创建 JavaWeb项目
  2. 将 Spring 的核心 JAR 文件与 SpingMVC 的 JAR 文件都导入到WebRoot/WEB-INF/lib目录下
  3. web.xml 中配置 Servlet,此步可以理解为是SpringMVC的执行入口
    <?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">
    
    	<!-- 配置 SpringMVC 入口 -->
    	<servlet>
    		<servlet-name>DispatcherServlet</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<!-- 指定 SpringMVC 配置文件所在路径 -->
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>classpath:springmvc-servlet.xml</param-value>
    		</init-param>
    		<!-- 启动容器时就要加载 SpringServlet -->
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>DispatcherServlet</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    </web-app>
    
  4. 创建resources源码目录,在此目录下创建SpringMVC配置文件:springmvc-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" 
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:mvc="http://www.springframework.org/schema/mvc"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
    	http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    	http://www.springframework.org/schema/context 
    	http://www.springframework.org/schema/context/spring-context-3.2.xsd
    	http://www.springframework.org/schema/mvc
    	http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
    	<!-- 配置处理器映射 指明访问某个URL时要进入的控制器类 -->
    	<bean name="/index.html" class="controller.IndexController"/>
    	<!-- 配置内部资源视图解析器 -->
    	<!-- 视图路径:/WEB-INF/jsp/逻辑视图名.jsp	 -->
    	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="prefix" value="/WEB-INF/jsp/"/>
    		<property name="suffix" value=".jsp"/>
    	</bean>
    </beans>
    
  5. src目录下创建控制器包controller,在控制器包中创建控制器IndexController.java,并键入如下信息:
    package controller;
    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 IndexController extends AbstractController {
    	@Override
    	protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
    			HttpServletResponse arg1) throws Exception {
    		System.out.println("Hello SpringMVC");
    		// index 为逻辑视图名 真实的视图路径为:/WEB-INF/jsp/index.jsp
    		return new ModelAndView("index");
    	}
    }
    
  6. WebRoot/WEB-INF下,创建jsp文件夹,在里面创建index.jsp文件,并键入如下内容:
    <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    	<base href="<%=basePath%>">
    	<title>首页</title>
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    </head>
    <body>
    	<h1>Hello SpringMVC</h1>
    </body>
    </html>
    
  7. 部署项目,并通过浏览器访问 http://localhost:8080/你的项目名/index.html

SprintMVC3 使用注解实现控制器类

支持注解配置

<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
	<!-- IOC注解支持 -->
	<context:component-scan base-package="controller"></context:component-scan>
	<!-- MVC注解支持 -->
	<mvc:annotation-driven/>
	<!-- 内部资源视图解析器 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

控制器改造

package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class IndexController {
	@RequestMapping("/index.html")
	public ModelAndView index(){
		return new ModelAndView("index");
	}
}
// 等效于
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
	@RequestMapping("/index.html")
	public String index(){
		return "index";
	}
}

SpringMVC3 请求映射映射

单映射

单级映射

访问URL:/index

@Controller
public class IndexController {
	@RequestMapping("/index")Q
	public String index() {
		return "index";
	}
}

多级映射

访问URL:/user/index

@Controller
public class IndexController {
	@RequestMapping("/user/index")
	public String index() {
		return "index";
	}
}
// 等效于
@Controller
@RequestMapping("/user")
public class IndexController {
	@RequestMapping("/index")
	public String index(){
		return "user/index";
	}
}

多映射

访问URL:/index/

@Controller
public class IndexController {
	@RequestMapping({"/index","/"})
	public String index() {
		return "index";
	}
}

只允许GET请求

GET方式请求:/index

@Controller
public class IndexController {
	@RequestMapping(value="/index",method=RequestMethod.GET)
	public String index() {
		return "index";
	}
}

只允许POST请求

POST方式请求:/index

@Controller
public class IndexController {
	@RequestMapping(value="/index",method=RequestMethod.POST)
	public String index() {
		return "index";
	}
}

SpringMVC3 视图向控制器传递参数

提交单个参数

访问URL:/index?name=admin

@Controller
public class IndexController {
	@RequestMapping("/index")
	public String index(String name){
		System.out.println(name);
		return "index";
	}
}
// 等效于
@Controller
public class IndexController {
	@RequestMapping("/index")
	public String index(@RequestParam String name){
		System.out.println(name);
		return "index";
	}
}
// 等效于
@Controller
public class IndexController {
	@RequestMapping("/index")
	public String index(@RequestParam("name") String name){
		System.out.println(name);
		return "index";
	}
}
// 等效于
@Controller
public class IndexController {
	@RequestMapping(value="/index",params="name")
	public String index(String name){
		System.out.println(name);
		return "index";
	}
}

提交多个参数

访问URL:/index?name=admin&age=20

@Controller
public class IndexController {
	@RequestMapping("/index")
	public String index(String name, int age){
		System.out.println(name);
		System.out.println(age);
		return "index";
	}
}
// 等效于
public class IndexController {
	@RequestMapping("/index")
	public String index(@RequestParam String name, @RequestParam int age){
		System.out.println(name);
		System.out.println(age);
		return "index";
	}
}
// 等效于
@Controller
public class IndexController {
	@RequestMapping("/index")
	public String index(@RequestParam("name") String name, @RequestParam("age") int age){
		System.out.println(name);
		System.out.println(age);
		return "index";
	}
}
// 等效于
@Controller
public class IndexController {
	@RequestMapping(value = "/index", params = { "name", "age" })
	public String index(String name, int age) {
		System.out.println(name);
		System.out.println(age);
		return "index";
	}
}

非必填参数

访问URL:/index

@Controller
public class IndexController {
	@RequestMapping("/index")
	public String index(@RequestParam(required=false,value="name")String name) {
		System.out.println(name); // null
		return "index";
	}
}

给参数设置默认值

访问URL:/index

@Controller
public class IndexController {
	@RequestMapping("/index")
	public String index(@RequestParam(required=false,value="name",defaultValue="匿名")String name) {
		System.out.println(name); // 匿名
		return "index";
	}
}

将参数赋值给对象的属性

  1. add.html 传来的参数名应该与 pojo.User 类中的属性名相同,否则无法进行自动赋值
  2. 无法给 pojo.User 类中的 Date 类型的属性自动赋值,需要在 Date 类型属性上添加注解 @DateTimeFormat(pattern="yyyy-MM-dd")
  3. 控制器中的操作方法的参数不能添加 @RequestParam 注解

控制器操作方法

@RequestMapping(value = "/add.html", method = RequestMethod.POST)
public String addSave(User user) {
	return "user/userlist";
}

pojo.User时间属性

@DateTimeFormat(pattern="yyyy-mm-dd")
private Date birthday;

SpringMVC3 控制器向视图传递参数

使用 ModelAndView 类实现

传入普通类型参数

控制器

@RequestMapping("/index")
public ModelAndView index() {
	ModelAndView mView = new ModelAndView("index");
	mView.addObject("username", "admin");
	mView.addObject("password", "123456");
	return mView;
}

视图

<h1>${username}</h1>
<h1>${password}</h1>

传入Map类型的参数

控制器

@RequestMapping("/index")
public ModelAndView index() {
	ModelAndView mView = new ModelAndView("index");
	Map<String, String> modelMap = new HashMap<String, String>();
	modelMap.put("username", "admin");
	modelMap.put("password", "123456");
	mView.addAllObjects(modelMap);
	return mView;
}

视图

<h1>${username}</h1>
<h1>${password}</h1>

传入对象类型的参数

控制器

@RequestMapping("/index")
public ModelAndView index() {
	ModelAndView mView = new ModelAndView("index");
	User user = new User();
	user.setUsername("admin");
	user.setPassword("123456");
	mView.addObject(user);
	return mView;
}

视图

<h1>username:${user.username}</h1>
<h1>password:${user.password}</h1>

使用 Model 类实现

传入普通类型参数

控制器

@RequestMapping("/index")
public String index(Model model) {
	model.addAttribute("username", "admin");
	model.addAttribute("password", "123456");
	return "index";
}

视图

<h1>${username}</h1>
<h1>${password}</h1>

传入 Map 类型的参数

控制器

@RequestMapping(value="/index")
public String index(Model model) {
	Map<String, String> datas = new HashMap<String, String>();
	datas.put("username", "admin");
	datas.put("password", "123456");
	model.addAllAttributes(datas);
	return "index";
}

视图

<h1>username:${username}</h1>
<h1>password:${password}</h1>

向页面传递对象参数

控制器

@RequestMapping("/index")
public String index(Model model) {
	User user = new User();
	user.setUsername("admin");
	user.setPassword("123456");
	model.addAttribute(user);
	return "index";
}

视图

<h1>username:${user.username}</h1>
<h1>password:${user.password}</h1>

接受参数并返回到页面

访问URL:http://localhost:8080/smdemo/index?username=admin
控制器

@RequestMapping(value="/index",params="username")
public String index(String username, Model model) {
	model.addAttribute("username",username);
	return "index";
}

视图

<h1>${username}</h1>

使用 Map 类型实现

控制器

@RequestMapping("/index")
public String index(Map<String, Object> model) {
	model.put("username","张三");
	model.put("password","123456");
	return "index";
}

视图

<h1>username:${username}</h1>
<h1>password:${password}</h1>

SpringMVC3 整合Spring与MyBatis

创建项目

  1. 创建 WEB 项目 SSM

  2. 将相关的 JAR 文件拷贝到 WebRoot/WEB-INF/lib 目录下

  3. 创建 resources 源码目录

  4. log4j.propertiesdatabase.properties 拷贝到 resources 目录中

  5. resources 目录中创建 spring-mvc.xmlspring-mybatis.xml

  6. src 目录中创建包 daoservicecontrollerpojo

  7. 创建 WebRoot/WEB-INF/jsp 目录

  8. 创建 WebRoot/statics 目录

配置SSM

  1. 打开 WebRoot/WEB-INF/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">

	<!-- 指定SpringMVC配置文件的位置 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring-*.xml</param-value>
	</context-param>

	<!-- 上下文加载监听器 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- 配置 springMVC 的 入口路径 -->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 指定 springmvc 配置文件所在的路径 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-*.xml</param-value>
		</init-param>
		<!-- Tomcat容器启动时就启动SpringMVC服务 -->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>
  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:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.2.xsd">

	<!-- IOC注解支持 -->
	<context:component-scan base-package="controller"/>

	<!-- MVC注解支持 -->
	<mvc:annotation-driven />

	<!-- 视图层模板解析器配置 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>

	<!-- 静态资源配置 -->
	<mvc:resources location="/statics/" mapping="/statics/**"/>
</beans>
  1. 打开 spring-mybatis.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.2.xsd">

	<!-- IOC注解支持 -->
	<context:component-scan base-package="dao,pojo,service"></context:component-scan>

	<!-- 读取Property配置文件 -->
	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location" value="classpath:database.properties" />
	</bean>

	<!-- 配置数据源 -->
	<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${driver}" />
		<property name="url" value="${url}" />
		<property name="username" value="${username}" />
		<property name="password" value="${password}" />
	</bean>

	<!-- 配置 SqlSessionFactory -->
	<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="datasource" />
		<property name="typeAliasesPackage" value="pojo" />
	</bean>

	<!-- 配置 Mapper 自动实现 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="dao" />
	</bean>
	<!-- 事务管理器 -->
	<bean id="txMananger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="datasource" />
	</bean>
	<!-- 支持注解实现事务 -->
	<tx:annotation-driven transaction-manager="txManager"/>
</beans>

编写POJO类

根据数据库,编写相关表的 POJO 类

编写数据库操作

在 dao 包中创建接口与映射文件,使用 MyBatis 编写数据库操作

编写业务层

根据相关业务,编写业务层,调用 DAO 层获取数据

编写视图层

将相关视图模板拷贝到 WebRoot/WEB-INF/jsp 目录中,并将静态资源文件拷贝到 WebRoot/statics 目录中

编写控制器

根据相关业务,编写控制器,调用业务层获取数据,并加载相关视图模板与数据进行绑定,然后将最终的结果返回给用户

SpringMVC3 转发与重定向

转发

@RequestMapping(value = "/forward.html")
public String forward() {
	return "forward:index.html";
}

重定向

@RequestMapping(value = "/redirect.html")
public String redirect() {
	return "redirect:index.html";
}

SpringMVC3 Session与Reuqrest对象

使用 session 对象

@RequestMapping(value="/index.html")
public String index(HttpSession session){ ... }

使用 request 对象

@RequestMapping(value="/index.html")
public String index(HttpServletRequest request){ ... }

SpringMVC3 加载静态资源

  1. 创建静态资源目录:WebRoot/statics
  2. 在 SpringMVC 的配置文件中进行配置:
<!-- 将 URL '/statics/ 与 本地物理路径 'WebRoot/statics/' 进行绑定 -->
<mvc:resources location="/statics/" mapping="/statics/**"></mvc:resources>
  1. 修改视图页面的静态资源路径:
<link rel="stylesheet" href="<%=basePath %>statics/css/custom.css">
<script src="<%=basePath %>statics/js/custom.js"></script>

SpringMVC3 异常处理

局部异常处理

  1. 在控制器中创建异常处理方法
@Controller
public class IndexController {

	@RequestMapping(value = "/index")
	public String index() {
		throw new RuntimeException("出现异常");
	}

	// 异常处理操作 当 Index 控制器中出现 RuntimeException 异常时,则调用此方法
	@ExceptionHandler(value={RuntimeException.class})
	public String handlerException(RuntimeException e, HttpServletRequest req){
		req.setAttribute("e", e);
		return "error";
	}
}
  1. WebRoot/WEB-INF/jsp 目录下创建异常显示页面 error.jsp,并键入:
<h1>异常信息:${e.message}</h1>

全局异常处理

  1. 在 SpringMVC 的配置文件中添加全局异常处理配置
<!-- 全局异常处理 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
	<property name="exceptionMappings">
		<props>
			<prop key="java.lang.RuntimeException">error</prop>
		</props>
	</property>
</bean>
  1. 在控制器中抛出异常
@Controller
public class IndexController {
	@RequestMapping(value = "/index")
	public String index() {
		throw new RuntimeException("出现异常");
	}
}
  1. 创建错误页面 WEB-INF/jsp/error.jsp,并键入如下信息:
<h1>异常信息:${exception.message}</h1>

SpringMVC3 中文乱码问题

web.xml中添加spring字符编码过滤器

<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>
	<init-param>
		<param-name>forceEncoding</param-name>
		<param-value>true</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>encodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

SpringMVC3 表单标签

声明 taglib 指令

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

form 标签

modelAttribute 属性值应该与 @ModelAttribute 后的参数名称保持一致
View

<fm:form method="post" modelAttribute="user"> ... </fm:form>

Controller

@RequestMapping(value = "/add.html", method = RequestMethod.GET)
public String add(@ModelAttribute User user) { ... }

常用表单标签

名称说明
<fm:input />单行输入框
<fm:password />密码框
<fm:hidden />隐藏域
<fm:textarea />文本域
<fm:radiobutton />单选框
<fm:checkbox />复选框
<fm:select />下拉列表框
<fm:error />显示表单数据校验所对应的错误信息

常用属性

属性描述
path属性路径,表示表单对象属性
cssClass表单组件对应的CSS样式类名
cssErrorClass当提交表单后报错(服务端错误),采用的CSS样式类
cssStyle表单组件对应的CSS样式
htmlEscape绑定的表单属性值是否要对HTML特殊字符进行转换,默认为true

SpringMVC3 JSR303校验框架

依赖的JAR文件

  1. hibernate-validator-4.3.2.Final.jar
  2. jboss-logging-3.1.0.CR2.jar
  3. validation-api-1.0.0.GA.jar

JSR 303 约束

约束说明
@Null被注释的元素必须为null
@NotNull被注释的元素必须不为null
@AssertTrue被注释的元素必须为 true
@AssertFalse被注释的元素必须为 false
@Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min)被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past被注释的元素必须是一个过去的日期
@Future被注释的元素必须是一个将来的日期

JSR 303 应用

  1. 将相关 JAR 文件拷贝到 WebRoot/WEB-INF/lib 目录中

  2. 在 pojo 类的属性上添加校验注解

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
public class User {
	@NotEmpty(message="用户编码不能为空")
	private String userCode; //用户编码
	@NotEmpty(message="用户名称不能为空")
	private String userName; //用户名称
	@NotNull(message="密码不能为空")
	@Length(min=6,max=10,message="用户密码长度为6-10")
	private String userPassword; //用户密码	
	@Past(message="必须是一个过去的时间")
	@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date birthday;  //出生日期
	// ...
}
  1. 在控制器操作方法中指定要校验的入参
/**
 * 第一个参数:需要校验的入参
 * 第二个参数:校验后的结果对象
 */
@RequestMapping(value="/add.html",method=RequestMethod.POST)
public String addSave(@Valid User user,BindingResult bindingResult){
	if(bindingResult.hasErrors()){
		// 校验失败时的操作
		return "user/useradd";
	}
	// 通过校验时的操作
}
  1. 在视图层显示错误信息
<fm:errors path="userCode"/>

SpringMVC3 REST风格的URL

访问URL:http://localhost:8080/项目名称/view/1

@RequestMapping(value="/view/{id} ",method=RequestMethod.GET)
// @PathVariable 注解将 URL 中的 {id} 与 入参 String id 进行绑定
public String view(@PathVariable String id,Model model){
	System.out.print(id); // 输出:1
	return "userview";
}

SpringMVC3 文件上传

依赖的JAR文件

  1. commons-fileupload-1.2.2.jar
  2. commons-io-2.4.jar
  3. commons-lang-2.6.jar

单文件上传

  1. 在 SpringMVC 的配置文件中添加如下配置:
<!-- 上传配置 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!-- 允许上传文件的大小设置为 5000000字节 -->
	<property name="maxUploadSize" value="5000000"/>
	<!-- 将请求的编码格式设置为 UTF-8 -->
	<property name="defaultEncoding" value="UTF-8"/>
</bean>
  1. 编写文件上传表单
<form action="/upload.html" method="post" enctype="multipart/form-data">
	<div>
		<label for="pic">图片</label>
		<input type="file" id="pic" name="pic"/>
		<input type="submit" value="上传" />
	</div>
</form>
  1. 编写控制器实现上传
@RequestMapping(value="/picmodify.html",method = RequestMethod.POST)
public String picmodify(@RequestParam(value = "pic",required = false)MultipartFile multipartFile,
						HttpServletRequest request) {

	// 判断是否为空
	if(multipartFile.isEmpty()){
		request.setAttribute("msg", "您没有指定上传文件");
		request.setAttribute("url", "/admin/user/picmodify.html");
		return "info";
	}

	// 设置上传文件存放的路径
	String path = request.getSession().getServletContext().getRealPath("statics"+ File.separator+"uploads");
	// 设置允许上传文件的最大字节数
	long allowSize = 5 * 1024 * 1024;
	// 设置允许上传文件的类型
	String[] allowExt = {"jpg","png","gif","jpeg"};

	// 获取上传文件的文件名
	String oldFileName = multipartFile.getOriginalFilename();
	// 获取上传文件的扩展名
	String oldFileExt = FilenameUtils.getExtension(oldFileName);
	// 获取上传文件的字节数
	long oldFileSize = multipartFile.getSize();

	// 验证上传文件的尺寸
	if(allowSize < oldFileSize){
		request.setAttribute("msg","您上传的文件太大,最大尺寸不能超过 "+ allowSize +" 个字节");
		request.setAttribute("url","/admin/user/picmodify.html");
		return "info";
	}

	// 验证上传文件的类型
	if(!Arrays.asList(allowExt).contains(oldFileExt)){
		request.setAttribute("msg","您上传的文件类型不正确");
		request.setAttribute("url","/admin/user/picmodify.html");
		return "info";
	}

	// 生成新文件
	String newFileName = System.currentTimeMillis()+ new Random().nextInt(1000000)+"."+oldFileExt;
	File newFile = new File(path,newFileName);

	// 创建服务器目录
	if(!newFile.exists()){
		newFile.mkdirs();
	}

	// 迁移新文件
	try {
		multipartFile.transferTo(newFile);

		request.setAttribute("msg","上传文件成功:"+newFileName);

	} catch (IOException e) {
		request.setAttribute("msg","上传文件失败");
		request.setAttribute("url","/admin/user/picmodify.html");
		e.printStackTrace();
	}

	return "info";
}

多文件上传

  1. 在 SpringMVC 的配置文件中添加如下配置:
<!-- 上传配置 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!-- 允许上传文件的大小设置为 5000000字节 -->
	<property name="maxUploadSize" value="5000000"/>
	<!-- 将请求的编码格式设置为 UTF-8 -->
	<property name="defaultEncoding" value="UTF-8"/>
</bean>
  1. 编写文件上传表单
<form action="/upload.html" method="post" enctype="multipart/form-data">
	<div>
		<label for="pic1">图片1</label>
		<input type="file" id="pic1" name="pic"/>
	</div>
	<div>
		<label for="pic2">图片2</label>
		<input type="file" id="pic2" name="pic"/>
	</div>
	<input type="submit" value="上传" />
</form>
  1. 编写控制器实现上传
@RequestMapping(value="/upload.html",method=RequestMethod.POST)
public String addUserSave(@RequestParam(value ="pic", required = false) MultipartFile[] attachs, HttpServletRequest request){
	String idPicPath = null;
	for (int i = 0; i < attachs.length; i++) {
		MultipartFile attach = attachs[i];
		//判断文件是否为空
		if(!attach.isEmpty()){
			// 省略部分为单文件上传代码
		}
	}
	return "info";
}

前后端分离实现文件上传

后端控制器

@RequestMapping(value = "/picmodify", method = RequestMethod.POST)
@ResponseBody
public Object picmodify1(
        @RequestParam(value = "pic", required = false) MultipartFile multipartFile, HttpServletRequest request) {
    Map<String,String> map = new HashMap<>();
    // 判断上传的文件是否为空
    if (multipartFile.isEmpty()) {
        map.put("state", "0");
        map.put("msg", "请选择文件");
        return map;
    }

    // 设置存储路径
    String savePath = request.getSession().getServletContext().getRealPath("statics/uploads");
    // 设置允许上传的大小
    long allowSize = 1024 * 1024 * 5;
    // 设置允许上传的扩展名
    String[] allowExtends = {"jpg", "png", "gif"};

    // 验证上传文件的大小
    long oldSize = multipartFile.getSize();
    if (oldSize > allowSize) {
        map.put("state", "0");
        map.put("msg", "上传文件太大");
        return map;
    }

    // 验证上传文件的扩展名
    String oldFileName = multipartFile.getOriginalFilename();
    String oldExtend = FilenameUtils.getExtension(oldFileName);
    if(!Arrays.asList(allowExtends).contains(oldExtend)){
        map.put("state", "0");
        map.put("msg", "上传非法类型的文件");
        return map;
    }

    // 生成要保存到服务器上的文件
    String newFileName = System.currentTimeMillis() + new Random().nextInt(1000000) + "." + oldExtend;
    File newFile = new File(savePath,newFileName);
    if(!newFile.exists()){
        newFile.mkdirs();
    }

    // 文件迁移
    try {
        multipartFile.transferTo(newFile);
        map.put("state", "1");
        map.put("msg", "上传成功");
    } catch (IOException e) {
        map.put("state", "0");
        map.put("msg", "上传失败");
        e.printStackTrace();
    }

    return map;
}

前端HTML

<form action="#" method="post" enctype="multipart/form-data">
    <div class="form-group row">
        <label for="pic" class="col-2 text-right m-0 col-form-label">头像上传:</label>
        <input type="file" id="pic" name="pic" class="form-control col-3">
    </div>
    <div class="form-group row">
        <div class="offset-2">
            <input type="button" class="btn btn-primary pl-5 pr-5 mr-3" onclick="upload_handle()"
                   value="上传">
        </div>
    </div>
</form>

前端脚本

function upload_handle() {
    let file = $('#pic')[0].files[0];
    let formData = new FormData();
    formData.append("pic", file);
    $.ajax({
            url: "http://localhost/api/picmodify",
            type: "post",
            data: formData,
            contentType: false,
            processData: false,
            resultType: "json",
            success: function (res) {
                console.log(res);
            }
        }
    );
}

SpringMVC3 响应JSON数据

依赖的JAR文件

fastjson-1.2.13.jar

返回JSON数据

给方法加注解 @ResponseBody

@RequestMapping("/index")
@ResponseBody // 该注解告诉容器不加载模板,而是直接返回内容到页面
public String index() {
	Map<String, String> maps = new HashMap<String, String>();
	maps.put("id", "1");
	maps.put("name", "zhangsan");
	return JSONArray.toJSONString(maps);
}

给类加注解 @RestController

@RestController
public class IndexController{
	@RequestMapping("/index")
	public String index(){
		Map<String, String> maps = new HashMap<String, String>();
	maps.put("id", "1");
	maps.put("name", "zhangsan");
	return JSONArray.toJSONString(maps);
	}
}

中文乱码解决

使用注解解决

@RequestMapping(value="/index",produces={"application/json;charset=UTF-8"})
@ResponseBody
public String index() { ... }

使用StringHttpMessageConverter类解决

<mvc:annotation-driven>
	<mvc:message-converters>
		<bean class="org.springframework.http.converter.StringHttpMessageConverter">
			<property name="supportedMediaTypes">
				<list>
					<value>application/json;charset=UTF-8</value>
					<value>text/html;charset=UTF-8</value>
					</list>
			</property>
		</bean>
	</mvc:message-converters>
</mvc:annotation-driven>

使用FastJsonHttpMessageConverter类解决

<mvc:annotation-driven>
	<mvc:message-converters>
		<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
			<property name="supportedMediaTypes">
				<list>
					<value>application/json;charset=UTF-8</value>
					<value>text/html;charset=UTF-8</value>
				</list>
			</property>
		</bean>
	</mvc:message-converters>
</mvc:annotation-driven>

JSON请求时406错误

报错原因
请求的 URL 后缀如果以 .html 结尾,例如:@RequestMapping("/index.html"),Spring 将会以 HTML 的形式进行请求,而返回的数据为 JSON 数据,导致请求与响应的格式不统一,所以报 406 错误。
解决方案
只需将请求 URL 的后缀 .html 删除即可,例如 @RequestMapping("/index")

日期格式问题

注解方式解决

通过在POJO类字段上添加注解设置日期格式

public class User{
	@JSONField(format="yyyy-MM-dd")
	private Date birthday;
	// ...
}

配置文件方式解决

<mvc:annotation-driven>
	<mvc:message-converters>
		<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
			<!-- 解决 中文乱码 问题 -->
			<property name="supportedMediaTypes">
				<list>
					<value>application/json;charset=UTF-8</value>
					<value>text/html;charset=UTF-8</value>
				</list>
			</property>
			<!-- 解决 JSON 日期格式问题 -->
			<property name="features">
				<list>
					<!-- Date的日期转换器,转换成的日期格式:yyyy-MM-dd HH:mm:ss -->
					<value>WriteDateUseDateFormat</value>
				</list>
			</property>
		</bean>
	</mvc:message-converters>
</mvc:annotation-driven>

混合模式

如果同时使用了 注解方式 和 配置文件方式 解决日期问题,则以 注解方式 为准!

SpringMVC3 多视图解析器

配置XML文件

<!-- 视图层模板解析器配置 
<bean
	class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/jsp/" />
	<property name="suffix" value=".jsp" />
</bean>-->

<!-- 多视图解析器 -->
<bean
	class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
	<property name="favorParameter" value="true" />
	<property name="mediaTypes">
		<map>
			<entry key="html" value="text/html;charset=UTF-8" />
			<entry key="json" value="application/json;charset=UTF-8" />
		</map>
	</property>
	<property name="viewResolvers">
		<list>
			<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
				<property name="prefix" value="/WEB-INF/jsp/" />
				<property name="suffix" value=".jsp" />
			</bean>
		</list>
	</property>
</bean>

编写控制器

@RequestMapping("/show/{id}")
@ResponseBody
public User getUserById(@PathVariable int id){
	return service.getUserById(id);
}

SpringMVC3 自定义转换器

创建自定义转换器

创建 tools.StringToDateConverter

package tools;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
public class StringToDateConverter implements Converter<String, Date> {
	private String datePattern;
	public StringToDateConverter() {
	}
	public StringToDateConverter(String datePattern) {
		this.datePattern = datePattern;
	}
	@Override
	public Date convert(String s) {
		Date date = null;
		try {
			date = new SimpleDateFormat(datePattern).parse(s);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
}

配置自定义转换器

在 SpringMVC 配置文件中配置以下代码:

<!-- 定义转换器 -->
<bean id="myConversionService"
	class="org.springframework.context.support.ConversionServiceFactoryBean">
	<property name="converters">
		<list>
			<bean class="tools.StringToDateConverter">
				<constructor-arg type="java.lang.String">
					<value>yyyy-MM-dd</value>
				</constructor-arg>
			</bean>
		</list>
	</property>
</bean>
<!-- MVC注解支持 -->
<mvc:annotation-driven conversion-service="myConversionService">
	<!-- 中文乱码解决 -->
	<mvc:message-converters>
		<bean
			class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
			<property name="supportedMediaTypes">
				<list>
					<value>application/json;charset=UTF-8</value>
					<value>text/html;charset=UTF-8</value>
				</list>
			</property>
		</bean>
	</mvc:message-converters>
</mvc:annotation-driven>

SpringMVC3 自定义编辑器

创建自定义编辑器

创建类 controller.BaseController,并键入如下信息:

package controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
public class BaseController {
	@InitBinder
	public void initBinder(WebDataBinder dataBinder) {
		System.out.println("initBinder被调用了...");
		dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(
				new SimpleDateFormat("yyyy-MM-dd"), true));
	}
}

使用自定义编辑器

打开控制器类,让其继承 BaseController 类

@Controller
public class UserController extends BaseController{ ... }

SpringMVC3 自定义拦截器

创建自定义拦截器

package interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import pojo.User;

public class SysInterceptor extends HandlerInterceptorAdapter {
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {

		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		if (null == user) {
			response.sendRedirect(request.getContextPath() + "/401.jsp");
			return false;
		}

		return true;
	}
}

配置自定义拦截器

访问 http://localhost:8080/SSM/sys/* 路径将进入拦截器进行拦截验证

<!-- 配置拦截器 -->
<mvc:interceptors>
	<mvc:interceptor>
		<mvc:mapping path="/sys/**"/>
		<bean class="interceptor.SysInterceptor"/>
	</mvc:interceptor>
</mvc:interceptors>

SpringMVC3 邮箱发送

添加依赖

<dependency>
	<groupId>javax.mail</groupId>
	<artifactId>mail</artifactId>
	<version>1.4.7</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context-support</artifactId>
	<version>${spring.version}</version>
</dependency>

创建配置文件

创建 /resources/spring-mail.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.2.xsd">
    <!-- 发送邮件的服务器配置 -->
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.qq.com"/>
        <property name="port" value="465"/>
        <property name="username" value="****@qq.com"/>
        <property name="password" value="****"/>
        <property name="defaultEncoding" value="utf-8"/>
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">true</prop>
                <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
                <prop key="mail.smtp.socketFactory.port">465</prop>
            </props>
        </property>
    </bean>
    <!-- 邮件内容配置 -->
    <bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage">
        <property name="subject" value="[i旅行]请激活您的账户"/>
        <property name="from" value="123456@qq.com"/>
    </bean>
</beans>

创建业务层代码

/service/MailService.java

package service;

public interface MailService {
    /**
     * 发送邮件
     * @param to 收件人
     * @param message 正文
     */
    void send(String to, String message);
}

/service/MailServiceImpl.java

package service;

import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class MailServiceImpl implements MailService {

    @Resource
    private SimpleMailMessage mailMessage;
    @Resource
    private MailSender mailSender;

    @Override
    public void send(String to, String message) {
        mailMessage.setTo(to);
        mailMessage.setText("您的激活码是:" + message);
        mailSender.send(mailMessage);
    }
}

创建控制器层代码

/controller/LoginController.java

package controller;

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

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Controller
public class LoginController {
    @Resource
    private MailService mailService;

    /**
     * 发送邮件
     * @param to 收件人
     * @param message 正文
     * @return
     */
    @RequestMapping(value = "/mail")
    @ResponseBody
    public Object mail(@RequestParam String to,@RequestParam String message){
        Map<String, Object> map = new HashMap<>();
        mailService.send(to,message);
        map.put("to",to);
        map.put("message",message);
        return map;
    }
}

测试

使用 postman 进行测试

SpringMVC4 集成Swagger

Swagger简介

Swagger 是一个Restfull API 文档的在线自动生成工具,可以直接运行,在线测试 API。
Swagger 支持多种语言,比如:JAVA、PHP 等。
官方网站为:https://swagger.io/

环境准备

  1. JDK1.8
  2. Spring4.1.7

集成配置步骤

  1. pom.xml 文件中添加 Swagger2 相关依赖
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.4.0</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.4.0</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>19.0</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${jackson.verson}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.verson}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>${jackson.verson}</version>
</dependency>
  1. 下载配置类
    SwaggerConfig.java

    • @ComponentScan 设置 Swagger 扫描包
    • @EnableSwagger2 使 Swagger2 生效
    • @Configuration 自动在本类上下文加载一些环境变量信息
  2. 配置类 拷贝到 控制器包

  3. spring-mvc.xml 中添加如下代码:

<mvc:default-servlet-handler />
  1. 给控制器类添加API说明

    • 通过在 API 上添加注解实现,API文档的同步效果
    • @Api 表明可供 Swagger 展示的结构类(用在类上面)
    • @ApiOperation 描述 API 方法(用在方法上)
    • @ApiParam 单个参数描述
    • @ApiModel 用对象接收参数(用在 Bean 组件类上)
    • @ApiModelProperty 用对象接收参数是,描述对象属性(用在 Bean 组件类属性上)
  2. 访问 Swagger
    访问 http://IP:prot/{context-path}/swagger-ui.html

Swagger 帮助手册

http://docs.swagger.io/swagger-core/apidocs

SpringMVC4 JSON日期格式化

spring-mvc.xml

<!-- MVC 注解支持 -->
<mvc:annotation-driven>
	<mvc:message-converters>
		<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
			<property name="supportedMediaTypes">
				<list>
					<value>application/json;charset=UTF-8</value>
					<value>text/html;charset=UTF-8</value>
				</list>
			</property>
			<property name="fastJsonConfig">
				<bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
					<property name="dateFormat">
							<value>yyyy-MM-dd</value>
					</property>
				</bean>
			</property>
		</bean>
	</mvc:message-converters>
</mvc:annotation-driven>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值