struts2中实现返回json格式请求

struts2作为一个mvc框架,请求一个方法,返回一个页面,当post请求成功之后,跳转到success页面,大多数情况下能够满足我们的要求,但是web开发中ajax技术的使用是不可避免的,我们知道ajax请求大多数情况下需要的数据是json格式。我们如何让struts这个mvc框架作为一个restful服务器,提供rest api,显得尤为重要,虽然这时候不能完全体现mvc框架的职能。

struts2实现json请求,可以有两种方式:

  • 通过struts2-json-plugin插件,这种方式需要在struts.xml中配置action,而且package需要继承json-struts,另外还需要配置结果资源。
  • 传统的输出流,向ajax请求写结果。

第一种方式,如果是maven工程,那么就需要在pom.xml中加入struts2-json-plugin依赖。


    org.apache.struts
    struts2-core
    ${struts2.version}
 

    org.apache.struts
    struts2-json-plugin
    ${struts2.version}

编写action,其中,方法返回结果不重要,也不需要指定资源,但是返回给ajax请求的结果需要声明在action中,并提供get,set方法。我们只需要给请求结果赋值。

package com.xxx.struts.action;
import com.opensymphony.xwork2.Action;
import com.xxx.struts.entity.User;
public class ApiAction {	
	private User user;
	public User getUser(){return this.user;}
	public void setUser(User user){this.user = user;}
	public String json(){
		user  = new User();
		user.setId("1");
		user.setUsername("ajax返回json");
		user.setPassword("123456");
		System.out.println("method get call.");
		return Action.SUCCESS;
	}
}

这里,我们返回的是User对象的变量user,我们需要在json()方法中给user赋值。

配置struts.xml

struts2中实现返回json格式请求_第1张图片

  • package需要继承json-default
  • result的type值是json
  • param名为root的参数就是我们在 action中定义的user变量

这样就完成了我们的一个json请求的编写,我们查看一下运行结果:

struts2中实现返回json格式请求_第2张图片

请求确实返回了json格式数据,而且json编码是utf-8。可以支持中文。

第二种方式,借助输出流,来向请求响应一个json格式的数据。

首先我们需要引入依赖包json-lib,后面我们需要JSONObject来将java pojo对象转换为json对象。


   net.sf.json-lib
   json-lib
   2.4
   jdk15

 这里需要注意的是maven仓库中对json-lib的依赖描述是

   
        net.sf.json-lib
        json-lib
        2.4
   

这样,我们其实是无法下载到这个依赖包的,官方针对该版本提供了两个jdk版本的包,我们这里需要的是jdk15。所以还需要在依赖中加上这么一个属性:jdk15

struts2中实现返回json格式请求_第3张图片

从这个依赖图可以看到json-lib还依赖了其他的ezmorph,commons-beanutils,commons-collections,commons-lang,commons-logging,如果不是maven项目,需要将这些依赖包都加入到classpath下。

加入了依赖之后,我们编写一个BaseAction,实现方法ajax,用来将java对象转换为json对象,并输出。我们需要实现json返回请求的类可以继承该类。

package com.xxx.struts.action;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.struts2.ServletActionContext;
public class BaseAction {
	public String ajax(Object out){
		PrintWriter writer = null;
		try {
			HttpServletResponse response = ServletActionContext.getResponse();		
			response.setContentType("application/json;charset=utf-8");
			writer = response.getWriter();
			response.setDateHeader("Expires", 0);
			JSONObject object = JSONObject.fromObject(out);
			writer.write(object.toString());
			writer.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(writer!=null){
				writer.close();
			}
		}
		return null;
	}
}

 编写action类,实现返回json数据方法。

package com.xxx.struts.action;
import java.util.HashMap;
import java.util.Map;
public class UserAction extends BaseAction{
	public String json(){
		Map result  = new HashMap();
		result.put("code", 200);
		result.put("msg", "success");
		result.put("error", "没有错误信息");
		return ajax(result);
	}
}

 编写完这些就可以测试,我们访问http://localhost:8080/struts/user!json.action

struts2中实现返回json格式请求_第4张图片

这种通过PrintWriter返回的方式可以不用配置struts.xml,但是需要注意一个地方,就是我们在设置返回类型和编码的时候,需要在resonse.getWriter()之前。

struts2中实现返回json格式请求_第5张图片

如果顺序颠倒,那么这种设置就不生效。默认的编码就会变为iso-8859-1,如果返回结果中带有中文,那么就会出现中文乱码,如下所示: 

struts2中实现返回json格式请求_第6张图片

这种方式实现的json请求,方法实现中返回一个null视图,表示无结果视图,响应结果通过输出流输出。

这种借助response.getWriter()来获取输出流,并向请求写一个json格式数据的方式,还可以通过jackson-databind库来实现,我们再项目中加入jackson-databind,jackson-core,jackson-annotations三个jar包,如果是maven项目,可以直接在pom.xml文件中加入以下依赖。


        com.fasterxml.jackson.core
        jackson-databind
        2.9.5
 

通过jackson-databind提供的api,我们不仅可以实现返回json数据格式,还可以通过注解@IgnoreProperties指定返回实体中被过滤的字段,从而避免用户隐私或者敏感数据泄露问题。

在我们在UserAction中添加两个请求ajax的方法,代码如下:一个是用jackson,一个是用默认的输出。

public String ajaxByJackson(){
	User user = new User();
	user.setId("1001");
	user.setUsername("csdn");
	user.setPassword("md5encode");
	return ajaxByJackson(user);
}
	
public String ajaxByDefault(){
	User user = new User();
	user.setId("1001");
	user.setUsername("csdn");
	user.setPassword("md5encode");
	return ajax(user);
}

我们实现ajaxByJackson(Object obj)方法,这里面使用了jackson-databind提供的类ObjectMapper。

public String ajaxByJackson(Object obj){
	PrintWriter output = null;
	try {
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("application/json;charset=UTF-8");
		ObjectMapper mapper = new ObjectMapper();
		mapper.writeValue(response.getWriter(), obj);
	} catch (Exception e) {
		e.printStackTrace();
	}finally {
		if(output!=null)output.close();
	}
	return null;
}

 我们定义一个User实体类,用来像ajax请求中传入数据。

@JsonIgnoreProperties({"password"})
public class User {
	private String id;
	private String username;
	private String password;
    ...省略get,set方法
}

我们通过默认的ajax方法,返回的数据格式是json格式,但是password没有被过滤掉。

struts2中实现返回json格式请求_第7张图片

而ajaxByJaskson()方法,通过@IgnoreProperties设置过滤字段passsword后,成功过滤了password字段。

你可能感兴趣的:(java)