三 后台环境搭建
9. 表述层配置
分支: git checkout -b 3.9.0_web
9.1 目标
-
handler 中装配 Service
-
页面能够访问到 handler
-
页面 -> hander (@RequestMapping) -> Service -> Mapper -> 数据库
9.2 思路 web.xml 和 Spring 配置文件关系
- 图 9-1 各个配置文件的关系
IOC: ApplicationContext
9.3 web.xml 配置
- Ctrl + Shift + Alt + S 打开项目配置
- Apply
<?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_4_0.xsd"
version="4.0">
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-persist-*.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>CharacterEncodingFilter</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>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<!-- 强制响应设置字符集 -->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 这个 Filter 执行的顺序要在所有其他 filter 前面 -->
<!-- 原因如下: -->
<!-- request.setCharacterEncoding(encoding); 必须在 request.getParameter() 前面 -->
<!-- response.setCharacterEncoding(encoding); 必须在 response.getWriter() 前面 -->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web-mvc.xml</param-value>
</init-param>
<!-- Servlet 默认生命周期中, 创建对象是在第一次接收到请求时 -->
<!-- 而 DispatcherServlet 创建对象后有大量的 "框架初始化" 工作, 不适合在第一次请求时来做 -->
<!-- 设置 load-on-startup 就是为了 DispatcherServlet 在 Web 应用启动时创建对象初始化 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<!-- url-pattern 配置方式一: / 表示拦截所有请求 -->
<!-- <url-pattern>/</url-pattern> -->
<!-- url-pattern 配置方式二: 配置请求扩展名-->
<!-- 优点1: 静态资源完全不需要经过 SpringMVC, 不需要拦截 -->
<!-- 优点2: 可以实现伪静态效果。表面上看起来是访问一个 HTML 文件这样的静态资源, 但是实际上是经过 Java 代码运算的结果 -->
<!-- 伪静态作用1: 给黑客入侵增加难度 -->
<!-- 伪静态作用2: 有利于 SEO 优化 (让百度、谷歌这样的搜索引擎更容易找到我们项目) -->
<!-- 缺点: 不符合 RESTFul 风格 -->
<url-pattern>*.html</url-pattern>
<!-- 为什么要另外再配置 json 扩展名呢? -->
<!-- 如果一个 Ajax 请求扩展名是 HTML, 但是实际服务器给浏览器返回的是 JSON 数据, 二者就不匹配了, 会出现406错误 -->
<!-- 为了让 Ajax 请求能够顺利拿到 JSON 格式数据, 我们另外配置 JSON 扩展名 -->
<url-pattern>*.json</url-pattern>
</servlet-mapping>
</web-app>
9.3.1 配置 ContextLoaderListener
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-persist-*.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
9.3.2 配置 CharacterEncodingFilter
<filter>
<filter-name>CharacterEncodingFilter</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>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<!-- 强制响应设置字符集 -->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 这个 Filter 执行的顺序要在所有其他 filter 前面 -->
<!-- 原因如下: -->
<!-- request.setCharacterEncoding(encoding); 必须在 request.setParameter() 前面 -->
<!-- response.setCharacterEncoding(encoding); 必须在 response.getWriter() 前面 -->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
9.3.3 配置 DispatcherServlet
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web-mvc.xml</param-value>
</init-param>
<!-- Servlet 默认生命周期中, 创建对象是在第一次接收到请求时 -->
<!-- 而 DispatcherServlet 创建对象后有大量的 "框架初始化" 工作, 不适合在第一次请求时来做 -->
<!-- 设置 load-on-startup 就是为了 DispatcherServlet 在 Web 应用启动时创建对象初始化 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<!-- url-pattern 配置方式一: / 表示拦截所有请求 -->
<!-- <url-pattern>/</url-pattern> -->
<!-- url-pattern 配置方式二: 配置请求扩展名-->
<!-- 优点1: 静态资源完全不需要经过 SpringMVC, 不需要拦截 -->
<!-- 优点2: 可以实现伪静态效果。表面上看起来是访问一个 HTML 文件这样的静态资源, 但是实际上是经过 Java 代码运算的结果 -->
<!-- 伪静态作用1: 给黑客入侵增加难度 -->
<!-- 伪静态作用2: 有利于 SEO 优化 (让百度、谷歌这样的搜索引擎更容易找到我们项目) -->
<!-- 缺点: 不符合 RESTFul 风格 -->
<url-pattern>*.html</url-pattern>
<!-- 为什么要另外再配置 json 扩展名呢? -->
<!-- 如果一个 Ajax 请求扩展名是 HTML, 但是实际服务器给浏览器返回的是 JSON 数据, 二者就不匹配了, 会出现406错误 -->
<!-- 为了让 Ajax 请求能够顺利拿到 JSON 格式数据, 我们另外配置 JSON 扩展名 -->
<url-pattern>*.json</url-pattern>
</servlet-mapping>
9.3.4 创建 spring-web-mvc.xml
- atcrowdfunding02-admin-webui > resources
9.4 配置 spring-web-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.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
">
<!-- 配置自动扫描的包: 扫描 handler -->
<context:component-scan base-package="com.atguigu.crowd.mvc"/>
<!-- 配置 SpringMVC 的注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
9.4.1 创建包
-
config
-
handler
-
interceptor
9.5 测试 SSM 整合环境
9.5.1 创建 index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/test/ssm.html">测试 SMM 配置环境</a>
</body>
</html>
9.5.2 导入依赖
<!-- 引入 Servlet 容器中相关依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- JSP 页面使用的依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 引入 Servlet 容器中相关依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
9.5.3 创建 TestHandler
package com.atguigu.crowd.mvc.handler;
import com.atguigu.crowd.entity.Admin;
import com.atguigu.crowd.service.api.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class TestHandler {
@Autowired
private AdminService adminService;
@RequestMapping("/test/ssm.html")
public String testSsm(ModelMap modelMap) {
List<Admin> adminList = adminService.getAll();
modelMap.addAttribute("adminList", adminList);
return "target";
}
}
- getAll - AdminService
package com.atguigu.crowd.service.api;
import com.atguigu.crowd.entity.Admin;
import java.util.List;
public interface AdminService {
void saveAdmin(Admin admin);
List<Admin> getAll();
}
- getAll - AdminServiceImpl
package com.atguigu.crowd.service.impl;
import com.atguigu.crowd.entity.Admin;
import com.atguigu.crowd.entity.AdminExample;
import com.atguigu.crowd.mapper.AdminMapper;
import com.atguigu.crowd.service.api.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
private AdminMapper adminMapper;
@Override
public void saveAdmin(Admin admin) {
adminMapper.insert(admin);
throw new RuntimeException();
}
@Override
public List<Admin> getAll() {
return adminMapper.selectByExample(new AdminExample());
}
}
9.5.4 创建 target.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success</h1>
${requestScope.adminList}
</body>
</html>
9.5.5 创建 tomcat 并运行
-
打开项目设置
Ctrl + Shilf + Alt + S
-
- 点击
Create Artifact
- 点击
- 选中所有右键
put into Output Root
-
Apply
-
Ctrl + Shelf + A
-
- 搜索
Edit Con
- 搜索
- 创建 Tomcat Service
- 选择 Tomcat
- 设置 VM:
-Dfile.encoding=utf-8
- 添加项目
- Apply
Alt + 8
打开 Services- 启动项目
- 启动报错, 权限问题
error=13, Permission denied
进入到tomcat的bin目录下,执行命令
chmod a+x catalina.sh
- 编码问题
- VM 设置后重启生效
9.6 base 标签
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<base href="http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
</head>
<body>
<%--<a href="${pageContext.request.contextPath}/test/ssm.html">测试 SMM 配置环境</a>--%>
<a href="test/ssm.html">测试 SMM 配置环境</a>
</body>
</html>
9.6.1 注意的点
- 端口号前面的冒号不能省略
- contextPath 前面不能写 /
- contextPath 后面必须写 /
- 页面上所有参照 base 标签对的标签都必须放在 base 标签后面
- 页面上所有参照 base 标签的标签的路径都不能以 / 开头
9.7 AJAX
9.7.1 建立意识
9.7.2 常用注解
- @ResponseBody 和 @RequestBody 想要正常工作必须有 Jackson 的支持, 请确认当前环境引入了如下依赖 ( 已引入 )
<!-- Spring 进行 JSON 数据转换依赖 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
- 同时必须配置了 mvc:annotation-driven
9.7.3 @RequestBody 注解的使用
- 引入 Jquery 2.1.1📎jquery-2.1.1.min.js
- web > jquery
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<base href="http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
<script type="text/javascript" src="jquery/jquery-2.1.1.min.js"></script>
</head>
<body>
<%--<a href="${pageContext.request.contextPath}/test/ssm.html">测试 SMM 配置环境</a>--%>
<a href="test/ssm.html">测试 SMM 配置环境</a>
</body>
</html>
9.7.4 Ajax 发送数组 - 方案一
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<base href="http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
<script type="text/javascript" src="jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
$(function () {
$("#btn1").click(function () {
$.ajax({
url: "send/array", // 请求目标资源的地址
type: "post", // 请求方式
data: {
array: [5, 8, 12]
}, // 要发送的请求参数
dataType: "text", // 如何对待服务器返回的数据
success: function (response) { // 服务器端成功处理请求后调用的回调函数, response 是响应体数据
alert(response);
},
error: function () { // 服务器端处理请求失败后调用的回调函数
}
})
});
})
</script>
</head>
<body>
<%--<a href="${pageContext.request.contextPath}/test/ssm.html">测试 SMM 配置环境</a>--%>
<a href="test/ssm.html">测试 SMM 配置环境</a>
<br/>
<button id="btn1">Send [5, 8, 12] One</button>
</body>
</html>
- TestHandler.java
@ResponseBody
@RequestMapping("/send/array.html")
public String testReceiveArrayOne(@RequestParam("array[]") List<Integer> list) {
list.forEach(System.out::println);
return "success";
}
- 缺陷: handler 方法中接收数据时需要在请求参数名字后面多谢一组 []
9.7.4 Ajax 发送数组 - 方案二
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<base href="http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
<script type="text/javascript" src="jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
$(function () {
$("#btn1").click(function () {
$.ajax({
url: "send/array.html", // 请求目标资源的地址
type: "post", // 请求方式
data: {
array: [5, 8, 12]
}, // 要发送的请求参数
dataType: "text", // 如何对待服务器返回的数据
success: function (response) { // 服务器端成功处理请求后调用的回调函数, response 是响应体数据
alert(response);
},
error: function () { // 服务器端处理请求失败后调用的回调函数
}
})
});
$("#btn2").click(function () {
$.ajax({
url: "send/array/two.html", // 请求目标资源的地址
type: "post", // 请求方式
data: {
"array[0]": 5,
"array[1]": 8,
"array[2]": 12,
}, // 要发送的请求参数
dataType: "text", // 如何对待服务器返回的数据
success: function (response) { // 服务器端成功处理请求后调用的回调函数, response 是响应体数据
alert(response);
},
error: function () { // 服务器端处理请求失败后调用的回调函数
}
})
});
})
</script>
</head>
<body>
<%--<a href="${pageContext.request.contextPath}/test/ssm.html">测试 SMM 配置环境</a>--%>
<a href="test/ssm.html">测试 SMM 配置环境</a>
<br/>
<br/>
<button id="btn1">Send [5, 8, 12] One</button>
<br/>
<br/>
<button id="btn2">Send [5, 8, 12] One</button>
</body>
</html>
- TestHandler.java
package com.atguigu.crowd.mvc.handler;
import com.atguigu.crowd.entity.Admin;
import com.atguigu.crowd.entity.ParamData;
import com.atguigu.crowd.service.api.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class TestHandler {
@Autowired
private AdminService adminService;
@ResponseBody
@RequestMapping("/send/array/two.html")
public String testReceiveArrayTwo(ParamData paramData) {
List<Integer> list = paramData.getArray();
list.forEach(System.out::println);
return "success";
}
@ResponseBody
@RequestMapping("/send/array.html")
public String testReceiveArrayOne(@RequestParam("array[]") List<Integer> list) {
list.forEach(System.out::println);
return "success";
}
@RequestMapping("/test/ssm.html")
public String testSsm(ModelMap modelMap) {
List<Admin> adminList = adminService.getAll();
System.out.println(adminList);
modelMap.addAttribute("adminList", adminList);
modelMap.addAttribute("adminList2", adminList);
modelMap.addAttribute("adminList4", adminList);
return "/target";
}
}
- ParamData
package com.atguigu.crowd.entity;
import java.util.List;
public class ParamData {
private List<Integer> array;
public ParamData() {
}
public ParamData(List<Integer> array) {
this.array = array;
}
public List<Integer> getArray() {
return array;
}
public void setArray(List<Integer> array) {
this.array = array;
}
@Override
public String toString() {
return "ParamData{" +
"array=" + array +
'}';
}
}
9.7.5 Ajax 发送数组 - 方案三
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<base href="http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
<script type="text/javascript" src="jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
$(function () {
$("#btn1").click(function () {
$.ajax({
url: "send/array.html", // 请求目标资源的地址
type: "post", // 请求方式
data: {
array: [5, 8, 12]
}, // 要发送的请求参数
dataType: "text", // 如何对待服务器返回的数据
success: function (response) { // 服务器端成功处理请求后调用的回调函数, response 是响应体数据
alert(response);
},
error: function () { // 服务器端处理请求失败后调用的回调函数
}
})
});
$("#btn2").click(function () {
$.ajax({
url: "send/array/two.html", // 请求目标资源的地址
type: "post", // 请求方式
data: {
"array[0]": 5,
"array[1]": 8,
"array[2]": 12,
}, // 要发送的请求参数
dataType: "text", // 如何对待服务器返回的数据
success: function (response) { // 服务器端成功处理请求后调用的回调函数, response 是响应体数据
alert(response);
},
error: function () { // 服务器端处理请求失败后调用的回调函数
}
})
});
$("#btn3").click(function () {
// 准备好要发送到服务器端的数组
var array = [5, 8, 12];
// 将 JSON 数组转换为 JSON 字符串
var requestBody = JSON.stringify(array);
$.ajax({
url: "send/array/three.html", // 请求目标资源的地址
type: "post", // 请求方式
data: requestBody, // 请求体
contentType: "application/json;charset=UTF-8", // 请求体的内容类型, 告诉服务器本次请求的请求体是 JSON 数据
dataType: "text", // 如何对待服务器返回的数据
success: function (response) { // 服务器端成功处理请求后调用的回调函数, response 是响应体数据
alert(response);
},
error: function () { // 服务器端处理请求失败后调用的回调函数
}
})
});
})
</script>
</head>
<body>
<%--<a href="${pageContext.request.contextPath}/test/ssm.html">测试 SMM 配置环境</a>--%>
<a href="test/ssm.html">测试 SMM 配置环境</a>
<br/>
<br/>
<button id="btn1">Send [5, 8, 12] One</button>
<br/>
<br/>
<button id="btn2">Send [5, 8, 12] One</button>
<br/>
<br/>
<button id="btn3">Send [5, 8, 12] One</button>
</body>
</html>
- TestHandler.java
package com.atguigu.crowd.mvc.handler;
import com.atguigu.crowd.entity.Admin;
import com.atguigu.crowd.entity.ParamData;
import com.atguigu.crowd.service.api.AdminService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class TestHandler {
@Autowired
private AdminService adminService;
@ResponseBody
@RequestMapping("/send/array/three.html")
public String testReceiveArrayThree(@RequestBody List<String> list) {
Logger logger = LoggerFactory.getLogger(TestHandler.class);
list.forEach(logger::info);
return "success";
}
@ResponseBody
@RequestMapping("/send/array/two.html")
public String testReceiveArrayTwo(ParamData paramData) {
List<Integer> list = paramData.getArray();
list.forEach(System.out::println);
return "success";
}
@ResponseBody
@RequestMapping("/send/array.html")
public String testReceiveArrayOne(@RequestParam("array[]") List<Integer> list) {
list.forEach(System.out::println);
return "success";
}
@RequestMapping("/test/ssm.html")
public String testSsm(ModelMap modelMap) {
List<Admin> adminList = adminService.getAll();
System.out.println(adminList);
modelMap.addAttribute("adminList", adminList);
modelMap.addAttribute("adminList2", adminList);
modelMap.addAttribute("adminList4", adminList);
return "/target";
}
}
9.7.6 Ajax 发送复杂对象
- Student 类
package com.atguigu.crowd.entity;
import java.util.List;
import java.util.Map;
public class Student {
private Integer stuId;
private String stuName;
private Address address;
private List<Subject> subjectList;
private Map<String, String> map;
public Student() {
}
public Student(Integer stuId, String stuName, Address address, List<Subject> subjectList, Map<String, String> map) {
this.stuId = stuId;
this.stuName = stuName;
this.address = address;
this.subjectList = subjectList;
this.map = map;
}
public Integer getStuId() {
return stuId;
}
public void setStuId(Integer stuId) {
this.stuId = stuId;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<Subject> getSubjectList() {
return subjectList;
}
public void setSubjectList(List<Subject> subjectList) {
this.subjectList = subjectList;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
@Override
public String toString() {
return "Student{" +
"stuId=" + stuId +
", stuName='" + stuName + '\'' +
", address=" + address +
", subjectList=" + subjectList +
", map=" + map +
'}';
}
}
- Address 类
package com.atguigu.crowd.entity;
public class Address {
private String province;
private String city;
private String street;
public Address() {
}
public Address(String province, String city, String street) {
this.province = province;
this.city = city;
this.street = street;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
", street='" + street + '\'' +
'}';
}
}
- Subject 类
package com.atguigu.crowd.entity;
public class Subject {
private String subjectName;
private Integer subjectScore;
public Subject() {
}
public Subject(String subjectName, Integer subjectScore) {
this.subjectName = subjectName;
this.subjectScore = subjectScore;
}
public String getSubjectName() {
return subjectName;
}
public void setSubjectName(String subjectName) {
this.subjectName = subjectName;
}
public Integer getSubjectScore() {
return subjectScore;
}
public void setSubjectScore(Integer subjectScore) {
this.subjectScore = subjectScore;
}
@Override
public String toString() {
return "Subject{" +
"subjectName='" + subjectName + '\'' +
", subjectScore=" + subjectScore +
'}';
}
}
- TestHandler - testReceiveComposeObject
@ResponseBody
@RequestMapping("/send/compose/object.html")
public String testReceiveComposeObject(@RequestBody Student student) {
Logger logger = LoggerFactory.getLogger(TestHandler.class);
logger.info(student.toString());
return "success";
}
- index - btn4
$("#btn4").click(function () {
// 准备好要发送到服务器端的数组
var student = {
stuId: 5,
stuName: "tom",
address: {
province: "广东",
city: "深圳",
street: "后端"
},
subjectList: [
{
subjectName: "javaSE",
subjectScore: 100
},
{
subjectName: "SSM",
subjectScore: 99
}
],
map: {
k1: "v1",
k2: "v2"
}
}
// 将 JSON 数组转换为 JSON 字符串
var requestBody = JSON.stringify(student);
$.ajax({
url: "send/compose/object.html", // 请求目标资源的地址
type: "post", // 请求方式
data: requestBody, // 请求体
contentType: "application/json;charset=UTF-8", // 请求体的内容类型, 告诉服务器本次请求的请求体是 JSON 数据
dataType: "text", // 如何对待服务器返回的数据
success: function (response) { // 服务器端成功处理请求后调用的回调函数, response 是响应体数据
alert(response);
},
error: function () { // 服务器端处理请求失败后调用的回调函数
}
})
});
9.7.7 对 Ajax 请求返回的结果进行规范
package com.atguigu.crowd.util;
/**
* 统一整个项目中 Ajax 请求返回的结果 (未来也可以用于分布式架构各个模块间调用时返回统一类型)
*
* @param <T>
*/
public class ResultEntity<T> {
public static final String SUCCESS = "SUCCESS";
public static final String FAILED = "FAILED";
// 用来封装当前请求处理的结果是成功还是失败
private String result;
// 请求处理失败时返回的错误消息
private String message;
// 要返回的数据
private T data;
/**
* 请求处理成功且不需要返回数据时使用的工具方法
*
* @param <Type>
* @return
*/
public static <Type> ResultEntity<Type> successWithoutData() {
return new ResultEntity<Type>(SUCCESS, null, null);
}
/**
* 请求处理成功且需要返回数据时使用的工具
*
* @param data 要返回的数据
* @param <Type>
* @return
*/
public static <Type> ResultEntity<Type> successWithData(Type data) {
return new ResultEntity<Type>(SUCCESS, null, data);
}
/**
* 请求处理失败后使用的工具方法
*
* @param message 失败的错误消息
* @param <Type>
* @return
*/
public static <Type> ResultEntity<Type> failed(String message) {
return new ResultEntity<Type>(FAILED, message, null);
}
public ResultEntity() {
}
public ResultEntity(String result, String message, T data) {
this.result = result;
this.message = message;
this.data = data;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "ResultEntity{" +
"result='" + result + '\'' +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
- 测试 TestHandler -
@ResponseBody
@RequestMapping("/send/compose/object2.json")
public ResultEntity<Student> testReceiveComposeObject2(@RequestBody Student student) {
Logger logger = LoggerFactory.getLogger(TestHandler.class);
logger.info(student.toString());
// 将"查询"到的 Student 对象封装到 ResultEntity 中返回
return ResultEntity.successWithData(student);
}
- 测试 index - btn5
$("#btn5").click(function () {
// 准备好要发送到服务器端的数组
var student = {
stuId: 5,
stuName: "tom",
address: {
province: "广东",
city: "深圳",
street: "后端"
},
subjectList: [
{
subjectName: "javaSE",
subjectScore: 100
},
{
subjectName: "SSM",
subjectScore: 99
}
],
map: {
k1: "v1",
k2: "v2"
}
}
// 将 JSON 数组转换为 JSON 字符串
var requestBody = JSON.stringify(student);
$.ajax({
url: "send/compose/object2.json", // 请求目标资源的地址
type: "post", // 请求方式
data: requestBody, // 请求体
contentType: "application/json;charset=UTF-8", // 请求体的内容类型, 告诉服务器本次请求的请求体是 JSON 数据
dataType: "JSON", // 如何对待服务器返回的数据
success: function (response) { // 服务器端成功处理请求后调用的回调函数, response 是响应体数据
alert(response);
},
error: function () { // 服务器端处理请求失败后调用的回调函数
}
})
});