使用 Jersey 在正文请求中 POST JSON

2023-12-06

我有一个 Java 动态 Web 项目(部署在本地应用程序服务器 Tomcat 7 上),它使用 Jersey 来创建 REST API。

我不使用任何构建自动化工具(因此我的库被添加到构建路径中,并且 servlet 被插入到 web.xml 文件中)。

我正在使用的库是:

asm-3.1.jar
gson-2.2.1.jar
jersey-client-1.0.3.jar
jersey-core-1.0.3.jar
jersey-json-1.18.jar
jersey-server-1.0.3.jar
jettison-1.1.jar
jsr311-api-1.0.jar
mysql-connector-java-5.0.8-bin.jar

我的 web.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>UserAccount</display-name>
    <servlet>
        <servlet-name>ServletAdaptor</servlet-name>
        <servlet-class>com.sun.jersey.server.impl.container.servlet.ServletAdaptor</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletAdaptor</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

该应用程序正在与 MySQL 数据库交互。 场景如下:数据库包含一个名为 users 的用户帐户表。这些列是 id、名称、用户名和密码。

我有一个 POST 方法来验证帐户(用户名+密码)是否有效。 (用户名和密码作为标头参数传递)http://localhost:8080/UserAccount/rest/login/doLogin和标题: 用户名:x 密码:1234

@POST
@Path("/doLogin")
@Produces(MediaType.APPLICATION_JSON) 
public String doLogin(@HeaderParam("username") String uname, @HeaderParam("password") String pwd){
    String response = "";
    if(checkCredentials(uname, pwd)){
        response = Utility.constructJSON("login",true);
    }else{
        response = Utility.constructJSON("login", false, "Incorrect Email or Password");
    }
return response;        
}

正如您所看到的,响应将根据用户帐户是否有效生成一个包含 true 或 false 的 JSON。 到目前为止,它运行良好。它也可以很好地执行 GET 并将参数作为查询参数传递(但这不是重点)。

现在我尝试执行 POST,但这次在 JSON 正文中传递用户名和密码:

{
    "username":"x",
    "password":"1234"
}

为此,我创建了一个名为 User.java 的类:

@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @XmlElement(name="username")
    private String username;

    @XmlElement(name="password")
    private String password;

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "username: " + username;
    }
}

我创建了一个方法:

    //pass the arguments as JSON body
@POST
// Path: http://localhost:8080/UserAccount/rest/login/asklogin
@Path("/askLogin")
// Produces JSON as response
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response askLogin(User user) {
    System.out.println("Inside POST askLogin");
    if(checkCredentials(user.getUsername(), user.getPassword())) {
        return Response.ok().build();
    } else {
        return Response.serverError().build();
    }
}

我正在使用 Google Chrome 中的 Advanced Rest Client 和 Firefox 中的 REST Easy 来测试 API。

我还创建了一个实现 MessageBodyReader 的类,如下所示:

@Provider
public class UserBeanMessageBodyReader implements MessageBodyReader<User> {

    //used for MessageBodyReader
    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations,
            MediaType mediaType) {
        return type == User.class;
    }

    @Override
    public User readFrom(Class<User> type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
            InputStream entityStream) throws IOException, WebApplicationException {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
            User user = (User) jaxbContext.createUnmarshaller().unmarshal(entityStream);
            return user;
        } catch (JAXBException jaxbException) {
            jaxbException.printStackTrace();
            System.out.println("Error deserializing a User" + jaxbException);
        }
        return null;
    }
}

经过调试,问题来了:

User user = (User) jaxbContext.createUnmarshaller().unmarshal(entityStream);

它继续在 catch 语句中。

堆栈跟踪如下:

    INFO: Server startup in 1239 ms
javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is 

    not allowed in prolog.]
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:563)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:249)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:204)
        at ro.useraccount.jersey.UserBeanMessageBodyReader.readFrom(UserBeanMessageBodyReader.java:36)
        at ro.useraccount.jersey.UserBeanMessageBodyReader.readFrom(UserBeanMessageBodyReader.java:1)
        at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:393)
        at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:139)
        at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:43)
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:126)
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:173)
        at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:67)
        at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:163)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:71)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:63)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:654)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:612)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:603)
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:309)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:425)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:590)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:612)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:503)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
        at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1437)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:999)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:118)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
        ... 35 more
    Error deserializing a Userjavax.xml.bind.UnmarshalException
     - with linked exception:
    [org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.]
    Inside POST askLogin
    Oct 06, 2016 8:57:27 AM org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet ServletAdaptor threw exception
    java.lang.NullPointerException
        at ro.useraccount.jersey.Login.askLogin(Login.java:67)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:175)
        at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:67)
        at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:163)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:71)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:63)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:654)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:612)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:603)
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:309)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:425)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:590)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:612)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:503)
        at java.lang.Thread.run(Thread.java:745)

你怎么认为?


您应该告诉 Jersey 使用 Gson 进行 JSON 处理。您可以执行此操作MessageBodyReader and MessageBodyWriterJersey 提供的接口。 在这个堆栈溢出问题您可以找到一个示例(请参阅已接受的答案)。 如果您想为其添加一些上下文,请查看Jersey 1.x 手册的 JSON 部分

编辑 : 我可能不理解你的代码,但是你的 Gson 调用在哪里UserBeanMessageBodyReader? 尝试改变reaedFrom方法类似于

String result = new BufferedReader(new InputStreamReader(entityStream))
                 .lines().collect(Collectors.joining("\n"));
Gson gson = new GSon();
User myUser = gson.fromJson(result, User.class);

而不是使用JAXBContext(它只理解 XML 输入)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Jersey 在正文请求中 POST JSON 的相关文章

随机推荐

  • 如何在 webview 组件中检索 Javascript 函数值

    如何从 webview 组件中加载的网页中检索 Javascript 函数值 你不能直接 您可以通过以下方式调用 Javascript 函数loadUrl javascript where 是你的函数调用 但是 您无法通过这种方式得到结果
  • 为什么 snprintf 在打印单个数字时始终比 ostringstream 快 2 倍?

    我正在测试各种格式化方法doubleC 中的 s 这是我想出的一些代码 include
  • 如何在两个应用程序之间共享 Spark RDD 的数据

    在两个 Spark 作业之间共享 Spark RDD 数据的最佳方式是什么 我有一个案例 作业 1 Spark 滑动窗口流应用程序将定期消耗数据并创建 RDD 我们不想将其持久化到存储中 作业 2 查询作业将访问作业 1 中创建的相同 RD
  • MenuStrip 和 ToolStrip 上的“红十字”问题

    我有一个在许多机器上运行良好的软件 尽管在一台机器上偶尔会出现一个问题 MenuStrip 和 ToolStrip 都显示为空白的白色背景 上面有一个红色十字 作为自定义控件如果您创建了一个 null 对象 则会发生这种情况 当我调试时 这
  • 将文件保存到手机而不是 SD 卡

    在我的应用程序中 我通过执行以下操作将 XML 文件保存到用户的 SD 卡中File newxmlfile new File Environment getExternalStorageDirectory Message xml 但并非所有
  • JavaCard 的数学库?

    我目前正在开发一个 JavaCard 项目 v 2 2 2 我需要使用平方根 对数等来计算值 我知道Math类在 JavaCard API 中不可用 想知道是否存在另一个提供此类操作的库 而且我也不能用double价值观 但我需要 有没有一
  • 如何从谷歌应用程序脚本获取自动刷新谷歌电子表格自定义单元格功能[自定义功能刷新]

    在制作新工作表或更改工作表名称或复制工作表或从谷歌电子表格中删除工作表时 如何通过谷歌应用程序脚本自动刷新工作表名称的当前列表 我需要工作表名称列表 有很多张 新工作表将由其他用户添加 新工作表的名称将被其他用户更改 某些工作表将被其他用户
  • Android 检测按下电源键

    我的应用程序需要知道屏幕是否由于超时或用户单击电源按钮而关闭 我决定检查是否按下了电源按钮 我在这里读了一些问答并想出了这个 public class MyActivity extends Activity Called when the
  • mysql中的ST_Distance_Sphere没有给出两个位置之间的准确距离

    My requirement是计算distance两个之间locations在给定的map using mysql 我发现了一个函数mysql named ST 距离 球体返回球体上两个位置和 或多个位置之间的最小球面距离 以米为单位 当我
  • 跨域ajax

    我读完之后this文章 我了解的是 为了允许跨域AJAX调用 我必须将服务器响应设置为访问控制 允许孔 用于测试目的的公共 这是我的服务器代码 python中的Google Appengine self response headers a
  • 如何使用 Dio 在 Flutter 中上传多个图像/文件?

    我一直在尝试将多个图像 文件上传到 Flutter 的后端 我在用Dio 到目前为止 我还无法做到这一点 我已经能够使用邮递员做到这一点 这是表单数据 这是我的代码 Future
  • .data 和 cur_data() 之间的区别

    m lt 10 mtcars gt dplyr mutate disp data disp env m 相当于 m lt 10 mtcars gt dplyr mutate disp cur data disp env m 你能举个例子吗c
  • 我可以使浮动共享图标的垂直列表响应不同的屏幕分辨率吗? (含图片)

    我在我的一个博客上使用 addthis 我有垂直浮动列表的新选项 addthis 按钮的代码如下所示 div class addthis toolbox addthis floating style addthis 32x32 style
  • 自动传递路径参数

    我正在建立一个网站 用户可以选择他想要的国家 州和城市 一旦他选择了这些参数 他就会进入如下页面 en example com spain madrid madrid 问题是 每次我想构建一个新的 url 时 我都必须传递这 3 个变量 我
  • SWI-Prolog:将文本原子拆分为字符列表

    非常简单的问题 我知道有很多方法可以分割原子 例如在某些分隔符上分割 示例原子 例如 gt 示例 原子 但是有没有办法分割每个字符 例如 e x a o m 我试过了 atomic list concat List Atom 但这会产生错误
  • 一个块中有多个 try 代码

    我的 try 块中的代码有问题 为了简单起见 这是我的代码 try code a code b if b fails it should ignore and go to c code c if c fails go to d code d
  • 在R中构建单词共现边缘列表

    我有一大块句子 我想构建单词共现的无向边缘列表并查看每个边缘的频率 我看了一下tm包但没有找到类似的功能 有一些我可以使用的包 脚本吗 多谢 注意 单词不与其自身同时出现 出现两次或多次的单词在同一个句子中仅与其他单词同时出现一次 DF s
  • 如何在jquery中正确缓存DOM元素?

    我在从命名空间变量访问缓存的 DOM 元素时遇到一些问题 我的 FeedManager 配置变量是这样的 var FeedManager config feedContainer feedContainer feedUrl http rss
  • 使用 makecert 进行开发 SSL

    这是我的情况 我正在尝试创建一个 SSL 证书 该证书将安装在所有开发人员的计算机上 以及两个内部服务器 一切都是非生产的 我需要做什么来创建一个可以安装在所有这些地方的证书 现在 我使用 Microsoft Visual Studio 8
  • 使用 Jersey 在正文请求中 POST JSON

    我有一个 Java 动态 Web 项目 部署在本地应用程序服务器 Tomcat 7 上 它使用 Jersey 来创建 REST API 我不使用任何构建自动化工具 因此我的库被添加到构建路径中 并且 servlet 被插入到 web xml