该方法与(二)中项目结构相同,但是配置文件等略有不同
方法(二)这种借助response.getWriter()来获取输出流,并向请求写一个json格式数据的方式,还可以通过jackson-databind库来实现,我们再项目中加入jackson-databind,jackson-core,jackson-annotations三个jar包,如果是maven项目,可以直接在pom.xml文件中加入以下依赖。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
通过jackson-databind提供的api,我们不仅可以实现返回json数据格式,还可以通过注解@IgnoreProperties指定返回实体中被过滤的字段,从而避免用户隐私或者敏感数据泄露问题。
在我们在UserAction中添加两个请求ajax的方法,代码如下:一个是用jackson,一个是用默认的输出。这样做是与方法(二)形成对比
项目结构如下:
导包:
web.xml文件和spring-web.xml文件与方法(一)相同
实体类User如下:
package cn.tedu.entity;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties("password") //采用jackson-databind返回json数据时候过滤掉该字段
public class User implements Serializable{
private int id;
private String username;
private String password;
...
}
该实体类中采用了注解@JsonIgnoreProperties("password"),使用jackson-databind返回json数据时候过滤掉该字段
MianAction如下:
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 com.fasterxml.jackson.databind.ObjectMapper;
//用来将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都可以
}
public String jackson_databind(Object obj){
PrintWriter writer = null;
try {
HttpServletResponse response = ServletActionContext.getResponse();
//此处为text/html,否则IE浏览器会将返回的json字符串当做文件下载
response.setContentType("text/html;charset=utf-8");
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(response.getWriter(), obj);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(writer != null){
writer.close();
}
}
return NONE;//或者返回null都可以
}
}
在MainAction类中使用了jackson-databind提供的类ObjectMapper。
UserAction如下:
package cn.tedu.json;
import java.util.HashMap;
import java.util.Map;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.tedu.entity.User;
/**
* 使用传统的输出流,借助输出流,来向请求响应一个json格式的数据
* @author wq
*
*/
@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);
}
public String jsonNormal(){//采用json-lib包返回json数据
User user = new User();
user.setId(1001);
user.setUsername("张安");
user.setPassword("md5encode");
return ajax(user);
}
public String jackson(){//采用jackson-databind包返回json数据
User user = new User();
user.setId(1001);
user.setUsername("张安");
user.setPassword("md5encode");
return jackson_databind(user);
}
}
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字符串 采用struts2-json-plugin包返回json数据 -->
<action name="json22" class="userAction" method="json2">
<param name="contentType">text/html</param>
</action>
<!-- 返回json字符串 采用json-lib包返回json数据 -->
<action name="json33" class="userAction" method="jsonNormal">
<param name="contentType">text/html</param>
</action>
<!-- 返回json字符串 采用jackson-databind包返回json数据-->
<action name="json44" class="userAction" method="jackson">
<param name="contentType">text/html</param>
</action>
</package>
</struts>
测试URL动态访问action中的方法:
方法二中我们通过默认的ajax方法,返回的数据格式是json格式,但是password没有被过滤掉
方法三中的jackson_databind方法,通过@IgnoreProperties设置过滤字段passsword后,成功过滤了password字段
注意:该方式在谷歌 和 IE11 和 Edge中皆可正常使用