struts2 怎样读取json数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了struts2 怎样读取json数据相关的知识,希望对你有一定的参考价值。

参考技术A

一.认识JSON

JSON是一种轻量级、基于文本、与语言无关的数据交换格式,可以用文本格式的形式来存储或表示结构化的数据。

二.POST请求与Content-Type: application/json

常用的HTTP请求方法有GET, POST, PUT, DELETE等。在提交POST请求时,请求数据放在消息体(Body)中,请求数据的格式及编码方式用Content-Type来指定。如我们常用的表单<form>提交,其Content-Type默认为application/x-www-form-urlencoded,提交的数据按照key1=val1&key2=val2进行编码,服务器端也能很容易地解析K-V值。

JSON的出现,让交换的数据不再仅限于简单的K-V结构,而可以有更加复杂的层级,特别适合于RESTful接口。在发送请求时,指定Content-Type为application/json,即可使用JSON字符串作为请求的数据。而在服务器端接收到该请求后,将按照JSON字符串对请求数据进行处理。

三.Struts2接收JSON请求

在Struts2的Action中提取Content-Type为application/x-www-form-urlencoded的POST参数,我们非常熟悉:在Action中定义属性及其getter, setter方法,接收到请求时,默认会将与属性同名的参数值赋予该属性。

但是对Content-Type为application/json的请求数据,Struts2默认无法解析。因为请求的JSON数据需从输入流中读取出来,无法直接从ServletRequest的请求参数中解析。很容易想到,要读取JSON请求数据,最直接的方式就是从输入流读取。而同时,Struts2的strus2-json-plugin也提供了有关的拦截器,对JSON请求数据进行解析。下面将对两种方案进行分析:

1.从输入流中读取JSON请求数据,以下是在Action中实现的一个读取输入流数据的方法

1     //解析请求的Json数据 2     private String getRequestPostData(HttpServletRequest request) throws IOException 3         int contentLength = request.getContentLength(); 4         if(contentLength<0) 5             return null; 6          7         byte buffer[] = new byte[contentLength]; 8         for (int i = 0; i < contentLength;) 9             int len = request.getInputStream().read(buffer, i, contentLength - i);10             if (len == -1) 11                 break;12             13             i += len;14         15         return new String(buffer, "utf-8");16    

在Action的execute方法中调用该方法,即可获取到请求的JSON数据。

2.使用struts2-json-plugin配置

    添加struts2-json-plugin的依赖,以maven配置为例:

    <dependencies>
      ...   <dependency>
          <groupId>org.apache.struts</groupId>
          <artifactId>struts2-json-plugin</artifactId>
          <version>STRUTS_VERSION</version>
      </dependency>
      ...</dependencies>

    struts.xml配置文件添加JSON配置(粗体部分)

    <package name="example"  extends="struts-default,json-default">
       ...    <interceptor-ref name="json"/>
       ... </package>

    在Action中指定JSON数据中各个key及getter, setter,如请求的JSON数据如下,则在Action中定义名为type, message, code的属性及其getter, setter

       "type":10,    "message": "this is a test msg",    "code": 200

    这样,在接收到以上JSON请求数据时,Struts会默认将type, message, code的值解析出来。

    3.struts2-json-plugin解析JSON请求数据的分析

    经过分析,struts2-json-plugin解析JSON请求数据,最核心的一个类是JSONIntercepter类。该拦截器的主要工作就是:读取JSON请求数据,将JSON数据提取出K-V值并设置到Action的属性中。步骤如下:

    判断当前请求数据类型是否为JSON类型

    1 String contentType = request.getHeader("content-type");2 ...3 if ((contentType != null) && contentType.equalsIgnoreCase("application/json")) 4     // load JSON object5     Object obj = JSONUtil.deserialize(request.getReader());6     ...7

    如果数据类型为JSON,从输入流中读取JSON数据,以下为JSONUtil类的deserialize方法

    1     public static Object deserialize(Reader reader) throws JSONException 2         // read content 3         BufferedReader bufferReader = new BufferedReader(reader); 4         String line; 5         StringBuilder buffer = new StringBuilder(); 6  7         try 8             while ((line = bufferReader.readLine()) != null) 9                 buffer.append(line);10             11         catch (IOException e) 12             throw new JSONException(e);13         14 15         return deserialize(buffer.toString());16    

    解析得到JSON对象后,遍历JSON对象,取出K-V,通过反射的V设置给予K相同的属性

    开发者可根据自己的需求进行选择:从输入流直接读取JSON请求数据,或使用struts2-json-plugin对JSON请求数据进行处理。

如何在 Struts 2 应用程序中读取文本文件 [重复]

【中文标题】如何在 Struts 2 应用程序中读取文本文件 [重复]【英文标题】:How can one read a text file in a Struts 2 app [duplicate] 【发布时间】:2010-12-19 12:16:17 【问题描述】:

开发 Struts 2 应用程序我遇到了以下问题。我需要使用我的应用程序读取部署在 Web 服务器中的文本文件。我怎样才能知道它的相对路径来访问它。换句话说,如果我知道部署目录中的相对路径,我怎么能找到绝对路径。 当我遇到与 servlet 类似的问题时,我曾经使用 this.getContextPath() (或类似的东西)返回网络服务器中文件夹的绝对路径。

编辑: 谢谢大家的回答。对我来说是这样的:

String path=GetPointsOfInterestAction.class.getResource("../../../resources/visitor_attractions.txt")

您能否解释一下为什么我会成功,因为我是在 java 中迈出第一步。

【问题讨论】:

【参考方案1】:

如果它放在 webapp 的类路径中,那么只需使用:

InputStream input = servletContext.getResourceAsStream("file.txt");

如果放在全局类路径中,则使用:

InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt");

如果是放在网页内容中,那么就用:

InputStream input = new FileInputStream(servletContext.getRealPath("file.txt"));

这些示例假定它们位于根目录中。您当然可以使用相对路径,而不是类路径根或 webcontent 根,例如path/to/file.txt。您可以通过ServletActionContext#getServletContext() 获取Struts 中的ServletContext

编辑:您使用以下内容编辑了您的问题:

编辑:谢谢大家的回答。对我来说是这样的:

String path=GetPointsOfInterestAction.class.getResource("../../../resources/visitor_attractions.txt")

请解释一下原因

这实际上不是“正确”的方式,但这也是可行的。您只需确保您知道文件的相对路径,而不是GetPointsOfInterestAction 类的实际路径。这个类当然放在不同的包中,所以您基本上需要退回一个目录(就像您在普通磁盘文件系统中所做的那样:cd ../ 等等)。同样,这不是最优雅的方式。您需要使用上述前两种方式之一,资源名称为resources/visitor_attractions.txt

【讨论】:

【参考方案2】:

Here

ServletActionContext.getServletContext()

你似乎知道从那里做什么。

【讨论】:

是的。如果我尝试以常量读取它会返回 null 的问题。这似乎是一个错误的设计决定。【参考方案3】:

您可以使用Resource Bundle。我用它们来查找属性文件。我相信该目录只需要在 Classpath 上,ResourceBundle 就会找到它。

【讨论】:

【参考方案4】:

如果文件在类路径上(不清楚,但这是个好主意),我建议使用实用程序 classorg.apache.struts2.util.ClassLoaderUtils。从它的java文档:

这个类对于以跨不同应用服务器的容错方式加载资源和类非常有用。

特别注意ClassLoaderUtils.getResourceAsStream(String resourceName, Class callingClass) 静态方法,它是一种将资源作为流加载的便捷方法。如文档所述,用于查找资源的算法在getRessource() 中给出:

此方法将尝试加载 资源使用以下方法 (按顺序):

来自Thread.currentThread().getContextClassLoader() 来自ClassLoaderUtil.class.getClassLoader() 来自callingClass.getClassLoader()

【讨论】:

以上是关于struts2 怎样读取json数据的主要内容,如果未能解决你的问题,请参考以下文章

js怎样读取json里面的数据

怎么用jsp生成json格式数据,然后用js又怎样读取其数据?

Java如何读取网址中的json内容

layui 利用ajax冲获取到json 数据后 怎样进行渲染

node.js怎样删除json数据

js怎样生成json的数据?