该方法与(一)中项目结构相同,但是配置文件等略有不同
使用传统的输出流,借助输出流,来向请求响应一个json格式的数据
首先我们需要引入依赖包json-lib,后面我们需要JSONObject来将java pojo对象转换为json对象
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier><!--指定jdk版本-->
</dependency>
这里需要注意的是maven仓库中对json-lib的依赖描述是
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
</dependency>
这样,我们其实是无法下载到这个依赖包的,官方针对该版本提供了两个jdk版本的包,我们这里需要的是jdk15。所以还需要在依赖中加上这么一个属性:<classifier>jdk15</classifier>
从这个依赖图可以看到json-lib还依赖了其他的ezmorph,commons-beanutils,commons-collections,commons-lang,commons-logging,如果不是maven项目,需要将这些依赖包都加入到classpath下。
加入了依赖之后,我们编写一个MainAction,实现方法ajax,用来将java对象转换为json对象,并输出。我们需要实现json返回请求的类可以继承该类
项目结构如下:
导包:
web.xml文件和spring-web.xml文件与方法(一)相同
MainAction如下:
package cn.tedu.json;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.struts2.ServletActionContext;
import cn.tedu.web.BaseAction;
//用来将java对象转换为json对象
public class MainAction extends BaseAction{
public String ajax(Object obj){
PrintWriter writer = null;
try {
HttpServletResponse response = ServletActionContext.getResponse();
//此处为text/html,否则IE浏览器会将返回的json字符串当做文件下载
response.setContentType("text/html;charset=utf-8");
writer = response.getWriter();
response.setDateHeader("Expires", 0);
JSONObject object = JSONObject.fromObject(obj);
writer.write(object.toString());
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(writer != null){
writer.close();
}
}
return NONE;//或者返回null都可以
}
}
编写action类,实现返回json数据方法
UserAction如下:
package cn.tedu.json;
import java.util.HashMap;
import java.util.Map;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
@Controller
@Scope("prototype")
public class UserAction extends MainAction{
public String json2(){
Map<String, Object> result = new HashMap<String, Object>();
result.put("code", 200);
result.put("msg", "success");
result.put("error", "没有错误信息");
return ajax(result);
}
}
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>
<!-- 开启动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<package namespace="/demo" name="demo" extends="struts-default,json-default">
<!-- 返回json字符串 -->
<action name="json22" class="userAction">
<param name="contentType">text/html</param>
</action>
</package>
</struts>
URL:http://localhost:8000/struts_day03/demo/json22!json2.action
显示结果:{"error":"没有错误信息","code":200,"msg":"success"}
该方式在谷歌 和 IE11 和 Edge中皆可正常使用
对上述访问URL的问题请参见博客(采用动态方式访问action中的方法)
注意:这种通过PrintWriter返回的方式需要注意一个地方,就是我们在设置返回类型和编码的时候,需要在resonse.getWriter()之前。
如果顺序颠倒,那么这种设置就不生效。默认的编码就会变为iso-8859-1,如果返回结果中带有中文,那么就会出现中文乱码,如下所示:
{"error":"??????","code":200,"msg":"success"}
这种方式实现的json请求,方法实现中返回一个null或者’none’,表示无结果视图,响应结果通过输出流输出。