POST JSON в теле запроса с Джерси

У меня есть динамический веб-проект на Java (развернут на локальном сервере приложений Tomcat 7), который использует Джерси для создания REST API.

Я не использую никаких инструментов автоматизации сборки (поэтому мои библиотеки добавляются в путь сборки, а сервлет вставляется в файл 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. Сценарий следующий: база данных содержит таблицу учетных записей пользователей, называемую пользователями. Столбцы ID, имя, имя пользователя и пароль.

У меня есть метод POST для проверки правильности учетной записи (имя пользователя + пароль). (имя пользователя и пароль передаются как параметры заголовка)HTTP: // локальный: 8080 / учетная_запись_пользователя / отдых / Логин / 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;        
}

Как вы можете видеть, ответ будет генерировать 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();
    }
}

Я тестирую API с помощью Advanced Rest Client из Google Chrome и REST Easy из Firefox.

Я также создал класс, который реализует 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);

и это идет на заявлении улова.

Трассировка стека следующая:

    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)

Как вы думаете?

Ответы на вопрос(1)

Ваш ответ на вопрос