Spring MVC 也叫 Spring Web MVC ,属于展示层框架。SpringMVC 是 Spring 框架的一部分。
Spring Web MVC 框架提供了 MVC (模型 - 视图 - 控制器) 架构和用于开发灵活和松散耦合的 Web 应用程序的组件。 MVC 模式导致应用程序的不同方面(输入逻辑,业务逻辑和 UI 逻辑)分离,同时提供这些元素之间的松散耦合。
Spring Web MVC 框架是围绕 DispatcherServlet 设计的,它处理所有的 HTTP 请求和响应。 Spring Web MVC DispatcherServlet 的请求处理工作流如下图所示:
以下是对应于到 DispatcherServlet 的传入 HTTP 请求的事件顺序:
在pom.xml
配置文件中增加org.springframework:spring-webmvc
依赖
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>4.3.17.RELEASEversion>
dependency>
配置字符集过滤器,用于解决中文编码问题
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
配置 Spring 的 Servlet 分发器处理所有 HTTP 的请求和响应
<servlet>
<servlet-name>springServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath*:/spring-mvc*.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
创建一个名为 spring-mvc.xml
文件来配置 MVC
Spring MVC Configuration
相关配置说明:
配置 | 属性 | 说明 |
---|---|---|
context:property-placeholder |
动态加载属性配置文件以变量的方式引用需要的值 | |
context:component-scan |
当前配置文件为 MVC 相关,故只需要扫描包含 @Controller 的注解即可,由于 spring-context.xml | |
InternalResourceViewResolver |
视图文件解析器的一种,用于配置视图资源的路径和需要解释的视图资源文件类型,这里有两个需要配置的属性prefix(前缀) 以及suffix(后缀) 。 |
|
- | prefix |
配置视图资源路径,如:/WEB-INF/views/ |
- | suffix |
配置视图资源类型,如:.jsp |
mvc:resources |
静态资源映射,主要用于配置静态资源文件存放路径,如:JS、CSS、Image 等 |
在 spring-mvc.xml
中,我们配置了
<context:property-placeholder ignore-unresolvable="true" location="classpath:myshop.properties"/>
用于动态加载属性配置文件,实际开发中我们会将系统所需的一些配置信息封装到 .properties
配置文件中便于统一的管理。
创建一个名为 myshop.properties
的配置文件,内容如下:
#============================#
#==== Framework settings ====#
#============================#
# \u89c6\u56fe\u6587\u4ef6\u5b58\u653e\u8def\u5f84
web.view.prefix=/WEB-INF/views/
web.view.suffix=.jsp
由于spring-mvc.xml
中已经配置了 @Controller`` 注解的扫描而
spring-context.xml 中配置的是扫描全部注解,故在这里需要将
@Controller` 注解的扫描配置排除。
修改 spring-context.xml 配置:
<context:component-scan base-package="com.funtl.my.shop">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
package com.funtl.my.shop.web.controller;
import com.funtl.my.shop.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class LoginController {
@Autowired
private UserService userService;
@RequestMapping(value = {"", "login"}, method = RequestMethod.GET)
public String login() {
return "login";
}
@RequestMapping(value = "login", method = RequestMethod.POST)
public String login(@RequestParam(required = true) String email, @RequestParam(required = true) String password) {
return "redirect:/main";
}
}
在 Spring MVC 中,控制器 Controller 负责处理由DispatcherServlet
分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个 Model ,然后再把该 Model 返回给对应的 View 进行展示。在 Spring MVC 中提供了一个非常简便的定义 Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用 @Controller
标记一个类是 Controller ,然后使用 @RequestMapping
和 @RequestParam
等一些注解用以定义 URL 请求和 Controller 方法之间的映射,这样的 Controller 就能被外界访问到。此外 Controller 不会直接依赖于 HttpServletRequest
和 HttpServletResponse
等 HttpServlet
对象,它们可以通过 Controller 的方法参数灵活的获取到。
@Controller
用于标记在一个类上,使用它标记的类就是一个 Spring MVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping
注解。@Controller
只是定义了一个控制器类,而使用 @RequestMapping
注解的方法才是真正处理请求的处理器。
RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
RequestMapping 注解有六个属性:
属性 | 说明 |
---|---|
value |
指定请求的实际地址,指定的地址可以是 URI Template 模式 |
method |
指定请求的method类型, GET、POST、PUT、DELETE 等 |
consumes |
指定处理请求的提交内容类型(Content-Type),例如 application/json, text/html |
produces |
指定返回的内容类型,仅当 request 请求头中的(Accept)类型中包含该指定类型才返回 |
params |
指定 request 中必须包含某些参数值是,才让该方法处理 |
headers |
指定 request 中必须包含某些指定的 header 值,才能让该方法处理请求 |
Spring Web MVC 的处理器拦截器,类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算 PV(Page View)等
权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面
性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间
通用行为:读取 Cookie 得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取 Locale、Theme 信息等,只要是多个处理器都需要的即可使用拦截器实现
Spring MVC 拦截器需要实现 HandlerInterceptor
接口,该接口定义了 3 个方法,分别为 preHandle()
、postHandle()
和 afterCompletion()
,咱们就是通过重写这 3 个方法来对用户的请求进行拦截处理的。
preHandle
(HttpServletRequest request, HttpServletResponse response, Object handle):
该方法在请求处理之前进行调用
。Spring MVC 中的 Interceptor 是链式调用的,在一个应用中或者说是在一个请求中可以同时存在多个 Interceptor 。每个 Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是 Interceptor 中的 preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求做一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值 Boolean 类型的,当它返回为 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当返回值为 true 时,就会继续调用下一个 Interceptor 的 preHandle 方法,如果已经是最后一个 Interceptor 的时候,就会是调用当前请求的 Controller 中的方法。
postHandle
(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView):通过 preHandle 方法的解释咱们知道这个方法包括后面要说到的 afterCompletion 方法都只能在当前所属的 Interceptor 的 preHandle 方法的返回值为 true 的时候,才能被调用。postHandle 方法在当前请求进行处理之后,也就是在 Controller 中的方法调用之后执行
,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以咱们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。postHandle 方法被调用的方向跟 preHandle 是相反的,也就是说,先声明的 Interceptor 的 postHandle 方法反而会后执行。
afterCompletion
(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex):也是需要当前对应的 Interceptor 的 preHandle 方法的返回值为 true 时才会执行。因此,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行
,这个方法的主要作用是用于进行资源清理的工作。
我们知道对系统的相关操作是需要登录后才可以使用的,当未登录时是无法直接访问需要登录权限的操作的,为了做到这个效果,我们使用登录拦截器来判断用户是否登录,如果用户已登录则放行让用户继续操作,否则就将其跳转到登录页。
定义一个名为 LoginInterceptor
的拦截器,代码如下:
package com.funtl.my.shop.web.interceptor;
import com.funtl.my.shop.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 登录拦截器
* Title: LoginInterceptor
* Description:
*
* @author Lusifer
* @version 1.0.0
* @date 2018/6/12 5:44
*/
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
User user = (User) httpServletRequest.getSession().getAttribute("user");
// 判断用户是否登录
if (user == null) {
// 用户未登录,重定向到登录页
httpServletResponse.sendRedirect("/login");
return false;
}
// 放行
return true;
}
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
// 如果请求来自登录页
if (modelAndView.getViewName().endsWith("login")) {
// 则直接重定向到首页不再显示登录页
httpServletResponse.sendRedirect("/main");
}
}
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
拦截器定义后还需要在spring-mvc.xml
中配置拦截器,代码如下:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/static/**"/>
<mvc:exclude-mapping path="/login"/>
<bean class="com.funtl.my.shop.web.interceptor.LoginInterceptor"/>
mvc:interceptor>
mvc:interceptors>
相关配置说明:
配置 | 属性 | 说明 |
---|---|---|
mvc:interceptor |
定义一个拦截器 | |
- | mvc:mapping |
映射路径,需要拦截的请求路径 |
- | mvc:exclude-mapping |
需要排除的请求路径,比如登录页本身是不需要拦截的,这里还包括了静态资源路径也是不需要拦截的 |
- | bean class |
配置指定的拦截器对象 |
先执行后定义的,排在第一位的最后执行
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/2"/>
<mvc:exclude-mapping path="/static/**"/>
<mvc:exclude-mapping path="/login"/>
<bean class="com.funtl.my.shop.web.interceptor.LoginInterceptor2"/>
mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/1"/>
<mvc:exclude-mapping path="/static/**"/>
<mvc:exclude-mapping path="/login"/>
<bean class="com.funtl.my.shop.web.interceptor.LoginInterceptor1"/>
mvc:interceptor>
mvc:interceptors>
在多人协同开发时,特别是规模较大的项目,为了方便日后的代码维护和管理,我们会将每个开发人员的工作细分到具体的功能和模块上。随着项目的不断扩大,模块也会越来越多,后续会更加难以维护和扩展,为了应对这种情况后期我们还会采用微服务架构的方式进行开发。
以当前教程为例,我们可以将模块划分为如下形式:
创建一个名为my-shop
的工程,`pom.xml 文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.funtlgroupId>
<artifactId>my-shopartifactId>
<version>1.0.0-SNAPSHOTversion>
<packaging>pompackaging>
<modules>
modules>
project>
该项目称之为 Root 项目,主要作用是管理整个工程的全部模块,当有新模块加入时需要在 modules
元素下配置对应的模块目录
创建一个名为 my-shop-dependencies
的项目,pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.funtlgroupId>
<artifactId>my-shopartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../pom.xmlrelativePath>
parent>
<artifactId>my-shop-dependenciesartifactId>
<packaging>pompackaging>
<name>my-shop-dependenciesname>
<description>description>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
<commons-lang3.version>3.5commons-lang3.version>
<jstl.version>1.2jstl.version>
<log4j.version>1.2.17log4j.version>
<servlet-api.version>3.1.0servlet-api.version>
<slf4j.version>1.7.25slf4j.version>
<spring.version>4.3.17.RELEASEspring.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>${servlet-api.version}version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>${jstl.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jcl-over-slf4jartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jul-to-slf4jartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>${commons-lang3.version}version>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.7.0version>
<configuration>
<source>${java.version}source>
<target>${java.version}target>
<encoding>${project.build.sourceEncoding}encoding>
<showWarnings>trueshowWarnings>
configuration>
plugin>
plugins>
<resources>
<resource>
<directory>src/main/javadirectory>
<excludes>
<exclude>**/*.javaexclude>
excludes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
resource>
resources>
build>
project>
PS:别忘记在 my-shop
工程的 pom.xml
中增加 配置
<module>my-shop-dependenciesmodule>
创建一个名为 my-shop-commons
的项目,pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.funtlgroupId>
<artifactId>my-shop-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../my-shop-dependencies/pom.xmlrelativePath>
parent>
<artifactId>my-shop-commonsartifactId>
<packaging>jarpackaging>
<name>my-shop-commonsname>
<description>description>
project>
PS:别忘记在 my-shop
工程的pom.xml
中增加 配置
<module>my-shop-commonsmodule>
创建一个名为my-shop-domain
的项目,pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.funtlgroupId>
<artifactId>my-shop-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../my-shop-dependencies/pom.xmlrelativePath>
parent>
<artifactId>my-shop-domainartifactId>
<packaging>jarpackaging>
<name>my-shop-domainname>
<description>description>
project>
PS:别忘记在 my-shop
工程的 pom.xml
中增加 配置
<module>my-shop-domainmodule>
创建一个名为 my-shop-web-admin
的项目,pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.funtlgroupId>
<artifactId>my-shop-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../my-shop-dependencies/pom.xmlrelativePath>
parent>
<artifactId>my-shop-web-adminartifactId>
<packaging>warpackaging>
<name>my-shop-web-adminname>
<description>description>
<dependencies>
<dependency>
<groupId>com.funtlgroupId>
<artifactId>my-shop-commonsartifactId>
<version>${project.parent.version}version>
dependency>
<dependency>
<groupId>com.funtlgroupId>
<artifactId>my-shop-domainartifactId>
<version>${project.parent.version}version>
dependency>
dependencies>
project>
PS:别忘记在my-shop
工程的pom.xml
中增加 配置
<module>my-shop-web-adminmodule>
创建一个名为 my-shop-web-ui
的项目,pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.funtlgroupId>
<artifactId>my-shop-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../my-shop-dependencies/pom.xmlrelativePath>
parent>
<artifactId>my-shop-web-uiartifactId>
<packaging>warpackaging>
<name>my-shop-web-uiname>
<description>description>
<dependencies>
<dependency>
<groupId>com.funtlgroupId>
<artifactId>my-shop-commonsartifactId>
<version>${project.parent.version}version>
dependency>
dependencies>
project>
PS:别忘记在 my-shop
工程的 pom.xml
中增加配置
<module>my-shop-web-uimodule>
创建一个名为 my-shop-web-api
的项目,pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>com.funtlgroupId>
<artifactId>my-shop-dependenciesartifactId>
<version>1.0.0-SNAPSHOTversion>
<relativePath>../my-shop-dependencies/pom.xmlrelativePath>
parent>
<artifactId>my-shop-web-apiartifactId>
<packaging>warpackaging>
<name>my-shop-web-apiname>
<description>description>
<dependencies>
<dependency>
<groupId>com.funtlgroupId>
<artifactId>my-shop-commonsartifactId>
<version>${project.parent.version}version>
dependency>
dependencies>
project>
PS:别忘记在 my-shop
工程的 pom.xml
中增加 配置
<module>my-shop-web-apimodule>
至此一个完整的模块化工程创建完毕,此时的 Root 工程pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.funtlgroupId>
<artifactId>my-shopartifactId>
<version>1.0.0-SNAPSHOTversion>
<packaging>pompackaging>
<modules>
<module>my-shop-dependenciesmodule>
<module>my-shop-commonsmodule>
<module>my-shop-domainmodule>
<module>my-shop-web-adminmodule>
<module>my-shop-web-uimodule>
<module>my-shop-web-apimodule>
modules>
project>
我们可以在 Root 工程中使用 Maven 提供的mvn clean
命令测试一下效果,控制台输出如下:
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] my-shop
[INFO] my-shop-dependencies
[INFO] my-shop-commons
[INFO] my-shop-domain
[INFO] my-shop-web-admin
[INFO] my-shop-web-ui
[INFO] my-shop-web-api
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building my-shop 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ my-shop ---
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building my-shop-dependencies 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ my-shop-dependencies ---
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building my-shop-commons 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ my-shop-commons ---
[INFO] Deleting D:\Workspace\my-shop\my-shop-commons\target
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building my-shop-domain 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ my-shop-domain ---
[INFO] Deleting D:\Workspace\my-shop\my-shop-domain\target
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building my-shop-web-admin 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ my-shop-web-admin ---
[INFO] Deleting D:\Workspace\my-shop\my-shop-web-admin\target
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building my-shop-web-ui 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ my-shop-web-ui ---
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building my-shop-web-api 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ my-shop-web-api ---
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] my-shop ............................................ SUCCESS [ 0.158 s]
[INFO] my-shop-dependencies ............................... SUCCESS [ 0.004 s]
[INFO] my-shop-commons .................................... SUCCESS [ 0.020 s]
[INFO] my-shop-domain ..................................... SUCCESS [ 0.016 s]
[INFO] my-shop-web-admin .................................. SUCCESS [ 0.033 s]
[INFO] my-shop-web-ui ..................................... SUCCESS [ 0.012 s]
[INFO] my-shop-web-api .................................... SUCCESS [ 0.008 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.400 s
[INFO] Finished at: 2018-06-12T07:47:58+08:00
[INFO] Final Memory: 8M/241M
[INFO] ------------------------------------------------------------------------
在使用 SpringMVC 的时候我们可以使用 Spring 封装的一系列表单标签,这些标签都可以访问到 ModelMap
中的内容。我们需要先在 JSP 中声明使用的标签,具体做法是在 JSP 文件的顶部加入以下指令:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
使用 Spring MVC 的 form
标签主要有两个作用,第一是它会自动的绑定来自 Model 中的一个属性值到当前form
对应的实体对象,默认是 command
属性,这样我们就可以在 form
表单体里面方便的使用该对象的属性了。第二是它支持我们在提交表单的时候使用除 GET 和 POST 之外的其他方法进行提交,包括 DELETE 和 PUT 等。
<form:form action="formTag/form.do" method="post">
<table>
<tr>
<td>Name:td><td><form:input path="name"/>td>
tr>
<tr>
<td>Age:td><td><form:input path="age"/>td>
tr>
<tr>
<td colspan="2"><input type="submit" value="提交"/>td>
tr>
table>
form:form>
可以通过在form中填加modelAttribute
属性指定Java对象,
<form:form modelAttribute="tbUser">
标签会从model中modelAttribute属性对应的键名来获取Java对象,如
/**
* 用户表单
*
* @param tbUser
* @return
*/
@Override
@RequestMapping(value = "form", method = RequestMethod.GET)
public String form(Model model) {
model.addAttribute("tbUser", new TbUser());
return "user_form";
}
如果使用了对象传参,spring会自动讲对象名首字母小写作为键名存如model中,无需传值
/**
* 新增/编辑用户
*
* @param tbUser
* @return
*/
@Override
@RequestMapping(value = "save", method = RequestMethod.GET)
public String form(TbUser tbUser,Model model) {
return "user_form";
}
使用
标签来渲染一个 HTML 文本框,等同于:
<input id="name" name="name" type="text" value=""/>
使用
标签来渲染一个 HTML 密码框,等同于:
<input id="password" name="password" type="password" value=""/>
使用
标签来渲染一个 HTML 文本域,等同于:
<textarea id="address" name="address" rows="5" cols="30">
使用
标签来渲染一个 HTML 复选框,等同于:
<input id="receivePaper1" name="receivePaper" type="checkbox" value="true"/>
<input type="hidden" name="_receivePaper" value="on"/>
使用
标签来渲染一个 HTML 多选复选框,等同于:
<span>
<input id="favoriteFrameworks1" name="favoriteFrameworks" type="checkbox" value="Spring MVC" checked="checked"/>
<label for="favoriteFrameworks1">Spring MVClabel>
span>
<span>
<input id="favoriteFrameworks2" name="favoriteFrameworks" type="checkbox" value="Struts 1"/>
<label for="favoriteFrameworks2">Struts 1label>
span>
<span>
<input id="favoriteFrameworks3" name="favoriteFrameworks" type="checkbox" value="Struts 2" checked="checked"/>
<label for="favoriteFrameworks3">Struts 2label>
span>
<span>
<input id="favoriteFrameworks4" name="favoriteFrameworks" type="checkbox" value="Apache Wicket"/>
<label for="favoriteFrameworks4">Apache Wicketlabel>
span>
<input type="hidden" name="_favoriteFrameworks" value="on"/>
使用
标签来渲染一个 HTML 单选按钮,等同于:
<form:radiobutton path="gender" value="M" label="男" />
<form:radiobutton path="gender" value="F" label="女" />
<input id="gender1" name="gender" type="radio" value="M" checked="checked"/><label for="gender1">男label>
<input id="gender2" name="gender" type="radio" value="F"/><label for="gender2">女label>
使用
标签来渲染一个 HTML 多项单选按钮,等同于:
<span>
<input id="favoriteNumber1" name="favoriteNumber" type="radio" value="1"/>
<label for="favoriteNumber1">1label>
span>
<span>
<input id="favoriteNumber2" name="favoriteNumber" type="radio" value="2"/>
<label for="favoriteNumber2">2label>
span>
<span>
<input id="favoriteNumber3" name="favoriteNumber" type="radio" value="3"/>
<label for="favoriteNumber3">3label>
span>
<span>
<input id="favoriteNumber4" name="favoriteNumber" type="radio" value="4"/>
<label for="favoriteNumber4">4label>
span>
使用
,
,
标签来渲染一个 HTML 下拉列表,等同于:
<form:select path="country">
<form:option value="NONE" label="Select"/>
<form:options items="${countryList}" />
form:select>
<select id="country" name="country">
<option value="NONE">请选择...option>
<option value="US">United Statesoption>
<option value="CH">Chinaoption>
<option value="MY">Malaysiaoption>
<option value="SG">Singaporeoption>
select>
使用
标签及其属性 multiple=true
来渲染一个 HTML 多选下拉列表,等同于:
<form:select path="skills" items="${skillsList}" multiple="true" />
<select id="skills" name="skills" multiple="multiple">
<option value="Struts">Strutsoption>
<option value="Hibernate">Hibernateoption>
<option value="Apache Wicket">Apache Hadoopoption>
<option value="Spring">Springoption>
select>
<input type="hidden" name="_skills" value="1"/>
使用
标签来渲染一个 HTML 隐藏字段域,等同于:
<input id="id" name="id" type="hidden" value="1000"/>
@ModelAttribute
具有如下三个作用:
暴露表单引用对象为模型数据的例子
@ModelAttribute
public User get(@RequestParam(required = false) String id) {
User entity = null;
if (StringUtils.isNotBlank(id)) {
entity = userService.get(id);
}
if (entity == null) {
entity = new User();
}
return entity;
}
@ResponseBody
注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping
后,返回值通常解析为跳转路径,加上 @ResponseBody
后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。
该注解用于将Controller
的方法返回的对象,通过适当的HttpMessageConverter
转换为指定格式后,写入到 Response
对象的 body
数据区。
返回的数据不是 html 标签的页面,而是其他某种格式的数据时(如json、xml等)使用
如果需要返回自定义对象为 JSON 数据类型,需要增加jackson
依赖,pom.xml
配置文件如下:
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.5version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.5version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>${jackson.version}version>
dependency>