- 浏览: 1586467 次
- 性别:
- 来自: 吉林
文章分类
- 全部博客 (624)
- C/C++ (33)
- Java (181)
- 网络相关 (7)
- 我爱篮球 (3)
- 也爱足球 (4)
- 杂谈 (1)
- 系统架构 (3)
- Web Service (14)
- Framework (3)
- 系统命令 (8)
- 管理平台相关 (8)
- 其它 (35)
- Websphere (1)
- Struts2 (24)
- Hibernate (16)
- Spring (23)
- javascript (20)
- jquery (23)
- html/css/div (28)
- 数据库 (40)
- JavaWeb (27)
- 设计模式 (2)
- 文档编写 (3)
- SVN (5)
- Ant (1)
- Maven (13)
- 软件项目管理 (8)
- AOP (1)
- kindeditor (1)
- JSON (2)
- Servlt/JSP (4)
- WordXML (2)
- XML (12)
- 面试相关 (7)
- Tomcat (11)
- 性能与调优 (29)
- 职业发展 (2)
- 操作系统 (7)
- AJAX (2)
- DWR (1)
- Eclipse (12)
- 持续集成 (3)
- 批处理命令 (1)
- Mozilla Rhino (2)
- 新鲜技术 (18)
- Apache mina (2)
- 底层技术 (18)
- Linux (22)
- 新鲜技术,IT历史 (1)
- 敏捷开发 (1)
- 版本控制 (5)
- 较火技术 (7)
- 集群 (2)
- Web前端 (13)
- 报表工具 (3)
- 网站架构 (5)
- 大数据 (8)
- 分布式存储 (5)
- 云计算 (8)
- TCP/IP协议 (1)
- 负载均衡 (3)
- 硬件 (1)
- 表现层技术 (3)
- Velocity (3)
- jvm (6)
- 并发编程 (10)
- hadoop (8)
- 数据结构和算法 (12)
- 计算机原理 (1)
- 测试驱动开发-TDD (3)
- 开发技巧 (1)
- 分词器 (1)
- 项目构建工具 (2)
- JMX (4)
- RMI (1)
- 测试技术 (22)
- 网络完全 (1)
- Git (4)
- apache开源包 (4)
- Java常用 (1)
- mock (2)
- OSGi (2)
- MongoDB (1)
- JBPM (1)
- Storm (3)
- mysql (2)
- telnet (1)
- 正则表达式 (1)
- bootstrap (4)
- Apache ActiveMQ (1)
- redis (9)
- Nginx (2)
- rsync+inotify文件同步 (2)
- testng (1)
- 原型设计工具 (1)
- 工程能力 (1)
- 风险控制 (3)
- ibatis (1)
- 分布式 (4)
- 安全技术 (1)
- 计算机基础 (4)
- 消息中间件 (1)
- UML (2)
最新评论
-
u012236967:
java命令执行jar包(里面的main函数)的方式(包括依赖其它的jar包问题) -
世界尽头没有你:
Selenium自动化测试从入门到精通(Java版)百度网盘地 ...
自动化测试工具 Selenium WebDriver 入门教程(针对主流浏览器) -
小小西芹菜:
我喜欢代码简洁易读,服务稳定的推送服务,前段时间研究了一下go ...
dwr实现Reverse Ajax推送技术的三种方式 -
hellozhouqiao:
楼主,请教一点问题.现在我们需要在excel 的页脚里面加上图 ...
FreeMaker + xml 导出word(处理目录,图片和页眉页脚问题) -
乱在长安:
使用Timer会有各种各样的问题好嘛?!书上推荐使用Sched ...
DelayQueue (ScheduledThreadPoolExecutor调度的实现)
前面一篇文章其实只是介绍了如何在Struts2中返回JSON数据到客户端的具体范例而无关其原理,内容与标题不符惹来标题党嫌疑确实是笔者发文 不够严谨,目前已修改标题,与内容匹配。本文将从struts2-json插件的源码角度出发,结合之前的应用范例来说明struts2-json插件返 回JSON数据的原理。
用winrar打开struts2-json-plugin-xx.jar(笔者使用版本为2.1.8.1),根目录下有一个struts-plugin.xml,这个文件想必大家都很了解,不做过多介绍了。打开该文件,内容非常简答,如下:
- <? xml version = "1.0" encoding = "UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
- < struts >
- < package name = "json-default" extends = "struts-default" >
- < result-types >
- < result-type name = "json" class = "org.apache.struts2.json.JSONResult" />
- </ result-types >
- < interceptors >
- < interceptor name = "json" class = "org.apache.struts2.json.JSONInterceptor" />
- </ interceptors >
- </ package >
- </ struts >
前文提到,如果要使用Struts2返回JSON数据到客户端,那么action所在的package必须继承自json-default包,原因 就在上边的配置文件中:这里的配置文件指定了该插件的包名为json-default,所以要使用该插件的功能,就必须继承自该包——json- default。
上面的配置文件中,配置了两个类:org.apache.struts2.json.JSONResult和 org.apache.struts2.json.JSONInterceptor,前者是结果类型,后者是一个拦截器。简单说一 下,org.apache.struts2.json.JSONResult负责将action中的“某些”(通过相关参数可以指定,前文已有详述)或 action中所有"可获取"(有getter方法的属性或一个有返回值的getter方法的返回值)数据序列化成JSON字符串,然后发送给客户 端;org.apache.struts2.json.JSONInterceptor负责拦截客户端到json-default包下的所有请求,并检查 客户端提交的数据是否是JSON类型,如果是则根据指定配置来反序列化JSON数据到action中的bean中(说的有点简单,其实该拦截器内部对数据 做了很多判断),拦截器不是本文的重点,介绍到此为止。看一张图,或许能够更加清晰明了的说明JSON插件执行的流程:
下面重点说说org.apache.struts2.json.JSONResult。
首先看一下org.apache.struts2.json.JSONResult源码的核心部分:
部分属性
- private String defaultEncoding = "ISO-8859-1" ; //默认的编码
- private List<Pattern> includeProperties; //被包含的属性的正则表达式,这些属性的值将被序列化为JSON字符串,传送到客户端
- private List<Pattern> excludeProperties; //被排除的属性的正则表达式,这些属性的值在对象序列化时将被忽略
- private String root; //根对象,即要被序列化的对象,如不指定,将序列化action中所有可被序列化的数据
- private boolean wrapWithComments; //是否包装成注释
- private boolean prefix; //前缀
- private boolean enableGZIP = false ; //是否压缩
- private boolean ignoreHierarchy = true ; //是否忽略层次关系,即是否序列化对象父类中的属性
- private boolean ignoreInterfaces = true ; //是否忽略接口
- private boolean enumAsBean = false ; //是否将枚举类型作为一个bean处理
- private boolean excludeNullProperties = false ; //是否排除空的属性,即是否不序列化空值属性
- private int statusCode; //HTTP状态码
- private int errorCode; //HTTP错误码
- private String contentType; //内容类型,通常为application/json,在IE浏览器中会提示下载,可以通过参数配置<param name="contentType">text/html</param>,则不提示下载
- private String wrapPrefix; //包装前缀
- private String wrapSuffix; //包装后缀
看一下上一篇文章中的相关参数配置:
- < package name = "json" extends = "json-default" namespace = "/test" >
- < action name = "testByAction"
- class = "cn.ysh.studio.struts2.json.demo.action.UserAction" method = "testByAction" >
- < result type = "json" >
- <!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->
- <!-- 默认将会序列所有有返回值的getter方法的值,而无论该方法是否有对应属性 -->
- < param name = "root" > dataMap </ param >
- <!-- 指定是否序列化空的属性 -->
- < param name = "excludeNullProperties" > true </ param >
- <!-- 这里指定将序列化dataMap中的那些属性 -->
- < param name = "includeProperties" >
- user.*
- </ param >
- <!-- 指定内容类型,默认为application/json,IE浏览器会提示下载 -->
- < param name = "contentType" > text/html </ param >
- <!-- 这里指定将要从dataMap中排除那些属性,这些排除的属性将不被序列化,一半不与上边的参数配置同时出现 -->
- < param name = "excludeProperties" >
- SUCCESS
- </ param >
- </ result >
- </ action >
- </ package >
配置中出现了JSONResult的部分属性名,是的,JSONResult中的属性都可以根据需要在struts.xml中配置对应参数以改变默认值来满足我们的需要。
接下来看看它的两个核心方法:
- public void execute(ActionInvocation invocation) throws Exception {
- ActionContext actionContext = invocation.getInvocationContext();
- HttpServletRequest request = (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);
- HttpServletResponse response = (HttpServletResponse) actionContext.get(StrutsStatics.HTTP_RESPONSE);
- try {
- String json;
- Object rootObject;
- //查找指定的需要序列化的对象,否则序列化整个action(上文包括前一篇文章中一提到过多次)
- if ( this .enableSMD) {
- // generate SMD
- rootObject = this .writeSMD(invocation);
- } else {
- // generate JSON
- if ( this .root != null ) {
- ValueStack stack = invocation.getStack();
- rootObject = stack.findValue(this .root);
- } else {
- rootObject = invocation.getAction();
- }
- }
- //这是最核心的一行代码,包括了如何从rootObject抽取"可以"被序列化的属性的值,然后包装称JSON字符串并返回
- json = JSONUtil.serialize(rootObject, excludeProperties, includeProperties, ignoreHierarchy,
- enumAsBean, excludeNullProperties);
- //针对JSONP的一个成员方法
- json = addCallbackIfApplicable(request, json);
- boolean writeGzip = enableGZIP && JSONUtil.isGzipInRequest(request);
- //该方法是org.apache.struts2.json.JSONResult的一个成员方法,用于将JSON字符串根据指定参数包装后发送到客户端
- writeToResponse(response, json, writeGzip);
- } catch (IOException exception) {
- LOG.error(exception.getMessage(), exception);
- throw exception;
- }
- }
- /**
- * 负责根据相关参数配置,将制定JSON字符串发送到客户端
- * @param response
- * @param json
- * @param gzip
- * @throws IOException
- */
- protected void writeToResponse(HttpServletResponse response, String json, boolean gzip)
- throws IOException {
- JSONUtil.writeJSONToResponse(new SerializationParams(response, getEncoding(), isWrapWithComments(),
- json, false , gzip, noCache, statusCode, errorCode, prefix, contentType, wrapPrefix,
- wrapSuffix));
- }
恕笔者愚钝,找了好多资料,始终不明白这里的"SMD"是个什么意思,所在这里包括下文,都将忽略"SMD"。
可以看到,Struts2序列化对象为JSON字符串的整个过程都被JSONUtil的serialize方法包办了,所以有必要跟入这个方法一探究竟:
- /**
- * Serializes an object into JSON, excluding any properties matching any of
- * the regular expressions in the given collection.
- *
- * @param object
- * to be serialized
- * @param excludeProperties
- * Patterns matching properties to exclude
- * @param ignoreHierarchy
- * whether to ignore properties defined on base classes of the
- * root object
- * @param enumAsBean
- * whether to serialized enums a Bean or name=value pair
- * @return JSON string
- * @throws JSONException
- */
- public static String serialize(Object object, Collection<Pattern> excludeProperties,
- Collection<Pattern> includeProperties, boolean ignoreHierarchy, boolean enumAsBean,
- boolean excludeNullProperties) throws JSONException {
- JSONWriter writer = new JSONWriter();
- writer.setIgnoreHierarchy(ignoreHierarchy);
- writer.setEnumAsBean(enumAsBean);
- return writer.write(object, excludeProperties, includeProperties, excludeNullProperties);
- }
该方法还有一个重载的兄弟方法,只是少了boolean enumAsBean这个参数,我们并不关心它,这里不讨论它。可以看到,这个方法更简单:构建一个JSONWriter实例,注入两个参数,然后调用该 实例的write方法。我们进入JSONWriter,查看write方法的源码:
- /**
- * @param object
- * Object to be serialized into JSON
- * @return JSON string for object
- * @throws JSONException
- */
- public String write(Object object, Collection<Pattern> excludeProperties,
- Collection<Pattern> includeProperties, boolean excludeNullProperties) throws JSONException {
- this .excludeNullProperties = excludeNullProperties;
- this .buf.setLength( 0 );
- this .root = object;
- this .exprStack = "" ;
- this .buildExpr = ((excludeProperties != null ) && !excludeProperties.isEmpty())
- || ((includeProperties != null ) && !includeProperties.isEmpty());
- this .excludeProperties = excludeProperties;
- this .includeProperties = includeProperties;
- this .value(object, null );
- return this .buf.toString();
- }
它同样有一个重载的方法,我们同样不关心,浏览整个方法,不难发现,它只是所做了一些赋值操作,然后将对象的序列化工作交给了value成员方法,那么我们进入value方法看一看:
- /**
- * Detect cyclic references
- */
- private void value(Object object, Method method) throws JSONException {
- if (object == null ) {
- this .add( "null" );
- return ;
- }
- if ( this .stack.contains(object)) {
- Class clazz = object.getClass();
- // cyclic reference
- if (clazz.isPrimitive() || clazz.equals(String. class )) {
- this .process(object, method);
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Cyclic reference detected on " + object);
- }
- this .add( "null" );
- }
- return ;
- }
- this .process(object, method);
- }
很简洁,进入process方法
- /**
- * Serialize object into json
- */
- private void process(Object object, Method method) throws JSONException {
- this .stack.push(object);
- if (object instanceof Class) {
- this .string(object);
- } else if (object instanceof Boolean) {
- this .bool(((Boolean) object).booleanValue());
- } else if (object instanceof Number) {
- this .add(object);
- } else if (object instanceof String) {
- this .string(object);
- } else if (object instanceof Character) {
- this .string(object);
- } else if (object instanceof Map) {
- this .map((Map) object, method);
- } else if (object.getClass().isArray()) {
- this .array(object, method);
- } else if (object instanceof Iterable) {
- this .array(((Iterable) object).iterator(), method);
- } else if (object instanceof Date) {
- this .date((Date) object, method);
- } else if (object instanceof Calendar) {
- this .date(((Calendar) object).getTime(), method);
- } else if (object instanceof Locale) {
- this .string(object);
- } else if (object instanceof Enum) {
- this .enumeration((Enum) object);
- } else {
- this .bean(object);
- }
- this .stack.pop();
- }
发现它做了很多判断,并结合不同的方法来支持不同的数据类型,那么从这里我们可以知道Struts-json-plugin支持哪些数据类型了。对 于每一种支持的数据类型,Struts-json-plugin都有相应的方法来从从对象中抽取数据并封装成JSON字符串,以Map为例,我们看一下 map方法的源码:
- /**
- * Add map to buffer
- */
- private void map(Map map, Method method) throws JSONException {
- //这是一个对象,按照JSON语法,应该以"{}"括起来
- his.add("{" );
- Iterator it = map.entrySet().iterator();
- boolean warnedNonString = false ; // one report per map
- boolean hasData = false ;
- while (it.hasNext()) {
- Map.Entry entry = (Map.Entry) it.next();
- //如果key不是String类型,将发出警告
- Object key = entry.getKey();
- //当前属性的OGNL表达式
- String expr = null ;
- if ( this .buildExpr) {
- if (key == null ) {
- LOG.error("Cannot build expression for null key in " + this .exprStack);
- continue ;
- } else {
- //获取完整的OGNL表达式
- expr = this .expandExpr(key.toString());
- //是否是被排除的属性
- //如果你对上边生成的OGNL表达式的格式有所了解,那么includeProperties和excludeProperties的正则配置绝对不是问题
- if ( this .shouldExcludeProperty(expr)) {
- continue ;
- }
- //如果不被排除,则将当前属性名压入表达式栈(其实就是一个String而非传统意义上的栈,此处是模拟,非常精巧的算法)
- //该方法返回原来的表达式,稍后还将恢复该表达式到"栈"中
- expr = this .setExprStack(expr);
- }
- }
- //如果还有数据,则以","风格,这是JSON的语法格式
- if (hasData) {
- this .add( ',' );
- }
- hasData = true ;
- //如果key不是String类型,将发出警告,且只警告一次
- if (!warnedNonString && !(key instanceof String)) {
- LOG.warn("JavaScript doesn't support non-String keys, using toString() on "
- + key.getClass().getName());
- warnedNonString = true ;
- }
- this .value(key.toString(), method);
- this .add( ":" );
- //递归抽取数据
- this .value(entry.getValue(), method);
- //下一层的数据递归完成后,恢复表达式栈值为当前层的属性名
- if ( this .buildExpr) {
- this .setExprStack(expr);
- }
- }
- this .add( "}" );
- }
这个方法中比较重要的几行代码都做了注释,不再赘述。过滤某些属性,以使其不被序列化时struts2-JSON应用中非常常见的,比如在序列化一 个用户对象的时候,密码信息时不应该被传送到客户端的,所以要排除掉。了解shouldExcludeProperty方法的过滤规则,可以帮助我们更好 的使用此功能。源码如下:
- private boolean shouldExcludeProperty(String expr) {
- if ( this .excludeProperties != null ) {
- for (Pattern pattern : this .excludeProperties) {
- if (pattern.matcher(expr).matches()) {
- if (LOG.isDebugEnabled())
- LOG.debug("Ignoring property because of exclude rule: " + expr);
- return true ;
- }
- }
- }
- if ( this .includeProperties != null ) {
- for (Pattern pattern : this .includeProperties) {
- if (pattern.matcher(expr).matches()) {
- return false ;
- }
- }
- if (LOG.isDebugEnabled())
- LOG.debug("Ignoring property because of include rule: " + expr);
- return true ;
- }
- return false ;
- }
非常简单,就是简单的正则匹配,如果有排除配置,则先判断当前属性是否被排除,如果没有被排除,且有包含配置则检查是否被包含,如果没有被包含,则不序列化该属性,如果没有被排除且没有包含配置,则将序列化该属性。
源码跟踪到这里,已经没有继续下去的必要了,因为我们已经很清楚Struts2是如何将一个对象转换成JSON字符串并返回客户端的:
1、收集用户配置;
2、JSONWriter通过判断对象的类型来有针对性的抽取其中的属性值,对于嵌套的对象则采用递归的方式来抽取,抽取的同时,包装成符合JSON语法规范的字符串;
3、JSONUtil.writeJSONToResponse将序列化的JSON字符串按照相关配置发送到客户端;
不难看出,代码逻辑清晰,简单,朴素,没有半点花巧和卖弄,但确实是非常的精巧,表现出作者扎实的编程功底和过人的逻辑思维能力。尤其是递归抽取嵌套对象的属性值和获取当前属性的OGNL表达式的算法,堪称经典!
通过以上的源码跟踪,我们很清楚的了解Struts2序列化对象的原理和过程,并对相关参数的配置有了深刻的体会。只是令人感到奇怪的是,他并没有 使用json-lib.xx.jar中的API接口,而是以字符串拼接的方式手动构建JSON字符串,我想原因可能是因为它要用正则表达式包含或排除某些 属性的原因吧,仅作猜测,还望高人指点。
有很多人说不知道includeProperties和excludeProperties的正则表达式该怎么配置,我想说其实很简单,除了正则知 识外,就是"对象名.属性名",数组稍微不同,以为它有下标,所以是"数组对象名\[\d+\]\.属性名"。如果这里觉得说的不清楚,可以阅读以下 JSONWriter中关于OGNL表达式是如何获取的部分代码,就会明白正则该如何写了。
纯属个人理解,如有错误,烦请指正,不胜荣幸!
原创文章,转载请注明出处:http://yshjava.iteye.com/blog/1333602
发表评论
-
Struts2与Velocity整合
2014-02-19 17:13 2330转自:http://yjhexy.iteye.com/ ... -
Velocity简介和Velocity与Jsp、Freemarker的对比(java常用的三种表现层技术)
2014-02-19 17:09 1441Velocity 是一个基于java ... -
学习Struts2 jQuery Plugin 3.0(转)(此外还有struts-jquery-grid-tags, showcase等)
2014-01-14 20:04 1366from:http://blog.csdn.net/ld_f ... -
KindEditor上传图片问题
2013-03-19 15:24 3402转自:http://www.cnblogs.com/jav ... -
使用SVN检出Struts Spring Hibernate源码
2013-02-05 16:50 1356Spring Spring源码是由springframewo ... -
Servlet与Struts action线程安全问题分析
2012-08-23 10:22 1175Servlet/JSP技术和ASP、PHP等相比,由于其多线程 ... -
Struts2上传文件过大的反馈处理
2012-08-23 09:42 2379问题描述:前段时间在struts2下做文件上传,当上传大文件时 ... -
Struts2的addActionError() 与addFieldError ()
2012-08-23 09:41 1089addActionError() 与addFieldError ... -
struts2中<s:property value="xx"/>的工作原理
2012-08-20 10:18 1709使用struts2标签的jsp页面中<s:propert ... -
struts2的线程安全(好好看看)(在理解不扎实与测试下自己砸了理解的真理)
2012-08-08 15:57 2945转自:http://japi.iteye.com/blog/4 ... -
struts2下利用json进行文件上传和下载遇到的一些问题(暂时未明白)
2012-07-16 16:52 1317上传文件时:利用jquery的ajaxfileupload异步 ... -
struts2文件下载(使用struts2配置方式和单纯response方式)
2012-07-16 16:43 1862若是使用类似Servlet方式下载,可以通过ServletAc ... -
struts2文件上传(单个文件和多个文件)
2012-07-16 16:38 19611. 文件上传的原理: 表单元素的encty ... -
探究Struts2运行机制:StrutsPrepareAndExecuteFilter 源码剖析 (转)
2012-07-13 15:22 1202作者:niumd blog:http://ari.i ... -
Struts2的StrutsPrepareAndExecutefilter与FilterDispatcher
2012-07-13 15:18 979FilterDispatcher是早期struts2的过滤器, ... -
OGNL遍历list和map以及访问四个范围的属性值
2012-07-11 17:23 2342转自:http://blog.csdn.net/a9529 ... -
struts2的result为chain的跳转问题(参数设置)
2012-07-09 14:59 2626本文章非原创,本文章抄录于http://blog.sina.c ... -
struts2拦截器(转)
2012-07-01 13:52 1206转自:http://www.blogjava.ne ... -
struts2工作原理(转)
2012-07-01 13:45 1268读者如果曾经学习 过S ... -
Struts2返回JSON数据的具体应用范例(转)
2012-06-29 09:20 1401早在我刚学Struts2之初 ...
相关推荐
赠送源代码:struts2-json-plugin-2.3.24-sources.jar; 赠送Maven依赖信息文件:struts2-json-plugin-2.3.24.pom; 包含翻译后的API文档:struts2-json-plugin-2.3.24-javadoc-API文档-中文(简体)版.zip; Maven...
在"struts2返回json格式的数据练习"这个实例中,我们将学习如何配置Struts2框架以支持JSON输出,并创建一个简单的示例来展示这一过程。 首先,我们需要在Struts2项目的`pom.xml`文件中添加JSON插件依赖。Struts2的...
在"Struts2_JSON_Demo"项目中,你可以通过分析源代码,了解上述各个步骤的实现细节,从而深入理解Struts2和JSON的交互。这个示例项目将帮助你掌握如何在实际项目中有效地使用Struts2和JSON,提升Web应用的性能和用户...
在压缩包`demo_json2`中,可能包含了实现上述示例的源代码,包括Action类、配置文件和测试页面。你可以下载这些文件并按照说明运行,以便更好地理解和实践Struts2与Jackson结合处理JSON数据的方法。 总之,通过集成...
在这个例子中,`testJson`方法处理请求后返回一个包含"message"键的Map,当配置了JSON结果类型时,Struts2会自动将其转化为JSON格式,并返回给客户端。 在实际的"Maven-web项目 Struts2 Struts注解"中,`Strut2-...
本示例主要探讨如何在Struts2框架中实现从服务器向客户端返回JSON数据。 首先,让我们了解JSON的基本结构。JSON是一种数据交换格式,它以键值对的形式存储数据,类似于JavaScript对象。例如: ```json { "name": ...
Struts2 JSON Plugin是Apache Struts框架的一个扩展插件,主要功能是为Struts2提供JSON(JavaScript Object Notation)支持。JSON是一种轻量级的数据交换格式,它使得客户端(通常为JavaScript)与服务器端之间进行...
1. **Action类**:这是Struts2的核心组件,处理来自客户端的请求,执行业务逻辑,并通过JSON格式返回数据。 2. **配置文件**:Struts2的配置文件(通常为struts.xml)定义了Action的映射、结果类型以及数据拦截器等...
在这个例子中,`/helloWorld.json`请求会被发送到服务器,Struts2框架会处理这个请求,返回JSON数据,然后jQuery会将接收到的JSON数据解析并显示在页面上。 关于源码方面,你可以查看`src`目录下的Java源代码和`...
本篇将深入探讨`JsonUtils.java`源代码,以及Struts2与JSON插件的结合使用。 首先,`JsonUtils`是Struts2 JSON插件中的核心工具类,主要负责将Java对象转换为JSON格式的字符串。在`JsonUtils.java`中,我们可以看到...
“ajax,struts2,json实现省市区三级联动源码含全国省市区数据库”这一标题揭示了这个压缩包包含的是一项使用AJAX、Struts2和JSON技术来实现的省市区三级联动功能的源代码。这项技术常用于web应用中,允许用户在选择...
学习和研究JavaEE源代码及Struts2源代码,有助于开发者深入理解Web应用的工作原理,提升解决问题的能力,同时也能为开发更复杂的企业级应用打下坚实的基础。通过对源代码的阅读和分析,我们可以学习到最佳实践,提高...
通过Struts2的插件,如struts2-json-plugin,可以在Action类中直接返回一个包含JSON数据的对象,Struts2会自动将其序列化为JSON格式。 3. **WebRoot目录**:这是Web应用程序的根目录,包含了HTML、CSS、JavaScript...
- 使用Struts 2的JSON插件,使Action能够返回JSON格式的数据。 3. **JSON数据交换**: - JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。 - 在...
学习XWork源代码可以帮助我们更好地理解Struts2的工作原理,解决实际开发中遇到的问题。同时,也可以从中获取灵感,自定义拦截器、转换器和验证器,以满足特定的业务需求。"推荐,一定要看看.txt"这个文件可能是对源...
这个源代码包提供了对Struts2核心组件、拦截器、插件以及其他相关模块的深入理解。 在Struts2的核心组件中,主要包括以下部分: 1. **Action类**:它是业务逻辑的载体,处理用户请求并返回结果。在Struts2中,...
ExtJS Tree + JSON + Struts2 示例源代码详解 在Web开发中,构建交互式的用户界面是关键。ExtJS是一个强大的JavaScript库,尤其擅长创建桌面级的Web应用。本示例将详细介绍如何结合ExtJS的Tree组件、JSON数据格式...
Struts2、JSON和Ajax是Web开发中的三个关键技术,它们在构建动态、交互性强的Web应用中发挥着重要作用。这篇文章将深入探讨这三个概念及其在实际项目中的应用。 **Struts2** 是一个基于MVC(Model-View-Controller...
在"strutsPortlet"这个压缩包中,很可能包含了一个示例portlet的源代码,演示了如何在Struts2和Spring的上下文中处理JSON请求和响应。开发者可以通过研究这些代码了解以下知识点: 1. **Struts2 JSON插件**:了解...