问题
I am using the below AngularJS client code to perform a HTTP post request with JSON formatted payload to the jersey rest service
patientMgmtModule.controller('NewPatientCtrl',
function NewPatientCtrl($scope, $http)
{
$scope.addPatient = function (){
var patientJSON = angular.toJson($scope.Patient);
console.log("Patient (JSON) is ============> " + patientJSON);
$http({
method: 'POST',
data: $scope.Patient,
url:'/ManagePatient/AddPatient',
headers: {'Content-Type':'application/x-www-form-urlencoded;application/json;'}
});
};
} );
I have the following maven dependencies for Jersey:
<dependency>
<groupId>org.glassfish.jersey.archetypes</groupId>
<artifactId>jersey-quickstart-webapp</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.0</version>
</dependency>
On the Server Side, I have
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.hms.app.ui.beans.Patient;
@Path("/ManagePatient")
public class PatientController {
@POST
@Path("/AddPatient")
@Consumes({MediaType.APPLICATION_JSON})
public String addPatient(Patient patient) {
System.out.println("Sarat's servlet called" );
//patient.toConsole();
System.out.println("Done Calling Patient To Console");
return "Done Calling Patient To Console";
}
}
When I submit the form on the client side, I see the below error in the chrome console -
POST http://localhost:8080/HMS_Web/services/ManagePatient/AddPatient 500 (Internal Server Error) angular.min.js:99
and on the server end, I see (high level detail 1):
SEVERE: Servlet.service() for servlet [Jersey REST Service] in context with path [/HMS_Web] threw exception
org.glassfish.jersey.message.internal.HeaderValueException: Unable to parse "Content-Type" header value: "application/x-www-form-urlencoded;application/json;"
and the last stack trace has this:
Caused by: java.text.ParseException: Expected separator '=' instead of '/'
Detailed stack trace: (
Aug 01, 2013 9:28:18 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Jersey REST Service] in context with path [/HMS_Web] threw exception
org.glassfish.jersey.message.internal.HeaderValueException: Unable to parse "Content-Type" header value: "application/x-www-form-urlencoded;application/json;"
at org.glassfish.jersey.message.internal.InboundMessageContext.exception(InboundMessageContext.java:318)
at org.glassfish.jersey.message.internal.InboundMessageContext.singleHeader(InboundMessageContext.java:313)
at org.glassfish.jersey.message.internal.InboundMessageContext.getMediaType(InboundMessageContext.java:427)
at org.glassfish.jersey.servlet.WebComponent.filterFormParameters(WebComponent.java:482)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:303)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.ws.rs.ProcessingException: java.lang.IllegalArgumentException: Error parsing media type 'application/x-www-form-urlencoded;application/json;'
at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:433)
at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:427)
at org.glassfish.jersey.message.internal.InboundMessageContext.singleHeader(InboundMessageContext.java:311)
... 22 more
Caused by: java.lang.IllegalArgumentException: Error parsing media type 'application/x-www-form-urlencoded;application/json;'
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:89)
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:59)
at javax.ws.rs.core.MediaType.valueOf(MediaType.java:179)
at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:431)
... 24 more
Caused by: java.text.ParseException: Expected separator '=' instead of '/'
at org.glassfish.jersey.message.internal.HttpHeaderReader.nextSeparator(HttpHeaderReader.java:115)
at org.glassfish.jersey.message.internal.HttpHeaderReader.readParameters(HttpHeaderReader.java:261)
at org.glassfish.jersey.message.internal.HttpHeaderReader.readParameters(HttpHeaderReader.java:242)
at org.glassfish.jersey.message.internal.MediaTypeProvider.valueOf(MediaTypeProvider.java:107)
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:87)
... 27 more
Aug 01, 2013 9:29:00 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Jersey REST Service] in context with path [/HMS_Web] threw exception
org.glassfish.jersey.message.internal.HeaderValueException: Unable to parse "Content-Type" header value: "application/x-www-form-urlencoded;application/json;"
at org.glassfish.jersey.message.internal.InboundMessageContext.exception(InboundMessageContext.java:318)
at org.glassfish.jersey.message.internal.InboundMessageContext.singleHeader(InboundMessageContext.java:313)
at org.glassfish.jersey.message.internal.InboundMessageContext.getMediaType(InboundMessageContext.java:427)
at org.glassfish.jersey.servlet.WebComponent.filterFormParameters(WebComponent.java:482)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:303)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.ws.rs.ProcessingException: java.lang.IllegalArgumentException: Error parsing media type 'application/x-www-form-urlencoded;application/json;'
at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:433)
at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:427)
at org.glassfish.jersey.message.internal.InboundMessageContext.singleHeader(InboundMessageContext.java:311)
... 22 more
Caused by: java.lang.IllegalArgumentException: Error parsing media type 'application/x-www-form-urlencoded;application/json;'
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:89)
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:59)
at javax.ws.rs.core.MediaType.valueOf(MediaType.java:179)
at org.glassfish.jersey.message.internal.InboundMessageContext$5.apply(InboundMessageContext.java:431)
... 24 more
Caused by: java.text.ParseException: Expected separator '=' instead of '/'
at org.glassfish.jersey.message.internal.HttpHeaderReader.nextSeparator(HttpHeaderReader.java:115)
at org.glassfish.jersey.message.internal.HttpHeaderReader.readParameters(HttpHeaderReader.java:261)
at org.glassfish.jersey.message.internal.HttpHeaderReader.readParameters(HttpHeaderReader.java:242)
at org.glassfish.jersey.message.internal.MediaTypeProvider.valueOf(MediaTypeProvider.java:107)
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:87)
... 27 more
After implementing LoggingFilter - I see that the server is responding with HTTP 415.
Aug 04, 2013 10:28:25 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 2 * LoggingFilter - Request received on thread tomcat-http--11
2 > POST http://localhost:8080/HMS_Web/services/ManagePatient/AddPatient
2 > host: localhost:8080
2 > connection: keep-alive
2 > content-length: 341
2 > accept: application/json, text/plain, */*
2 > origin: http://localhost:8080
2 > x-requested-with: XMLHttpRequest
2 > user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36
2 > content-type: application/json
2 > dnt: 1
2 > referer: http://localhost:8080/HMS_Web/views/Landing.html
2 > accept-encoding: gzip,deflate,sdch
2 > accept-language: en-US,en;q=0.8
Aug 04, 2013 10:28:25 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 2 * LoggingFilter - Response received on thread tomcat-http--11
2 < 415
回答1:
Your Content-Type
header is invalid (see spec 14.17 Content-Type). Based on you JAX-RS resource you should use application/json
as Content-Type
(without application/x-www-form-urlencoded
):
$http({
method: 'POST',
data: $scope.Patient,
url:'/ManagePatient/AddPatient',
headers: {'Content-Type':'application/json'}
});
EDIT 1:
If you want to see requests that are coming to your server you can register LoggingFilter and it will show you some useful information. You can turn it on in:
web.xml
(add it to the JAX-RS servlet definition):
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter</param-value>
</init-param>
Application
extension:
public class MyApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
return new HashSet<Class<?>>() {{
// Add your resources.
add(HelloWorldResource.class);
// Add LoggingFilter.
add(LoggingFilter.class);
}};
}
}
ResourceConfig
instance (demonstrating also outputting the entity here):
public class MyApplication extends ResourceConfig {
public MyApplication() {
// Resources - add your package name here to enable package scanning.
packages(...);
// Enable LoggingFilter & output entity.
registerInstances(new LoggingFilter(Logger.getLogger(MyApplication.class.getName()), true));
}
}
EDIT 2:
Jersey 2.x does not support application/json
media type out of the box - you need to add one of the JSON modules to your classpath (see JSON section in users guide), for example:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.0</version>
</dependency>
来源:https://stackoverflow.com/questions/18007919/angularjs-client-jax-rs-jersey-rest-service-application-json-client-request-t