JAX-RS响应不符合预期

时间:2018-11-17 15:35:34

标签: java jax-rs

我实际上是在尝试扩展开源项目(逻辑文档)的REST API,以允许更新一项设置。

@Override
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@ApiOperation(value = "Uploads a document", notes = "Creates or updates an existing document, if used in update mode docId must be provided, when used in create mode folderId is required. Returns the ID of the created/updated document. <br/>Example: curl -u admin:admin -H ''Accept: application/json'' -X POST -F folderId=4 -F filename=newDoc.txt -F filedata=@newDoc.txt http://localhost:8080/services/rest/document/upload")
@ApiImplicitParams({
        @ApiImplicitParam(name = "docId", value = "The ID of an existing document to update", required = false, dataType = "integer", paramType = "form"),
        @ApiImplicitParam(name = "folderId", value = "Folder ID where to place the document", required = false, dataType = "string", paramType = "form"),
        @ApiImplicitParam(name = "release", value = "Indicates whether to create or not a new major release of an updated document", required = false, dataType = "string", paramType = "form", allowableValues = "true, false"),
        @ApiImplicitParam(name = "filename", value = "File name", required = true, dataType = "string", paramType = "form"),
        @ApiImplicitParam(name = "language", value = "Language of the document (ISO 639-2)", required = false, dataType = "string", paramType = "form", defaultValue = "en"),
        @ApiImplicitParam(name = "filedata", value = "File data", required = true, dataType = "file", paramType = "form") })
@ApiResponses(value = { @ApiResponse(code = 401, message = "Authentication failed"),
        @ApiResponse(code = 500, message = "Generic error, see the response message") })
public Response upload(@ApiParam(hidden = true) List<Attachment> attachments) throws Exception {
    String sid = validateSession();
    try {
        Long docId = null;
        Long folderId = null;
        boolean release = false;
        String filename = null;
        String language = null;
        DataHandler datah = null;

        for (Attachment att : attachments) {
            Map<String, String> params = att.getContentDisposition().getParameters();
            // log.debug("keys: {}", params.keySet());
            // log.debug("name: {}", params.get("name"));

            if ("docId".equals(params.get("name"))) {
                docId = Long.parseLong(att.getObject(String.class));
            } else if ("folderId".equals(params.get("name"))) {
                folderId = Long.parseLong(att.getObject(String.class));
            } else if ("release".equals(params.get("name"))) {
                release = Boolean.parseBoolean(att.getObject(String.class));
            } else if ("filename".equals(params.get("name"))) {
                filename = att.getObject(String.class);
            } else if ("language".equals(params.get("name"))) {
                language = att.getObject(String.class);
            } else if ("filedata".equals(params.get("name"))) {
                datah = att.getDataHandler();
            }
        }

        long documentId = super.upload(sid, docId, folderId, release, filename, language, datah);

        return Response.ok("" + documentId).build();
    } catch (Throwable t) {
        log.error(t.getMessage(), t);
        return Response.status(500).entity(t.getMessage()).build();
    }
}

当我安装logicaldoc的二进制发行版时,我可以使用REST端点。

现在,当我下载源代码并从源代码构建它时,我的响应始终包含以下内容:

javax.ws.rs.core.Response $ ResponseBuilder.status(ILjava / lang / String;)Ljavax / ws / rs / core / Response $ ResponseBuilder;

通常它应该包含新的documentId作为字符串。

在Eclipse中调试时,java代码中的documentId包含新的documentId作为长值(例如119)。

有人可以给我一些提示吗?

谢谢。

在C#控制台应用程序中,有趣的部分看起来像这样

            var contents = result.Result.Content.ReadAsStringAsync().Result;
            Console.WriteLine("created documentID: " + contents);

内容之前包含documentId。现在,它返回该对象描述字符串。

根据要求:这是用于上载我所有扫描文档的完整控制台应用程序代码。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

using LogicalDocHotFolder.Util;

using LogicalDocHotFolder.Models;
using System.Data;

using Z.EntityFramework.Plus;
using System.Data.Common;
using System.Data.SqlClient;

namespace LogicalDocHotFolder
{
    class Program
    {
        static void Main(string[] args)
        {
            long? importAttributeTemplateId = null;
            long tmp;

            if (Int64.TryParse(ConfigurationManager.AppSettings["LogicalDocAttributeTemplateId"], out tmp)) {
                importAttributeTemplateId = tmp;
            }

            long importFolderId = Int64.Parse(ConfigurationManager.AppSettings["LogicalDocImportToFolder"]);

            string baseAddress = ConfigurationManager.AppSettings["LogicalDocCaseURL"];
            string logicalDocUser = ConfigurationManager.AppSettings["LogicalDocUser"];
            string logicalDocPassword = ConfigurationManager.AppSettings["LogicalDocPassword"];

            string path = ConfigurationManager.AppSettings["LogicalDocImportFromFolder"];
            string username = ConfigurationManager.AppSettings["ImportFromFolderUser"]; 
            string password = ConfigurationManager.AppSettings["ImportFromFolderPassword"]; 

            FileInfo[] files = GetFileInfos(path, username, password);

            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri(baseAddress);

            var byteArray = Encoding.ASCII.GetBytes(logicalDocUser + ":" + logicalDocPassword);
            var header = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
            client.DefaultRequestHeaders.Authorization = header;
            client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/plain");//ACCEPT header
            // That is important for LD 7.7.2 and LD 7.7.3 (unlessy you apply the patch BasicAuthenticationFilter)
            client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "C# service");//User-Agent header



            foreach (FileInfo fi in files.OrderBy(f => f.CreationTimeUtc))
            {
                var contentmp = new MultipartFormDataContent();

                contentmp.Add(new StringContent(String.Format("{0}", importFolderId)), "folderId");
                contentmp.Add(new StringContent("de"), "language");

                FileStream fstream;

                try
                {
                    fstream = fi.Open(FileMode.Open, FileAccess.Read);
                } catch
                {
                    continue;
                }


                contentmp.Add(new StringContent(fi.Name), "filename");
                //contentmp.Add(new StringContent(fi.CreationTimeUtc.ToString("yyyy-MM-dd HH:mm:ss")), "date");

                contentmp.Add(new StreamContent(fstream), "filedata", fi.Name);

                var result = client.PostAsync("/test/services/rest/document/upload", contentmp);
                Console.WriteLine(result.Result.ToString());


                var contents = result.Result.Content.ReadAsStringAsync().Result;
                Console.WriteLine("created documentID: " + contents);

                long newId = Convert.ToInt64(contents);

                fstream.Close();

                using (LogicalDoc81HotFolderEntities ctx = new LogicalDoc81HotFolderEntities())
                {
                    hf_importinfo info = new hf_importinfo();
                    ctx.hf_importinfo.Add(info);

                    info.ld_Id = newId;
                    info.file_date = fi.CreationTimeUtc;
                    info.file_name = fi.Name;
                    info.import_folder = importFolderId;
                    info.last_modified = fi.LastWriteTimeUtc;
                    info.origin_path = fi.FullName;

                    ctx.SaveChanges();

                }

            }
        }



        private static FileInfo[] GetFileInfos(string path, string username, string password)
        {

            using (UNCAccessWithCredentials network = new UNCAccessWithCredentials())
            {

                network.NetUseWithCredentials(path, username, null, password);

                DirectoryInfo di = new DirectoryInfo(path);

                return di.GetFiles();


            }
        }

    }
}

2 个答案:

答案 0 :(得分:0)

通常,在JAX-RS中,将有一些提供程序将自动进行POJO <-> JSON转换。

在您的情况下,由于缺少JSON映射器,可能是您或默认情况下正在完成toString()。

我通常使用Jersey实现JAX-RS。泽西岛可以使用Jackson启用自动转换。

您可以查看本教程以了解更多信息: https://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/

Maven依赖关系必须正确,并且应该启用POJO映射功能(在web.xml中)。

注意: 由于是以声明方式添加的,因此可能很难调试。 但是,如果启用了该功能,但仍然缺少类,我希望它会引发一些异常。

答案 1 :(得分:0)

我找到了解决方法。

我需要将javax软件包降级到2.0.1版,现在它又可以工作了。

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0.1</version>
</dependency>