JSON(JavaScript Object Notation)
    1.一种轻量级的数据交换格式
    2.通常用于在客户端和服务器之间传递数据
    3.jQuery的所有参数都是以JSON格式出现
    4.在Struts 2中通过插件的方式实现

优势(较XML):
    1.轻量级交换语言
    2.结构简单
    3.易于解析
    
JSON对象:
    语法:
        var JSON对象 = {key:value,key:value,……};
    范例:{"id":4,"name":"梅西","pwd":"6666"}
【注意:其中的key值必须是字符串】
    
JSON数组:
    语法:
        var JSON数组 = [value,value,……];
    范例:
        var countryArray = ["中国","美国","俄罗斯"];
        var personArray = [
                            {"name":"张三","age":30},
                            {"name":"李四","age":40}
                          ];
                          
步骤:
    1.导入struts2-json-plugin-xxx.jar
    2.在struts.xml中定义package并继承json-default
    3.指定<result>的type属性指定为"json"

================================Result===============================    
一、JSON类型的Result:
    1.参数说明:
        参数                    作用                                         默认值                                   适用场景
        root   指定要序列化的根对象              当前Actin中所有有返回值的getter方法的值    用于指定不需要序列化key值的数据
        includeProperties  指定根对象中要序列化的属性            当前根对象中的所有属性      用于需要序列化的属性较少的情况
        excludeProperties        指定根对象中要排除的属性              null               用于需要排除序列化的属性较少的情况
        excludeNullProperties    指定根对象中是否序列化值为空的属性    false              用于需要过滤空值的情况

2.步骤:
        a.添加第三方插件:struts2-json-plugin-xxx.jar
        b.在struts.xml中指定package继承json-default
        c.指定<result>的type属性为“json”
        d.根据业务需求合理指定param参数
    
    3.作用:
        a.返回JSON格式数据,配合jQuery实现Ajax
        b.param参数
        c.root、 includeProperties、 excludeProperties、 excludeNullProperties

范例:登录表单
1.User实体类

 package com.Elastic.StrutsDemo6.ivy.entity;
spublic class User {
private String loginName;
private String loginPass; public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getLoginPass() {
return loginPass;
}
public void setLoginPass(String loginPass) {
this.loginPass = loginPass;
} }

2.UserAction类

 package com.Elastic.StrutsDemo6.ivy.action;

 import java.util.Date;
import java.util.HashMap;
import java.util.Map; import com.Elastic.StrutsDemo6.ivy.entity.User;
import com.opensymphony.xwork2.ActionSupport; public class UserAction extends ActionSupport {
private User user; public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} private Map<String, Object> jsonResult = new HashMap<String, Object>(); public Map<String, Object> getJsonResult() {
return jsonResult;
} public void setJsonResult(Map<String, Object> jsonResult) {
this.jsonResult = jsonResult;
} public String login() { //登陆成功以后,额外添加的信息
/*jsonResult.put("success", true);
jsonResult.put("data", user);
jsonResult.put("msg", "登陆成功");
jsonResult.put("loginTime", new Date());*/ if ("admin".equals(user.getLoginName().trim()) && "123456".equals(user.getLoginPass().trim())) {
jsonResult.put("success", true);
jsonResult.put("data", user);
jsonResult.put("msg", "登陆成功");
jsonResult.put("loginTime", new Date());
} else {
jsonResult.put("success", false);
jsonResult.put("msg", "登陆失败");
jsonResult.put("loginTime", new Date());
}
return SUCCESS;
}
}

3.struts.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd" >
<struts>
<!-- 使用JSON配置 -->
<package name="jsonDefault" namespace="/" extends="json-default">
<action name="login" class="com.Elastic.StrutsDemo6.ivy.action.UserAction" method="login"> <!-- 配置JSON类型的result -->
<!--type属性指定为"json"",将返回序列化的JSON格式数据-->
<result type="json">
<!-- <param name="root">user</param> -->
<param name="root">jsonResult</param>
</result>
</action> </package>
</struts>

4.web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>StrutsDemo6_ivy</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list> <filter>
<filter-name>Struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> </web-app>

5.valid.js

 /**
* rules: 对象
*/ var rules = {
loginName : {
rule : {
required : true,
length : [6,12]
},
msg : {
required : '用户名不能为空',
length : '用户名的长度必须在6-12位之间'
}
}, loginPass : {
rule : {
length : [6,12]
},
msg : {
length : '密码的长度必须在6-12位之间'
}
}
}; function validForm(form,rules) {
for ( var p in rules) {
form.find('#' + p).on('valid',rules[p],function(event){
//使用event.data, msg内容才会不同!!!
var inputRules = event.data.rule; for ( var r in inputRules) {
var value = $(this).val();
if (r === 'required' && inputRules[r] === true) {
if (value === '') {
$(this).data('success',false); $(this).closest('div').next().html(event.data.msg[r]); } else {
$(this).data('success',true);
$(this).closest('div').next().html('');
}
} //验证先后顺序
/*if ($(this).data('success') === false) {
return;
}*/ if (r === 'length' && inputRules[r]) {
if (value.length > inputRules[r][1] || value.length < inputRules[r][0]) {
$(this).data('success',false); $(this).closest('div').next().html(event.data.msg[r]); } else {
$(this).data('success',true);
$(this).closest('div').next().html('');
}
}
}
});
} //事件绑定一次
function valid() {
//trigger:触发valid事件
form.find(':input').trigger('valid');
var success = true; form.find(':input').each(function() {
if ($(this).data('success') === false) {
success = false;
return;
}
});
return success;
} return valid;
}

6.login.jsp

 <%--引入JSP页面PAGE指令 --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- 引入JSTL标签指令 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html language="zh-CN">
<head>
<meta charset="utf-8">
<!-- 设置浏览器渲染的引擎 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!-- 设置支持移动设备 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>网页标题</title>
<!-- 引入bootstrap的样式 -->
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/css/bootstrap.min.css">
</head>
<body>
<div class="container"> <div class="panel panel-primary">
<div class="panel-heading">登陆</div>
<div class="panel-body">
<form class="form-horizontal" action="login" method="post" data-role="login">
<div class="form-group">
<label class="col-md-3 control-label" for="loginName">用户名:</label>
<div class="col-md-6">
<input class="form-control" id="loginName" name="user.loginName" type="text" autocomplete="off" />
</div>
<div class="col-md-3"> </div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="loginPass">密码:</label>
<div class="col-md-6">
<input class="form-control" id="loginPass" name="user.loginPass" type="password" />
</div>
<div class="col-md-3"> </div>
</div>
<div class="form-group">
<input class="btn btn-primary btn-block" data-role="login" type="button" value="登陆" />
</div>
</form>
</div>
</div>
</div> <!-- 引入JS的样式 -->
<script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery-2.2.4.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/bootstrap.min.js"></script> <script type="text/javascript" src="<%=request.getContextPath()%>/js/valid.js"></script> <script type="text/javascript">
//JSON对象
//测试
/* var person = {
"name":"李四",
"age":20
}; alert(person.age); */ $(function() {
//方法二
//给表单元素绑定一个自定义的验证事件
/* $('#loginName').on('valid', function() {
var name = $(this).val();
if ('' == name) {
$(this).closest('div').next().html('用户名不能为空!');
$(this).data('success', false);
} else {
$(this).closest('div').next().html('');
$(this).data('success', true);
} });
$('#loginPass').on('valid', function() {
var name = $(this).val();
if ('' == name) {
$(this).closest('div').next().html('密码不能为空!');
$(this).data('success', false);
} else {
$(this).closest('div').next().html('');
$(this).data('success', true);
} }); */ var valid = validForm($('form'), rules); $('[data-role="login"]').click(function() {
//获取表单
var $form = $(this).closest('form'); $.ajax({
url : "login",
type : "post",
data : $form.serialize(),
//data : $(this).closest('form').serialize(),
beforeSend : function() {
/* var success = true; //trigger:触发valid事件
$form.find(':input').trigger('valid');
$form.find(':input').each(function() {
if ($(this).data('success') === false) {
success = false;
return;
}
});
return success;*/ //方法三
//返回方法
return valid(); //方法一:
/* var name = $('#loginName').val();
if ('' == name) {
$('#loginName').closest('div').next().html('用户名不能为空!');
return false;
} else {
$('#loginName').closest('div').next().html('');
} var pass = $('#loginPass').val();
if ('' == pass) {
$('#loginPass').closest('div').next().html('密码不能为空!');
return false;
} else {
$('#loginPass').closest('div').next().html('');
} */
},
success : function(result) {
//返回result(对象)
//alert(result);
alert(result.msg);
if (result.success) {
//window.location = 'index.jsp';
}
} });
});
});
</script>
</body>
</html>

二、Stream类型的Result    
    1.步骤:
        a.定义一个InputStream类型的成员变量
        b.给该变量添加getter和setter方法
        c.将要发送到客户端的数据赋值给该变量
        d.根据业务需求合理指定param参数
        
    2.作用:
        a.返回二进制数据,配合jQuery实现Ajax,或者实现验证码
    
    3.param参数
        a.contentType、inputStream

范例:验证码--在上一个范例的基础上修改
1.CodeAction类

 package com.Elastic.StrutsDemo6.ivy.action;

 import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date; import javax.imageio.ImageIO; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport; public class CodeAction extends ActionSupport {
private InputStream inputStream; public InputStream getInputStream() throws IOException {
//1.随机生成4位的验证码
String[] strs = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7",
"8", "9" };
String code = "";
for (int i = 0; i < 4; i++) {
String temp = strs[(int)(Math.random() * strs.length)]; //随机生成大写字母
temp = (int)(Math.random() * 2) == 0 ? temp : temp.toUpperCase();
code += temp;
} //2.生成验证码图片
BufferedImage codeImg = new BufferedImage(100, 25, BufferedImage.TYPE_INT_RGB);
//得到图片的绘制对象
Graphics2D g2d = codeImg.createGraphics();
//设置填充颜色并填充
g2d.setColor(new Color(240, 240, 240));
g2d.fillRect(0, 0, codeImg.getWidth(), codeImg.getHeight());
//绘制验证码到图片上
Font font = new Font("微软雅黑", Font.PLAIN, 20);
g2d.setFont(font);
//获取字体宽度
FontMetrics fm = g2d.getFontMetrics();
//设置左右空白和字体间隔
float start = 15;
float space = (float)(codeImg.getWidth() - 2 * start - fm.getStringBounds(code, g2d).getWidth()) / (code.length() - 1);
//随机生成每个字符的样式
for (int i = 0; i < code.length(); i++) {
g2d.setColor(getRandomColor());
String temp = code.charAt(i) + "";
g2d.drawString(temp, start, font.getSize());
start += fm.getStringBounds(temp, g2d).getWidth() + space;
} //绘制干扰项
//随机生成点
for (int i = 0; i < 100; i++) {
g2d.setColor(getRandomColor());
int x = (int)(Math.random() * codeImg.getWidth());
int y = (int)(Math.random() * codeImg.getHeight());
g2d.drawLine(x, y, x, y);
}
//随机生成线
for (int i = 0; i < 10; i++) {
g2d.setColor(getRandomColor());
int x = (int)(Math.random() * codeImg.getWidth());
int y = (int)(Math.random() * codeImg.getHeight());
int x1 = (int)(Math.random() * codeImg.getWidth());
int y1 = (int)(Math.random() * codeImg.getHeight());
g2d.drawLine(x, y, x1, y1);
} ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(codeImg, "png", byteArrayOutputStream);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); //把验证码保存到session中
ActionContext.getContext().getSession().put("code", code);
//设置验证码有效时间
ActionContext.getContext().getSession().put("codeMaxTime", new Date().getTime() + 10 * 1000); return byteArrayInputStream;
} public Color getRandomColor() {
int r = (int)(Math.random() * 256);
int g = (int)(Math.random() * 256);
int b = (int)(Math.random() * 256);
return new Color(r, g, b);
} }

2.struts.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd" >
<struts> <!-- 使用JSON配置 -->
<package name="jsonDefault" namespace="/" extends="json-default">
<action name="login" class="com.Elastic.StrutsDemo6.ivy.action.UserAction" method="login">
<!-- 配置JSON类型的result -->
<!--type属性指定为"json"",将返回序列化的JSON格式数据-->
<result type="json">
<!-- <param name="root">user</param> -->
<param name="root">jsonResult</param> <!-- ??? -->
<param name="excludeProperties">data.loginPass</param>
<param name="excludeNullProperties">true</param>
</result> </action>
</package> <package name="default" namespace="/" extends="struts-default">
<action name="code" class="com.Elastic.StrutsDemo6.ivy.action.CodeAction">
<result type="stream">
<param name="ContentType">image/jpeg</param>
<param name="inputStream"></param>
</result> </action> </package>
</struts>

3.UserAction类

 package com.Elastic.StrutsDemo6.ivy.action;

 import java.util.Date;
import java.util.HashMap;
import java.util.Map; import com.Elastic.StrutsDemo6.ivy.entity.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport; public class UserAction extends ActionSupport {
private User user; private String code; public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} private Map<String, Object> jsonResult = new HashMap<String, Object>(); public Map<String, Object> getJsonResult() {
return jsonResult;
} public void setJsonResult(Map<String, Object> jsonResult) {
this.jsonResult = jsonResult;
} public String login() { long time = (long) ActionContext.getContext().getSession().get("codeMaxTime");
if (time < new Date().getTime()) {
jsonResult.put("msg", "验证码过期");
jsonResult.put("success", false);
return SUCCESS;
} String sessionCode = ActionContext.getContext().getSession().get("code").toString();
if (sessionCode.equalsIgnoreCase(code)) {
jsonResult.put("msg", "验证码错误");
jsonResult.put("success", false);
return SUCCESS;
} //登陆成功以后,额外添加的信息
/*jsonResult.put("success", true);
jsonResult.put("data", user);
jsonResult.put("msg", "登陆成功");
jsonResult.put("loginTime", new Date());*/ if ("admin".equals(user.getLoginName().trim()) && "123456".equals(user.getLoginPass().trim())) {
jsonResult.put("success", true);
jsonResult.put("data", user);
jsonResult.put("msg", "登陆成功");
jsonResult.put("loginTime", new Date());
} else {
jsonResult.put("success", false);
jsonResult.put("msg", "登陆失败");
jsonResult.put("loginTime", new Date());
}
return SUCCESS;
} }

4.login.jsp

 <%--引入JSP页面PAGE指令 --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- 引入JSTL标签指令 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html language="zh-CN">
<head>
<meta charset="utf-8">
<!-- 设置浏览器渲染的引擎 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!-- 设置支持移动设备 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>网页标题</title>
<!-- 引入bootstrap的样式 -->
<link rel="stylesheet" type="text/css"
href="<%=request.getContextPath()%>/css/bootstrap.min.css">
</head>
<body>
<div class="container"> <div class="panel panel-primary">
<div class="panel-heading">登陆</div>
<div class="panel-body">
<form class="form-horizontal" action="login" method="post" data-role="login">
<div class="form-group">
<label class="col-md-3 control-label" for="loginName">用户名:</label>
<div class="col-md-6">
<input class="form-control" id="loginName" name="user.loginName" type="text" autocomplete="off" />
</div>
<div class="col-md-3"> </div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="loginPass">密码:</label>
<div class="col-md-6">
<input class="form-control" id="loginPass" name="user.loginPass" type="password" />
</div>
<div class="col-md-3"> </div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="code">验证码:</label>
<div class="col-md-6">
<input class="form-control" id="code" name="code" type="password" />
<img id="codeImg" alt="" src="code" onclick="getCode()"><a href="javascript:getCode();">看不清楚,换一张?</a>
</div>
<div class="col-md-3"> </div>
</div>
<div class="form-group">
<input class="btn btn-primary btn-block" data-role="login" type="button" value="登陆" />
</div>
</form>
</div>
</div>
</div> <!-- 引入JS的样式 -->
<script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery-2.2.4.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/bootstrap.min.js"></script> <script type="text/javascript" src="<%=request.getContextPath()%>/js/valid.js"></script> <script type="text/javascript">
function getCode() {
document.getElementById('codeImg').src='code?_dc='+new Data();
}
</script> <script type="text/javascript">
$(function() {
var valid = validForm($('form'), rules); $('[data-role="login"]').click(function() {
//获取表单
var $form = $(this).closest('form');
$.ajax({
url : "login",
type : "post",
data : $form.serialize(),
beforeSend : function() {
//返回方法
return valid();
},
success : function(result) {
alert(result.msg);
if (result.success) {
//window.location = 'index.jsp';
}
} });
});
});
</script>
</body>
</html>

最新文章

  1. 最新php环境搭建
  2. Openvz特点和分析
  3. SGU 185 Two shortest 最短路+最大流
  4. GB2312 简体中文编码表
  5. AIR lame参数配置
  6. c语言_链表实例讲解(两个经典例子)
  7. IE浏览器兼容性的痛苦
  8. [转载]网络编辑必知常识:什么是PV、UV和PR值 zz
  9. weighted Kernel k-means 加权核k均值算法理解及其实现(一)
  10. Python中标准模块importlib详解
  11. 封装和static 以及关键字“this”的用法
  12. javaweb闲暇小程序之抽签程序
  13. 泡泡堂BNB[ZJOI2008]
  14. Ubuntu18.04下可以完美运行Quake3 Arena
  15. SQLServer 清空某个库所有表
  16. @@identity与SCOPE_IDENTITY的区别
  17. 20155227《网络对抗》Exp6 信息收集与漏洞扫描
  18. Lintcode: First Position of Target (Binary Search)
  19. MVC,MVP 和 MVVM 的图示(转)
  20. javascript中函数的写法

热门文章

  1. 【一起学源码-微服务】Nexflix Eureka 源码十二:EurekaServer集群模式源码分析
  2. 动态规划之用最少的字符操作将字符串A转换为字符串B
  3. 毕业两年半,入手人生第一款macbook pro
  4. C# async await 死锁问题总结
  5. 洛谷P1462 通往奥格瑞玛的道路 题解 最短路+二分答案
  6. Go的内存对齐和指针运算详解和实践
  7. python 生成器 yield语句
  8. isStatic:检测数据是不是除了symbol外的原始数据
  9. 加老板qq:804691342一起交流学习 致读者的话:曾经的我们很年少,现在我们要为理想的路疯狂的走下去。
  10. git branch stash