SpringMVC 操作Ajax使用学习笔记整理;

SpringMVC 操作Ajax 学习: 纯异步 增删改查+分页;

Ajax

Ajax 其实之前,学习JS 时候了解过~ 也在 OneNote 上整理了笔记:
因此 这里可能会有一些跳跃~ (我又太懒了…最近每天抽出两小时开始减肥~~笔记就有点松懈了…)
如果 有疑惑可以click. 这里下载本人以前对Ajax的学习资源~;


在对Ajax 有了一定基础的之后,应该也都知道JSON
本次讲解主要也是依赖于JSON, 于JS 来操作异步的~
为了方便讲解还是需要一个项目例子~ 有例子更好讲解而且好观赏~
就做一个纯异步的 "增删改查分页吧~"

数据库

/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.5.56 : Database - myrole
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`myrole` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `myrole`;

/*Table structure for table `role` */

DROP TABLE IF EXISTS `role`;

CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `rolename` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

/*Data for the table `role` */

insert  into `role`(`id`,`rolename`) values (1,'后台开发者'),(2,'管理员');

/*Table structure for table `user` */

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `pwd` varchar(50) DEFAULT NULL,
  `nickname` varchar(50) DEFAULT NULL,
  `roleid` int(11) DEFAULT NULL,
  `createdate` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`id`,`name`,`pwd`,`nickname`,`roleid`,`createdate`) values (3,'test002','1223','as',2,'2020-11-06'),(4,'test003','1234','123',1,'2020-10-07'),(5,'test004','321321','WSM',2,'2020-10-06'),(6,'123','123','qwe',1,'2020-10-07');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

项目结构:

SSM 项目结构,就不会详细介绍了… 欢迎看我的 SSM整合.
实例代码.

在这里插入图片描述

实体层 entity 就不说了~

哦对,Util 里还有一个泛型分页类~ Page< T >
Page.Java

public class Page<T> {
    
    
	// 当前页数默认是 1
	private int dye = 1;
	// 每页行数 5
	private int hang = 2;
	// 总行数:数据库查寻
	private int zhang;
	// 总页数:根据总行数和每页行数计算而出;
	private int zye;
	// 每页的呈现数据集合;
	private List<T> data;

	// get/set封装;
	public int getDye() {
    
    
		return dye;
	}

	public void setDye(int dye) {
    
    
		// 如果当前页小于1 回到第一页
		if (dye < 1) {
    
    
			dye = 1;
		}
		this.dye = dye;
	}

	public int getHang() {
    
    
		return hang;
	}

	public void setHang(int hang) {
    
    
		this.hang = hang;
	}

	public int getZhang() {
    
    
		return zhang;
	}

	public void setZhang(int zhang) {
    
    
		this.zhang = zhang;
		this.zye = zhang % hang == 0 ? zhang / hang : zhang / hang + 1; // 根据总行计算出总页数;
		// 当前页 > 总页则等于总页;
		if (dye > zye && zye!=0) {
    
    
			dye = zye;
		}
	}

	public int getZye() {
    
    
		return zye;
	}

	public void setZye(int zye) {
    
    
		this.zye = zye;
	}

	public List<T> getData() {
    
    
		return data;
	}

	public void setData(List<T> data) {
    
    
		this.data = data;
	}
}

Dao

RoleMapper.java

public interface RoleMapper {
    
    
	//下拉查询全部~
	public List<Role> allRoles();
}

UserMapper.java

public interface UserMapper {
    
    
	//分页
	//查询当前页记录
	public List<User> pageUsers(Map<String,Object> map);
	//查询总记录数
	public int pageCount(Map<String,Object> map);
	//增
	public int addUser(User u);
	//删
	public int delUser(Integer id);
	//改
	public int updUser(User u);
	//详情
	public User selUser(Integer id); 
}

Service

RoleService.java

public interface RoleService {
    
    
	//下拉查询全部~
	public List<Role> allRoles();
}

UserService.java

public interface UserService {
    
    
	//分页
	//查询当前页记录: 当前页,用户名,角色id
	public Page<User> pageUser(Integer dye,String nickname,Integer roleid); 
	//增
	public int addUser(User u);
	//删
	public int delUser(Integer id);
	//改
	public int updUser(User u);
	//详情
	public User selUser(Integer id); 
}

ServiceImpl

RoleServiceImpl.java

@Service
public class RoleServiceImpl implements RoleService {
    
    

	@Autowired
	private RoleMapper rm;
	
	@Override
	public List<Role> allRoles() {
    
    
		// TODO Auto-generated method stub
		return rm.allRoles();
	}

}

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {
    
    
	
	@Autowired
	private UserMapper um;
	
	@Override
	public Page<User> pageUser(Integer dye, String nickname, Integer roleid) {
    
    
		//创建Page对象;
		Page<User> page = new Page<User>();
		//封装Map
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("nickname",nickname);
		map.put("roleid",roleid);
		
		//查询当前总记录数,根据记录数获得总页,需要与当前页进行比较是否合理~
		int count  = um.pageCount(map);		//获取总记录数
		page.setDye(dye);					//赋值,页面过来的当前页;
		page.setZhang(count);				//赋值,获取总记录数,并内部计算出总页,判断刚才存的当前页是否成立~
		
		//封装Map数据;
		map.put("dye",(page.getDye()-1)*page.getHang());
		map.put("hang",page.getHang());
		
		//获取每页数据
		List<User> users = um.pageUsers(map);
		//赋值给page
		page.setData(users);
		
		return page;						//返回~
	}

	@Override
	public int addUser(User u) {
    
    
		// TODO Auto-generated method stub
		return um.addUser(u);
	}

	@Override
	public int delUser(Integer id) {
    
    
		// TODO Auto-generated method stub
		return um.delUser(id);
	}

	@Override
	public int updUser(User u) {
    
    
		// TODO Auto-generated method stub
		return um.updUser(u);
	}

	@Override
	public User selUser(Integer id) {
    
    
		// TODO Auto-generated method stub
		return um.selUser(id);
	}

}

Spring核心配置文件… 就不在一一讲解了

controller 控制器:

其实上述代码也都是基本的, SSM 写增删改查的代码, 而Ajax 最大的区别也就是 控制器的变化!!
我们都知道: 以前浏览器发送请求——经过控制器——控制器经过一系列操作最后返回一个 视图给浏览器, 浏览器页面刷新展示~
而 Ajax 最大的不同就是: 浏览器发送请求——经过控制器——控制器将返回的不是视图,而是数据!!页面通过JS 解析进行数据展示!
@ResponseBody 注解完成Ajax
@ResponseBody是作用在方法上的注解, 将方法的返回值,以特定的格式写入到response的body区域,进而将数据返回给客户端。
当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象
需要注意:
如果返回对象,需要按utf-8编码。如果返回String,默认按iso8859-1编码
页面可能出现乱码。因此在注解中我们可以手动修改编码格式。
例如: @RequestMapping(value="xxx",produces="application/json;charset=UTF-8") value=是请求的路径 produces=后面是编码格式。
实现
为了方便操作, 一般对于Ajax 我们都喜欢返回 JSON格式给页面;
JS容易对其操作使用, 而且有 阿里巴巴… 等对JSON 提供了很多专属的 Jar包; 使在实现时候更加容易!
首先在项目中加入jar: fastjson-1.2.13.jar (市面上还有很多JSON的Jar组件,个人就用这个…)
通过: JSON.toJSONString(Object); 方法可以将 Object类型转换成 JSON形式~

RoleController.java

@Controller
public class RoleController {
    
    
	
	@Autowired
	private RoleService rs;
	
	@RequestMapping(value="/roleall",produces="application/json;charset=UTF-8")
	@ResponseBody
	public String roleall(){
    
    
		return JSON.toJSONString(rs.allRoles());
	}
}

UserController.java

@Controller
public class UserController {
    
    
	@Autowired
	private UserService us;
	
	//分页控制器
	@RequestMapping(value="/pageUser",produces="application/json;charset=UTF-8")
	@ResponseBody
	public String pageUser(Integer dye,String nickname,Integer roleid){
    
    
		return JSON.toJSONString(us.pageUser(dye, nickname, roleid));
	}
	
	
	//新增
	@RequestMapping(value="/useradd",produces="application/json;charset=UTF-8")
	@ResponseBody
	public  String useradd(User u){
    
    
		if(us.addUser(u)==1){
    
    
			return "true";		//新增成功!
		}
		return "false";			//新增失败!
	};
	
	//修改
	@RequestMapping(value="/userupd",produces="application/json;charset=UTF-8")
	@ResponseBody
	public String userupd(User u){
    
    
		if(us.updUser(u)==1){
    
    
			return "true";		//新增成功!
		}
		return "false";			//新增失败!
	}
	
	//删除
	@RequestMapping(value="/userdel",produces="application/json;charset=UTF-8")
	@ResponseBody
	public String userdel(Integer id){
    
    
		if(us.delUser(id)==1){
    
    
			return "true";		//新增成功!
		}
		return "false";			//新增失败!
	}
	
	//详情
	@RequestMapping(value="/userxq",produces="application/json;charset=UTF-8")
	@ResponseBody
	public String userxq(Integer id){
    
    
		return JSON.toJSONString(us.selUser(id));
	}
	
}

页面

页面进行 JS Ajax操作,并对返回的JSON 数据进行解析展示~

index.jsp

首页:异步分页+异步删除~

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
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>My JSP 'index.jsp' starting page</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">
	
	<!-- 使用AJAX当前要JS了!! 要注意静态资源的加载哦~SpringMVC!这里使用的是绝对路径防止地址引用失败! -->
	<script src="${pageContext.request.contextPath }/static/js/jquery-1.12.4.js"></script>
	<!-- JS代码块 -->
	<script type="text/javascript">
		//页面加载事件:
		$(function(){
     
     
			
			//页面加载首先查询一下角色下拉
			$.ajax({
     
     
				url:'roleall',				//请求url
				type:'GET',					//请求方式:get/post 
				async:false,				//请求设为同步,即必须等会调函数执行完,才执行其它代码eg:下面查询当前页数据,条件需要要角色id!! 
				success:function(result){
     
     	//回调函数: 参数是控制器返回的JSON 参数名result
					//每个下拉框必备的 "请选择" 
					var html="<option value='-1'>请选择</option>";
					//遍历JSON 来获取其它下拉选项~
					for(var i = 0;i<result.length;i++){
     
     		
    					var r = result[i];	
    					html+="<option value='"+r.id+"'>"+r.rolename+"</option>";  	//拼接字符,存在html 的var JS变量中;
    				}
    				//把数据,以 html形式放在指定的; 元素标签中去,在页面上形成下拉数据;
    				$("#roleid").html(html);	
				}
			})
			
			//调用分页方法; 且默认第一页!!
			page(1);
			
			//点击提交事件,则在次调用分页方法~
			$("#btn").click(function(){
     
     
    			page(1);
    		});
			
			
			//因为都是异步操作,所以根本不用考虑回显数据的需求!!页面就不会刷新,数据永远回显!!
			//以前对于回显,因为JS 对 EL表单式直接有执行顺序并不好用,都是用表单隐藏域来完成的...现在简直好多了!!
		})//页面加载事件结束!
		
		
		//自定义分页方法; 参数当前页数;
		function page(dye){
     
     
			//获取所需的分页条件; 当前页已经作为参数了;
			var nickname =$("#nickname").val();
			var roleid =$("#roleid").val();
			//把参数拼接为URL,中的数据
			var mydata ="dye="+dye+"&nickname="+nickname+"&roleid="+roleid;
			//执行异步!
			$.ajax({
     
     
				url:'pageUser',
				type:'POST',		//POST方式提交支持中文数据传输,GET不支持...这是关键!!
				data:mydata,		//引用上面定义好的URL参数拼接
				success:function(result){
     
     
					var html='';	//事先定义一个用于存,等会儿拼接的变量!
					for(var i=0;i<result.data.length;i++){
     
     		//遍历JSON 要知道JSON是一个Page对象 .其data属性.length 遍历其属性;
    					var r = result.data[i];					
    					html+="<tr>"+
								"<td>"+r.id+"</td>"+
								"<td>"+r.nickname+"</td>"+
								"<td>"+r.pwd+"</td>"+
								"<td>"+r.role.rolename+"</td>"+
								"<td>"+r.createdate+"</td>"+
								"<td><a href='upd.jsp?id="+r.id+"'>修改</a><a href='javascript:del("+r.id+")'>删除</a></td>"+
							"</tr>";
    				}
    				$("tbody").html(html);			//直接通过 元素选择器,并放进去!
    				//因为是分页,所以别忘了!需要当前页,方便操作就一起在回调函数中执行了;
    				html='';						//清空参数;
    				html+="<a href='javascript:page(1);'>首页</a>";
    				html+="<a href='javascript:page("+(result.dye-1)+");'>上一页</a>";
    				html+="当前"+result.dye+"页,总共有"+result.zye+"页";
    				html+="<a href='javascript:page("+(result.dye+1)+");'>下一页</a>";
    				html+="<a href='javascript:page("+(result.zye)+");'>末页</a>";
    				$("#page").html(html);
				}
			})
		}
		
		
		//删除方法
		function del(id){
     
     
			$.ajax({
     
     
				url:'userdel',
				data:'id='+id,
				success:function(result){
     
     
					if(result==true){
     
     
						alert("删除成功");	
						page(1);		//删除成功重新查询一次
					}else{
     
     
						alert("删除失败");
					}
				}
			})
		}
		
	</script>
  
  </head>
  
  <body>
	
	<a href="add.jsp" >新增</a>
	
	<!-- 条件表单:原先是表单但现在因为是异步所以好像用不上提交了,也就不需要表单了; -->
	<div>
		用户名	<input name="nickname" id="nickname" >
		角色 	
		<select name="roleid" id="roleid" >
			<!-- 内容由页面加载而来~ -->
		</select>
		<input type="button" id="btn"  value="提交"   >
	</div>
	
	<div>&nbsp</div>
	
	<!-- table展示数据 -->
	<div>
	
	<table width="100%"  border="1" >
		<thead>
			<tr>
				<td>编号</td>
				<td>用户名</td>
				<td>密码</td>
				<td>起始时间</td>
				<td>角色类型</td>
				<td>操作</td>
			</tr>
		</thead>
		<tbody>
			<!-- 内容来源于Ajax~-->
		</tbody>
	</table>
		
		<div id="page" >
			<!-- 分页数据~ -->
		</div>
	
	</div>
  </body>
  
</html>

add.jsp

异步新增: 一个特殊点就是如何获取单选按钮的选中值:
获取单选框的值有三种方式: 1. $(‘input:radio :checked’).val(); 2. $(“input[type=‘radio’]:checked”).val(); 3. $(“input[name=‘rd’]:checked”).val(); …

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
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>My JSP 'add.jsp' starting page</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">

	<script src="${pageContext.request.contextPath }/static/js/jquery-1.12.4.js"></script>
	<script type="text/javascript">
		$(function(){
     
     

			//页面加载,获取下拉数据; cope index.jsp即可~
			$.ajax({
     
     
				url:'roleall',				
				type:'GET',				
				async:false,				
				success:function(result){
     
     	
					var html="<option value='-1'>请选择</option>";
					for(var i = 0;i<result.length;i++){
     
     		
    					var r = result[i];	
    					html+="<option value='"+r.id+"'>"+r.rolename+"</option>";  	
    				}
    				$("#roleid").html(html);	
				}
			})
			
			
			//btn 点击事件;
			$("#btn").click(function(){
     
     
				//获取提交所需的参数
				var name = $("#name").val();
				var pwd = $("#pwd").val();
				var nickname = $("#nickname").val();
				var roleid = $("#roleid").val();
				//拼接URL参数
				var myurl = "name="+name+"&pwd="+pwd+"&nickname="+nickname+"&roleid="+roleid
				//Ajax新增;
				$.ajax({
     
     
					url:'useradd',
					type:'POST',
					data:myurl,
					success:function(result){
     
     
						if(result==true){
     
     
							alert("新增成功!");
							location.href="index.jsp";			//新增成功跳转页面~
						}else{
     
     
							alert("新增失败!");
						}
					}
				})
			})
			
		})
		
		
	</script>
	
  </head>
  
  <body>
   	<!-- 新增 : 因为是异步所以表单已经不是必须的了~-->
   	<div>
   		<p>姓名&nbsp:	<input name="name" id="name" > 			</p>
   		<p>密码&nbsp:	<input name="pwd" id="pwd" > 			</p>
   		<p>用户名:		<input name="nickname" id="nickname" > 	</p>
   		<p>角色&nbsp:		
   			<select name="roleid" id="roleid" >
   				<!-- 内容Ajax而来~ -->
   			</select>
   		</p>
   		<p> <input type="button" id="btn"  value="新增" > </p>
   	</div>
   	
  </body>
</html>

upd.jsp

异步修改:获取截取URL

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
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>My JSP 'upd.jsp' starting page</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">
	
	<script src="${pageContext.request.contextPath }/static/js/jquery-1.12.4.js"></script>
	<script type="text/javascript">
		$(function(){
     
     
			//获取获取当前URL;
			var url = window.location.href;
			//截取URL,根据 = 因为URL中就一个参数;  
			var id = url.split("=")[1]; 	//获取URL id的参数; 即要修改的 id;
			
			//页面加载,获取下拉数据; cope index.jsp即可~
			$.ajax({
     
     
				url:'roleall',				
				type:'GET',				
				async:false,				
				success:function(result){
     
     	
					var html="<option value='-1'>请选择</option>";
					for(var i = 0;i<result.length;i++){
     
     		
    					var r = result[i];	
    					html+="<option value='"+r.id+"'>"+r.rolename+"</option>";  	
    				}
    				$("#roleid").html(html);	
				}
			})
			
			//页面加载展示数据;
			$.ajax({
     
     
				url:'userxq',
				data:'id='+id,
				type:'get',
				success:function(result){
     
     
					//将数据呈现至页面~
					$("#name").val(result.name);
					$("#pwd").val(result.pwd);
					$("#nickname").val(result.nickname);
					$("#roleid").val(result.roleid);
				}
			})
			
			//btn 点击事件;
			$("#btn").click(function(){
     
     
				//获取提交所需的参数
				var name = $("#name").val();
				var pwd = $("#pwd").val();
				var nickname = $("#nickname").val();
				var roleid = $("#roleid").val();
				//拼接URL参数
				var myurl = "id="+	id+"&name="+name+"&pwd="+pwd+"&nickname="+nickname+"&roleid="+roleid
				//Ajax新增;
				$.ajax({
     
     
					url:'userupd',
					type:'POST',
					data:myurl,
					success:function(result){
     
     
						if(result==true){
     
     
							alert("修改成功!");
							location.href="index.jsp";			//新增成功跳转页面~
						}else{
     
     
							alert("修改失败!");
						}
					}
				})
			})
			
		})
		
		
	</script>

  </head>
  
  <body>
    <!-- 修改同新增类似~ -->
    <div>
   		<p>姓名&nbsp:	<input name="name" id="name" > 			</p>
   		<p>密码&nbsp:	<input name="pwd" id="pwd" > 			</p>
   		<p>用户名:		<input name="nickname" id="nickname" > 	</p>
   		<p>角色&nbsp:		
   			<select name="roleid" id="roleid" >
   				<!-- 内容Ajax而来~ -->
   			</select>
   		</p>
   		<p> <input type="button" id="btn"  value="修改" > </p>
   	</div>
    
  </body>
</html>

ok,恭喜您认真的看完了实例Demo 想必对Ajax 的操作有了一定了解;
接下来请深入了解一下, 以及容易出错的点!


JSON传递中文乱码问题~

在SpringMVC 中控制器,处理方法使用 @ResponseBody 注解向前台页面;
及JSON 格式进行数据传递的时候, 如果返回值是中文字符串, 则会出现乱码~
首先,当一个请求到来时,会先经过spring的这个过滤器—在到—DispatcherServlet——通过springmvc的一系列转化到控制层,并帮我们封装好了参数;
在springmvc中配置这个配置项之后< mvc:annotation-driven>会默认配置RequestMappingHandlerAdapter 和 HttpMessageConverter< T >(消息转换器)
当我们使用@ResponseBody时,那么数据返回时会调用这个数据转换器。
经过查看源码可知,默认情况下会转换成ISO-8859-1格式。简单源码附上:

public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
    
    
    public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
    private final Charset defaultCharset;
    private final List<Charset> availableCharsets;
    private boolean writeAcceptCharset;

    protected void writeInternal(String s, HttpOutputMessage outputMessage)
            throws IOException {
    
    
        if (this.writeAcceptCharset) {
    
    
            outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
        }
        Charset charset = getContentTypeCharset(outputMessage.getHeaders()
                .getContentType());
        StreamUtils.copy(s, charset, outputMessage.getBody());
    }

    ...
}

public abstract class AbstractHttpMessageConverter<T> implements
        HttpMessageConverter<T> {
    
    
    protected final Log logger = LogFactory.getLog(super.getClass());

    private List<MediaType> supportedMediaTypes = Collections.emptyList();

    ...
}

HttpMessageConverter< T > 是Spring的一个接口, 主要负责将请求信息转换为一个对象(类型为T); (通过对象,输出响应信息~)
StringHttpMessageConverter 就是其中一个实现类作用:
将请求信息转换为 字符串, 默认值 ISO-8859-1 所以每次返回值是String 就会中文乱码了~ (JSON也在字符串形式~)

方案一:

@RequestMapping(value = "/路径",produces="application/json;charset=UTF-8;")

produces : 指定返回的内容类型. application/json;charset=UTF-8; 表示该方法将返回 JSON类型的数据; 且字符编码 UTF-8;
此时会根据请求的 报文头Accept 进行匹配;这时候要注意 可能会导致406异常!
406异常: 浏览器不接受所请求页面的MIME类型(一种媒体文件的类型eg: text/html application/json );
主要可能是因为 value=”/xx.html“ 类似的请求,导致服务器响应的文件类型是 Content-Type: text/html
produces ="application/json;charset=UTF-8;" 又指定了Accept application/json;格式; 导致不匹配;
所以对于这种问题, 不在建议: value="" 中在带有 .文件后缀;
缺点: 是每一个控制器都要这样指定编码格式~

方案二:

此注解需要注意的是一定要使用spring 3.1.x 以上。

配置消息转换器 StringHttpMessageConverter 字符编码 UTF-8
优点:比较简单实用, 一次处理多次使用~
SpringMVC 核心配置文件

<!-- SptingMVC驱动 -->
<mvc:annotation-driven>
    <mvc:message-converters>  
   	  <!-- 简单明了实用,直接改类属性值,设置器编码格式~ -->
      <bean class="org.springframework.http.converter.StringHttpMessageConverter">  
        <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>  
      </bean>  
      
    </mvc:message-converters> 
</mvc:annotation-driven>

方案三:

(个人没试过~) 不使用@ResponseBody,将请求处理改成如下:直接流输出至页面~!!

@RequestMapping("/ajax")
public void ajax(HttpServletResponse response) throws IOException{
    
    
    PrintWriter out = response.getWriter();
    out.print("测试");
    out.close();
}

JSON 数据传递日期格式问题:

在SpringMVC 中使用@ResponseBody 返回JSON 数据时,日期格式默认为时间戳; (个人一般实体类直接写String 不用Data 还不错~)
(时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。)
而我们需要将器日期格式转换成 yyyy-MM-dd 格式;

方案一:

注解方式: @JSONField(format=“yyyy-MM-dd”)
我们使用FastJson 将后台查询获取user 对象转换成JSON 字符串返回给前台,
那么FastJson 对 Date类型对象处理可以通过注解方式来解决格式问题;
eg: 在user实体类中,createdate属性上面加上 @JSONField(format=“yyyy-MM-dd”) 进行日期格式化处理!
缺点:
代码有强侵入性, 禁耦合 并且修改麻烦, 所以在实际开发中一般不使用~

方案二:

配置消息转换器 FastJsonHttpMessageConverter

之前采用 StringHttpMessageConverter 来解决中文乱码问题~ 现在需要配置FastJson 消息转换器; (解决日期格式问题)
FastJsonHttpMessageConverter 序列化属性WriteDateUseDateFormat 配置默认日期类型;
FastJson 规定了默认返回的日期类型 DEFFAULT_DATE_FORMAT 为: yyyy-MM-dd HH:mm:ss

SpringMCV核心配置文件

 <mvc:annotation-driven>
	<mvc:message-converters>
	
		<bean class="org.springframework.http.converter.StringHttpMessageConverter">
			<property name="supportedMediaTypes">
				<list><value>application/json;charset=UTF-8</value></list>
			</property>
		</bean>
		
		<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
			<property name="supportedMediaTypes">
				<list><value>text/html;charset=UTF-8</value><value>application/json</value></list>
			</property>
			<property name="features">
				<list><value>WriteDateUseDateFormat</value></list>
			</property>
		</bean>
	</mvc:message-converters>
</mvc:annotation-driven>
<!--
	通过设置 FastJsonHttpMessageConverter 中的 features属性指定输出时候日期格式;
	WriteDateUseDateFormat: yyyy-MM-dd HH:mm:ss 
-->

最后还需要注意的是 controller 控制器中返回的将不在是 JSON字符串 而是直接将要获取的对象User 返回页面即可~
并在 页面上JS展示即可~

猜你喜欢

转载自blog.csdn.net/qq_45542380/article/details/108646393