Ich habe ein dynamisches Web-Projekt in Java (bereitgestellt auf einem lokalen Anwendungsserver Tomcat 7), die Jersey zum Erstellen von REST-APIs verwendet.POST JSON in Body Anfrage mit Jersey
Ich verwende keine Build-Automation-Tools (meine Bibliotheken werden also zum Build-Pfad hinzugefügt und das Servlet wird in die Datei web.xml eingefügt).
Die Bibliotheken, die ich verwende, sind:
<?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>
Die Anwendung mit einer MySQL-Datenbank interagiert:
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
Mein web.xml die folgende ist. Das Szenario ist das folgende: Die Datenbank enthält eine Benutzerkontentabelle, die als Benutzer bezeichnet wird. Die Spalten sind ID, Name, Benutzername und Passwort.
Ich habe eine POST-Methode für die Überprüfung, ob ein Konto (Benutzername + Passwort) gültig sind. (Benutzername und Passwort als Header-params übergeben) http://localhost:8080/UserAccount/rest/login/doLogin und die Header: Benutzername: x Passwort: 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;
}
Wie Sie sehen können, ist die Antwort ein JSON mit wahr oder falsch erzeugen, basiert, wenn die Benutzerkonto ist gültig oder nicht. Und bis jetzt funktioniert es gut. Es funktioniert auch ein GET und übergibt die Parameter als Abfrageparameter (aber das ist nicht der Punkt).
Jetzt versuche ich, eine POST aber dieses Mal das Bestehen der Benutzername und das Passwort in einem JSON Körper zu tun:
{
"username":"x",
"password":"1234"
}
Dafür ich eine Klasse erstellt haben User.java genannt:
@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;
}
}
Und ich habe eine Methode erstellt:
//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();
}
}
ich die API am testen von Advanced REST-Client von Google-C unter Verwendung von hrome und REST Einfach von Firefox.
ich habe auch eine Klasse, die die MessageBodyReader implementiert wie folgt:
@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;
}
}
Nach Debuggen, ist das Problem kommt hier:
User user = (User) jaxbContext.createUnmarshaller().unmarshal(entityStream);
und es geht auf der catch-Anweisung.
Der Stacktrace ist die folgende:
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)
Was denken Sie?
Ich fürchte, Jersey unterstützt nicht Gson oder Jettison out of Box. Sie können ändern, um jackson zu verwenden oder Ihren eigenen Nachrichtenkörperleser und -schreiber zu schreiben. – Veeram