SpringMVC 框架及部署方式介绍
- Java
- 2020-03-09
- 20热度
- 0评论
Java语言现在应用比较多的MVC框架有SpringMVC,Struts2两种。
首先,什么是MVC?
MVC其实就是一种软件的设计模式。在开发中并没有强制我们必须去遵循这种设计模式,但是遵循MVC模式会使我们系统层次更清晰;职责更明确;扩展性更强;耦合度降低。
一、SpringMVC 概述:
Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的 MVC 框架之一。
• Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架。
• Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。
• 支持 REST 风格的 URL 请求。
• 采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。
SpringMVC工作流程:
Spring MVC 特点:
清晰的角色划分,每一个角色都可以由一个专门的对象来实现:
控制器(controller)
验证器(validator)
命令对象(command object)
表单对象(form object)
模型对象(model object)
Servlet分发器(DispatcherServlet)
处理器映射(handler mapping)
视图解析器(view resolver)等。
可以非常简单的设计出干净的WEB层,和薄薄的WEB层
使用Spring MVC可以更加简洁地开发WEB层
天生与Spring框架集成(IOC、AOP等)
SpringMVC核心组件:
1、DispatcherServlet:前端控制器,核心
作用:接收请求,响应结果,相当于转发器,中央处理器,降低了组件之间的耦合性。
用户发送请求交给DispatcherServlet,DispatcherServlet是整个流程控制的中心,由它调用其他组件处理用户请求,分发到具体的对应Controller,从而获取到需要的业务数据Model,Model再通过DispatcherServlet传递给View完成页面呈现;DispatcherServlet的存在降低了组件的之间的耦合性。
配置DispatcherServlet:

2、HandlerMapping:处理器映射器
作用:根据请求的URL,找到对应的Handler,帮助DispatcherServlet找到对应的Controller。
HandlerMapping负责根据用户请求找到Handler即处理器,SpringMVC提供了多种不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
HandlerMapping执行流程:

3、HandlerInterceptor:Handler执行前后拦截器
HandlerInterceptor是个接口,里面包含三个方法:preHandle、postHandle、afterCompletion
分别在Handler执行前、执行中、执行完成后执行的三个方法
4、HandlerExecutionChain:HandlerMapping返回给DispatcherServlet的执行链
HandlerMapping返回给DispatcherServlet的不光有Handler,还有HandlerInterceptor
preHandle——>ControllerMethod——>postHandle——>afterCompletion
这个链如何实现的呢?使用了Java的反射机制reflection
5、HandlerAdapter:处理器适配器
作用:将各种Controller适配成DispatcherServlet可以使用的Handler,通过特定规则(HandlerAdapter要求的规则)去执行Handler
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
6、Handler:处理器(需要工程师开发)
注意:编写Handler时需要HandlerAdapter的要求去做,这样HandlerAdapter才可以正确执行Handler
Handler是继DispatcherServlet前端控制器的后台控制器,在DispatcherServlet控制下对用户请求进行处理,Handler涉及业务需求,所以需要工程师针对用户需求进行开发,最终返回业务数据
7、ModelAndView:SpringMVC中对Model的一种表示形式
SpringMVC中有Model、Map,但是SpringMVC都会将其转化为ModelAndView,Model、Map都是ModelAndView的具体表现
8、ViewResolver:视图解析器
作用:进行视图解析,根据逻辑视图名解析成真正的视图View
ViewResolver负责将处理结果生成View视图,ViewResolver首先根据逻辑视图名解析成具体的页面地址,然后对View进行渲染,将处理结果通过页面展示给用户;SpringMVC提供了很多类型View视图,包括:jstlView、freemarkerView、pdfView、jsp、html等。
9、View:视图(需要工程师开发jsp、html)
View是一个接口,实现类支持不同的类型(jsp、html、freemarker、pdf等)
SpringMVC三种部署方式:
1.SpringMVC的基本配置
使用SpringMVC开发前需要把meave依赖和Spring所依赖的jar包导进来,idea和ecilpse有所不同,自行百度吧(还可以设置成阿里云的在线依赖库,速度相对比较快些),下面我使用的是ieda

使用IDEA创建一个基于spring的Java项目:
步骤1:选择New Project,在弹出窗口中勾选spring和Web Application(此项也可以不选)。

当勾选Spring选项时,窗口下方的liraries出现load version…进度条,表示在网上检查Spring的可用版本。等待一定时间后,会显示最新可用版本,如下所示。

步骤2:选择下一步,此时会自动从互联网下载spring相关的jar包。
创建SpringMVC工程,架构如下:

重要两个配置文件为: web.xml和springmvc-config.xml。打开web.xml文件,文件配置如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>SpringMVC Demo</display-name>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspf</url-pattern>
<page-encoding>UTF-8</page-encoding>
<scripting-invalid>true</scripting-invalid>
<include-prelude>/WEB-INF/jsp/base.jspf</include-prelude>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
<default-content-type>text/html</default-content-type>
</jsp-property-group>
</jsp-config>
<!--过滤器配置 -->
<!--编码过滤器-->
<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>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Spring MVC配置-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化参数,读取spring mvc的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 将所有的url访问请求配置由springmvc处理 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
打开springmvc-config.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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描指定的包-->
<context:component-scan base-package="jee.course.ch10.*" />
<!-- 配置springmvc支持注解 -->
<mvc:annotation-driven>
<!--解决@ResponseBody返回的字符出现乱码问题-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 配置静态资源不用经过springmv的解析 -->
<!-- **表示该文件夹及其子文件夹所有文件-->
<mvc:resources location="/resource/" mapping="/resource/**"/>
<mvc:resources location="/" mapping="*.html"/>
<!-- 配置默认jsp页面的地址 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
步骤1:在controller包中添加HelloWorldController类,该类为Spring MVC控制器类,主要参考代码如下:
package jee.course.ch10.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
@Controller
public class HelloWorldController {
//返还字符串,类似servlet的out。println()
//演示一个简单的spring MVC应用,返回字符串
@ResponseBody
@RequestMapping(value="/hello")
public String hello(){
return "hello";
}
//演示返回一个jsp页面传递数据
@RequestMapping("/viewJsp")
public String viewJsp(Model model){
model.addAttribute("value","i am from springmvc value");
return "hello";
}
//演示使用session传递参数
@RequestMapping("/session")
public String useSession(HttpSession session){
session.setAttribute("msg","我是使用session使用session传递参数");
return "session";
}
}
JSP页面结构如下:

(1)测试/hello路径的访问,
return “hello”; 表示在页面中输出一个字符串hello,重点在于理解@ResponseBody,该注解表示返回一个字符串,而不是返回一个HTML页面。看函数注解。测试如下:

(2)测试http://localhost:8080/springmvc1/viewJsp, 重点理解@RequestMapping("/viewJsp")的使用,return "hello";表示跳转到hello.jsp页面。同时
public String viewJsp(Model model) 表示将model传入到控制器。其中Model为spring内置类。
model.addAttribute("value", "I am from SpringMvc Value");
表示往该页面传递一个参数,名称为value。
在hello.jsp页面中输出从控制器传递过来的参数。hello.jsp代码如下:

程序测试结果如下:

(3)测试http://localhost:8080/springmvc1/session。该方法和上一个相似,把值通过session传递到jsp页面。
同时将session作为参数传入到控制。
public String useSession(HttpSession session)
测试结果如下:

2.基于Spring MVC获取请求参数:
book.java
package jee.course.ch10.entity;
public class Book {
String bookname;
String author;
double price;
int category;
String description;
String press;
public Book() {
}
@Override
public String toString() {
return "Book{" +
"bookname='" + bookname + '\'' +
", author='" + author + '\'' +
", price=" + price +
", category=" + category +
", description='" + description + '\'' +
", press='" + press + '\'' +
'}';
}
/**
* 构造函数:@param bookname
* 构造函数:@param author
* 构造函数:@param price
* 构造函数:@param category
* 构造函数:@param picUrl
* 构造函数:@param description
* 构造函数:@param press
*/
public Book(String bookname, String author, double price, int category,
String description, String press) {
super();
this.bookname = bookname;
this.author = author;
this.price = price;
this.category = category;
this.description = description;
this.press = press;
}
public String getBookname() {
return bookname;
}
public void setBookname(String bookname) {
this.bookname = bookname;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getCategory() {
return category;
}
public void setCategory(int category) {
this.category = category;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPress() {
return press;
}
public void setPress(String press) {
this.press = press;
}
}
步骤1:添加BookController控制器类,该类主要演示如何获取客户端传递的参数。BookController的参考代码如下:
package jee.course.ch10.controller;
import jee.course.ch10.entity.Book;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/book")
public class BookController {
//跳转到addbook.jsp
//限制HTTP的请求类型为get
@RequestMapping(value = "/add",method = RequestMethod.GET)
public String toBookForm(){
return "addBook";
}
//演示使用pojo实体类自动填充表单数据
//使用model传值
@RequestMapping(value = "/add",method = RequestMethod.POST)
public String addBook(Book book,Model model){
System.out.println(book);
model.addAttribute("book",book);
return "viewBook";
}
//演示url传递参数
//查看ID为10的图书/book/10
@RequestMapping(value = "/{id}",produces = "text/html;charset=UTF-8")
@ResponseBody
public String getBook(@PathVariable("id") Long id){
return "您目前查看的图书ID为:"+id;
}
//演示使用@RequParam获取参数
@RequestMapping("/view")
@ResponseBody
public String viewBook(@RequestParam("id") Long id){
return "您查看的图书ID为"+id;
}
//演示重定向到我另外一个控制器
@RequestMapping(value = "toHello")
public String toHelloController(){
return "redirect:/hello";
}
}
(1)测试http://localhost:8080/springmvc1/book/add。跳转到添加图书界面。
相应的代码为:


(2)点击添加图书,后台对应的代码为:

同时跳转到viewBook.jsp页面,viewBook.jsp代码为:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>图书信息</title>
</head>
<body>
<h1>图书添加成功!</h1>
<br>
<h2>图书信息</h2>
<hr>
图书名称: ${book.bookname}
<br> 图书价格: ${book.price}
<br> 出版社: ${book.press}
<br> 类别: ${book.category}
<br>
</body>
</html>
页面结果如下:

(3)测试通过@RequestParam获取客户端提交的参数。
http://localhost:8080/springmvc1/book/view?id=100


(4)测试通过@PathVariable获取路径参数。代码为:


(5)测试重定向到另一个控制器。
说明:默认情况下控制器方法返回一个字符串值,表示返回的视图为一个jsp页面。如果要从一个控制器跳转到另一个控制器,可以使用下面方法:
在控制器的return语句字符串前面添加forward:或者redirect:。 其中forward:表示可以带数据的跳转,和request的forward相同,使用redirect:表示重定向。
return "forward:aaaa/bbbb.do";
return "redirect:aaaa/bbbb.do";
访问地址:http://localhost:8080/springmvc1/book/toHello
代码如下:

测试结果如下:

3.Spring MVC和Ajax的结合使用
步骤1:ajax.html页面代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>test</div>
<div>
<h3>1.演示获取JSON格式的数据对象</h3>
<button type="button" id="jsonData" onclick="getJsonBook()">
获取JSON格式的数据对象
</button>
</div>
<hr>
<div>
<h3>2.演示获取JSON格式的数据对象</h3>
<button type="button" id="delTicket" onclick="delMultiTickets()">
使用Ajax方式删除多个票据
</button>
</div>
<h2>3.演示使用Ajax提交图书数据</h2>
<hr>
<div>
<table>
<form id="bookForm" method="POST">
<tr>
<td>图书名称:</td>
<td><input type="text" name="bookname" value="三毛流浪记"></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="text" name="price" value="39.50"></td>
</tr>
<tr>
<td>作者:</td>
<td><input type="text" name="author" value="张乐平"></td>
</tr>
<tr>
<td>类别:</td>
<td><select name="category">
<option value="1" selected>文学</option>
<option value="2">计算机</option>
<option value="3">天文</option>
<option value="4">户外探险</option>
</select>
</tr>
<tr>
<td>出版社:</td>
<td><input type="text" name="press" value="译林出版社"></td>
</tr>
</form>
<tr>
<td colspan="2">
<button id="#addBook" onclick="addBook()">添加 </button>
</td>
</tr>
</table>
</div>
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="./resource/static/assets/jquery/jquery-2.1.4.min.js"></script>
<!-- Bootstrap 核心 JavaScript 文件 -->
<script src="./resource/static/assets/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- 站点 自定义 函数库,主要用到serializeObject方法-->
<script src="./resource/static/js/site.js"></script>
<!-- 页面 自定义 JS -->
<script>
//删除多个票据记录
function delMultiTickets() {
alert("test");
//需要删除的票据id号
var idList = [1, 2, 3];
$.ajax({
method: 'POST', //提交的方法为POST
url: './delTickets', //介绍数据URL路径
data: JSON.stringify(idList), //转换为字符串
contentType: 'application/json',
success: function (result) { //成功后的方法
alert("ajax请求成功,服务器返回消息为:" + result)
},
error: function () { // ajax请求失败
alert("ajax请求执行失败!");
}
})
}
//添加图书
function addBook() {
//获取表单数据并序列化为JSON对象
var formData = $("#bookForm").serializeObject();
alert("表单数据:" + formData);
//提交表单
$.ajax({
method: 'POST', //提交的方法为POST
url: './ajaxAddBook', //介绍数据URL路径
//以字符串格式提交数据
data: JSON.stringify(formData), //转换
//使用同步方式提交表单,获取结果后再去执行其他代码。
// POST方法默认使用异步方式提交表单
async: false,
contentType: 'application/json',
success: function (result) { //成功后的方法
alert("ajax请求成功,返回消息:" + result)
},
error: function () { // ajax请求失败
alert("ajax请求执行失败!");
}
})
}
//获取图书对象的JSON格式数据
function getJsonBook() {
$.ajax({
method: 'GET', //提交的方法为POST
url: './json_book', //介绍数据URL路径
success: function (result) { //成功后的方法
//将对象转换为字符串输出
alert("图书格式为:" + JSON.stringify(result))
},
error: function () { // ajax请求失败
alert("ajax请求执行失败!");
}
})
}
</script>
</body>
</html>
运行界面如下

后台代码AjaxParamsController如下:
package jee.course.ch10.controller;
import jee.course.ch10.entity.Book;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
//用于演示与ajax提交数据的交互
@Controller
public class AjaxParamsController {
//1.演示使用@RequestBody读取Ajax提交的JSON格式的数据
//说明:读取Ajax发送过来的数组对象并转换为List<Long>对象
@ResponseBody
@RequestMapping(value = "/delTickets", method = RequestMethod.POST)
public String delMultiTickets(@RequestBody List<Long> idList){
//打印输出要删除id
System.out.println("接收到Ajax请求.");
StringBuffer sb = new StringBuffer();
for (Long id: idList) {
sb.append(id+",");
}
String resMsg = "##成功删除的票据id为:"+sb.toString();
return resMsg;
}
//2.演示使用@RequestBody读取Ajax表单提交的JSON格式数据
//说明:读取Ajax发送过来的数组对象并转换为Book类型
@ResponseBody
@RequestMapping(value = "/ajaxAddBook", method = RequestMethod.POST)
public String ajaxAddBook(@RequestBody Book book){
//打印输出要删除id
System.out.println("接收到Ajax请求.");
System.out.println("添加的图书:" + book);
String resMsg = "操作成功:"+book.toString();
return resMsg;
}
@RequestMapping(value = "/json_book", method = RequestMethod.GET)
@ResponseBody
public Book getJsonBook(){
Book book = new Book();
book.setAuthor("金庸");
book.setBookname("笑傲江湖");
book.setPress("广东文学出版社");
book.setPrice(90.5);
return book;
}
}
发送表单数据:



鲁ICP备19063141号
鲁公网安备 37010302000824号