I'm trying to write a rest service to upload a file along with some other file information, using Jersey + Jackson.
Using multipart, the file is uploaded correctly, and simple fields are OK as well, but the POJO that's supposed to contain additional data, is always null.
Simplified example
POJO:
public class Test {
public String name;
public Test() {}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Application:
#ApplicationPath("myapp")
public class JerseyApp extends ResourceConfig {
public JerseyApp() {
register(MultiPartFeature.class);
register(JacksonFeature.class);
packages("com.test.rest");
// Enable Tracing support.
property(ServerProperties.TRACING, "ALL");
}
}
Service:
#Path("file")
public class FileRestService {
#POST
#Path("/upload1")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response createFile1(#FormDataParam("doc") Test doc) {
//doc is always null
return Response.ok(doc.getName()).build();
}
#POST
#Path("/upload2")
#Consumes(MediaType.APPLICATION_JSON)
public Response createFile2(Test doc) {
//doc is created ok
return Response.ok(doc.getName()).build();
}
web.xml is empty
pom.xml
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.22</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.22</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.22</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<version>1.11</version>
</dependency>
</dependencies>
Data is JSON and I'm testing with DHC/Postman, if it makes any difference.
Any idea why when using multipart, the pojo/bean is null?
See related problem here. The problem is that the Content-Type is not set for the doc part. In that post (answer) I didn't know how to set it in Postman, and I still haven't found a solution.
If you use a tool like cURL (which I'll just say is the best tool ever for REST development :-), you can make set the Content-Type of each part. If you don't know already cURL is a command like tool that you can use to make HTTP (and other protocol) requests. For example, you can do something like
curl -v -X POST http://localhost:8080/api/file \
-F 'doc={"hello":"world"};type=application/json'
This makes a POST request as multipart and sets the doc part to be of type application/json.
You will also find some useful examples of setting here
UPDATE
Another options, if you simply can't set the individual parts' Content-Type, is to set the type programmatically before deserialing. For example
#POST
#Path("/upload1")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response createFile1(#FormDataParam("doc") FormDataBodyPart part) {
part.setMediaType(MediaType.APPLICATION_JSON_TYPE);
Test doc = part.getValueAs(Test.class);
return Response.ok(doc.getName()).build();
}
Related
I used Jersey and Webflux with R2DBC. after send the POST via the postman I got this message " Cannot construct instance of reactor.core.publisher.Mono "
This is my JerseyConfiguration:
#Component
public class JerseyConfiguration
extends ResourceConfig {
public JerseyConfiguration() {
register(ProductController.class, 1);
}
}
and this is my Controller:
#Path("/v1")
#Controller
public class ProductController {
#Autowired
private ProductService productService;
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/product")
public Mono<Product> createProduct(#RequestBody Mono<Product> productMono){
return productMono.flatMap(this.productService::createProduct);
}
}
and this sis my service:
#Service
public class ProductService {
#Autowired
private ProductRepository repository;
public Mono<Product> createProduct(final Product product){
return this.repository.save(product);
}
}
and also this my pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Now, this is my problem; I got this message from the postman:
Cannot construct instance of `reactor.core.publisher.Mono` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]
Please let me know how to solve that problem.
Thank you
You cannot mix WebFlux and Jersey. You should choose one or the other, not both. They both provide an HTTP server engine, but:
Jersey is a Servlet JAX-RS implementation, it does not know anything about reactive streams, Mono, Flux, etc.
Webflux is the Spring HTTP server engine based on reactive streams and async Netty HTTP server.
If you look at Spring Boot reference documentation, section 3.5: Web, you will see that Jersey is one of the available engines, competing with other possible engines, i.e Web MVC and web reactive (webflux).
So, the answer is : Jersey is incompatible with Webflux, and you must choose between Webflux reactive Web and Spring rest annotation, or Jersey and Jax_RS without using Mono/Flux as return-type.
Note 1 : You should annotate your class with #RestController whe using webflux, so it understand that method return is the HTTP response body (see the last paragraph of reference documentation section 1.4.1: #Controller for details.
Note 2 : If you really want to use jersey, but you still require to consume Mono objects from other parts of your system, you might use one of the conversion functions provided by Reactor to return an object that jersey can work with. For example, on Mono object, you will find a toFuture() method. You could also block(), but it could be dangerous.
I am new the spring boot developement. I am trying to validate the post request by passing List from #RequestBody. Below is control class
#CrossOrigin
#RestController
#RequestMapping("/webapi/device")
#Validated
public class DeviceController extends AuthControllerImpl{
#Autowired
private DeviceServices deviceServices;
//Test Postman request 01
#PostMapping(path = "/udateDevices", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)
public ResponseEntity<Object> updateDeviceToDB( #RequestBody List<#Valid Device> device, #RequestParam("token") String token, Errors errors) {
if (errors.hasErrors()) {
return new ResponseEntity<Object>(new ErrorResponse(errors), HttpStatus.BAD_REQUEST);
}
if(isValidToken(token) != null){
DeviceControllerResponse response = deviceServices.updateDeviceToDB(device);
if (!response.isSuccess()) {
return new ResponseEntity<Object>(response, HttpStatus.BAD_REQUEST);
}
return ResponseEntity.ok(response);
}else {
return new ResponseEntity<Object>("Token has been expired/not valid.", HttpStatus.UNAUTHORIZED);
}
}
}
Below is my entity class.
import javax.validation.constraints.NotEmpty;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "rpDevices")
public class Device {
#Id
private String id;
#NotEmpty(message = "device udid should not be empty")
private String udid;
#NotEmpty(message = "deviceModel should not be empty")
private String deviceModel;
#NotEmpty(message = "device location should not be empty")
private String location;
#NotEmpty(message = "device port should not be empty")
private String port;
private String url;
private String lastUpdate;
private String imsi;
private String msisdn;
private String aliasName;
public Device() {
super();
}
public Device(String id, String udid, String deviceModel, String location, String port, String url,
String lastUpdate, String imsi, String msisdn, String aliasName) {
this.id = id;
this.udid = udid;
this.deviceModel = deviceModel;
this.location = location;
this.port = port;
this.url = url;
this.lastUpdate = lastUpdate;
this.imsi = imsi;
this.msisdn = msisdn;
this.aliasName = aliasName;
}
//Getter and setters
}
It never validates the entity and giving the below error.
{
"timestamp": 1591497348682,
"status": 500,
"error": "Internal Server Error",
"exception": "javax.validation.UnexpectedTypeException",
"message": "HV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.String'. Check configuration for 'updateDeviceToDB.device[0].port'",
"path": "/xxxx/webapi/device/udateDevices"
}
Can some one help how to validate the List directly from request boday.
https://www.baeldung.com/spring-validate-list-controller I tried this but not helps.
here are the pom dependencies
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Adding spring boot cap -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<!-- Adding spring boot security,ldap -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- starter-data-mongodb MongoRepository -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!-- javax.mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- some other stuff related to testing -- >
</dependencies>
validation-api is the specification, hibernate-validator is the implementation, simply speaking.
spring-boot-starter-web will automatically import hibernate-validator, then hibernate-validator will automatically import validation-api.
With your jar dependencies configuration, there are two version of validation-api. One is 1.1.0 imported by hibernate-validator 5.3.6 (from spring-boot-starter-web), and the other is 2.0.1 imported by your explicit declaration. validation-api 2.0.1 will be used with hibernate-validator 5.3.6, which is incompatible. Causing no validator could be found error.
When you remove validation-api 2.0.1, 1.1.0 version will be used. But javax.validation.constraints.NotEmpty not introduced with validation-api 1.1.0, so you will get another error.
Several ways to solve this problem:
remove validation-api 2.0.1, use org.hibernate.validator.constraints.NotEmpty instead of javax.validation.constraints.NotEmpty.
remove validation-api 2.0.1, upgrade spring boot version to 2.x, it will use hibernate-validator 6.x and validation-api 2.x.
keep your explicit validation-api 2.0.1 declaration. Then add another hibernate-validator 6.0.14 declaration. This case should be fully tested, cause there are maybe some Spring support issues.
I was having the similar issue, if you are using spring boot version (2.3.0) and above then validation-api wont work.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Just add the above dependency in pom.xml.
See release notes: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#validation-starter-no-longer-included-in-web-starters
The Errors parameter should follow the validated parameter:
public ResponseEntity<Object> updateDeviceToDB( #RequestBody List<#Valid Device> device, Errors errors, #RequestParam("token") String token)
This is required in order to support multiple validated parameters in a single method.
public ResponseEntity<Object> updateDeviceToDB(#Valid #RequestBody List<Device> device, #RequestParam("token") String token, Errors errors)
It is common to validate a model after binding user input to it. Spring 3 provides support for declarative validation with JSR-303. This support is enabled automatically if a JSR-303 provider, such as Hibernate Validator, is present on your classpath. When enabled, you can trigger validation simply by annotating a Controller method parameter with the #Valid annotation:
Visit This Link : https://spring.io/blog/2009/11/17/spring-3-type-conversion-and-validation/
I have a REST application using Spring Boot 2.2.4.RELEASE.
My REST controller is annotated like
#RestController
#RequestMapping("/")
My REST controller has #GetMapping, #PostMapping, etc., it works as expected.
Now I want to integrate Swagger in latest version.
https://github.com/swagger-api/swagger-core
https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Getting-started
The Maven dependencies shown there I added to my pom.xml:
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-core</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-integration</artifactId>
<version>2.1.1</version>
</dependency>
According to the 'Getting Started', just by adding the dependencies I should see the generated OpenAPI at http://localhost:8080/openapi.json but nothing shows up there.
Is Swagger (swagger-core,... in version 2.1.1) usable with Spring Boot web applications?
There is a project SpringFox, but it is not up to date. Also springdoc-openapi is available. But using Swagger directly would be my first thought.
You'll need a SwaggerConfig file in your code.
Configuration needed in Swagger for Java goes like this:
(Note that this is just the basic File and you can Configure it however you want.)
#EnableSwagger2
#Configuration
public class SwaggerConfig {
public static String bucketName;
#Value("${swagger.config.basePackage}")
public void setName(String name) {
bucketName = name;
}
#Bean
public Docket classifiedApi()
{
ArrayList<ApiKey> apiKeys=new ArrayList<>();
apiKeys.add(apiKey());
return new Docket(DocumentationType.SWAGGER_2).securitySchemes(apiKeys)
.select()
.apis(RequestHandlerSelectors.basePackage(bucketName))
.build()
.apiInfo(metaData());
}
private ApiKey apiKey() {
return new ApiKey("Api Key", Constants.JWTToken.API_KEY, "header");
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("APPNAME REST API")
.description("Spring Boot REST API for APPNAME")
.contact(new Contact("YOURNAME ", "Coming Soon ...", "CONTACT ADDRESS"))
.build();
}
}
I'm having problems to set up a global OkHttp interceptor for my #FeignClient beans. I'm not experiencing any error, but the interceptor is being ignored.
My understanding is that Spring Cloud's auto configuration should pick the OkHttpClient.Builder bean that I'm declaring and use it to create the underlying OkHttpClient instances, but I might be wrong about this.
Here are the relevant parts of my Spring app:
#SpringBootApplication
#EnableFeignClients(defaultConfiguration = FeignConfig.class)
#EnableCircuitBreaker
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class);
}
}
#Configuration
public class FeignConfig {
#Bean
public MyInterceptor myInterceptor() {
return new MyInterceptor();
}
#Bean
public OkHttpClient.Builder okHttpClientBuilder(MyInterceptor interceptor) {
return new OkHttpClient.Builder().addInterceptor(interceptor);
}
}
public class MyInterceptor implements okhttp3.Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
System.out.println("Hey there, this is my request: " + request);
Response response = chain.proceed(request);
System.out.println("Hey there, this is my response: " + response);
return response;
}
}
The intercept method above is never called. I need MyInterceptor to be a Spring bean, because I need to inject other dependencies to it.
#FeignClient(name = "myClient", fallback = MyClientFallback.class)
public interface MyClient {
// method declarations
}
#Component
public class MyClientFallback implements MyClient {
// method fallback implementations
}
Here's the relevant part of my application.properties file:
feign.hystrix.enabled = true
feign.okhttp.enabled = true
ribbon.eureka.enabled = false
ribbon.eager-load.enabled = true
ribbon.eager-load.clients = myClient
myClient.ribbon.listOfServers = <IP_LIST>
myClient.ribbon.ServerListRefreshInterval = 10000
As you see from the properties declared above, I'm not using Eureka and I'm using Ribbon to load balance my rest client. I'm also using Hystrix to enable fallback responses and I have set the feign.okhttp.enabled property to true.
Below is the info about dependecies config and versions...
Spring Boot version is 2.0.3.RELEASE and Spring Cloud version is Finchley.SR1, while OkHttp version is 3.11.0.
In my pom.xml file, I have this spring-cloud-dependencies config:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencies>
</dependencyManagement>
I have also included the following Spring Boot and Spring Cloud dependencies, along with the OkHttp dependency:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
...
</dependencies>
You should provide an OkHttpClient bean as stated in the doc:
The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled or feign.httpclient.enabled to true, respectively, and having them on the classpath. You can customize the HTTP client used by providing a bean of either ClosableHttpClient when using Apache or OkHttpClient whe using OK HTTP.
https://github.com/OpenFeign/feign/blob/master/okhttp/src/main/java/feign/okhttp/OkHttpClient.java
The solution is to let Spring auto configuration do its job.
In order for that to happen, the following dependency must be removed from the pom.xml file:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
And the following one must be manually included:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
Once this is done, everything works as expected with the provided configuration.
Solution is to use OkHttpClient. Add pom.xml dependencies:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
and configure a bean:
#Configuration
public class FeignConfiguration {
#Bean
public OkHttpClient client() {
return new OkHttpClient();
}
}
Explanation: For 401, 407 and some other HTTP-status responses, bodies are replaced with null by HTTP clients used in Open Feign by default.
From OpenFeign: Currently in the feign.Default client there is a streaming mode enabled. You can see in the sun.net.www.protocol.http.HttpURLConnection following lines of code :
if (respCode == HTTP_UNAUTHORIZED) {
if (streaming()) {
disconnectInternal();
throw new HttpRetryException (RETRY_MSG2, HTTP_UNAUTHORIZED);
}
}
So if the streaming is enabled and you have 401 HTTP response code you will get empty errorStream, because there is no initialization. The feign client will try to get the errorStream as a body because there is a check
if (status >= 400) {
stream = connection.getErrorStream();
} else { stream = connection.getInputStream(); }
I am getting below exception when i am using #RequestBody in my controller class.
But I need to use #RequestBody only for post method.
Caused by: org.springframework.web.HttpMediaTypeNotSupportedException:
Content type 'application/json' not supported
Anyone can help how to solve this issue..
you can add this annotation
#RequestMapping(method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON)
or put this dependency
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.4.3</version>
</dependency>
I was getting this in my unit tests, even though I had all the correct annotations on the Controller methods, and I was correctly setting the Content-Type in my request.
Error -
Caused by: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported
After debugging AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters , I realized there were no registered message converters that supported application/json .
#AutoConfigureMockMvc doesn't register all the converters, but #WebMvcTest does.
I changed the test annotation, and the problem was solved.
Previously I was using -
#SpringJUnitWebConfig
#ContextConfiguration
#AutoConfigureMockMvc
public class ReportControllerTests {
Now using the #WebMvcTest which registers the additional message converters.
#SpringJUnitWebConfig
#ContextConfiguration
#WebMvcTest(controllers = ReportController.class)
public class ReportControllerTests {
Firstly, Make sure that you have a correctly jackson version using:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
<version>2.8.0</version>
</dependency>
As for me, when I use the version of v2.7.6 or v2.8.7. This error came to me! And I change to v2.8.0, It work well!
Secondly, Make sure your controller code:
#RestController
#RequestMapping(value = "/user", produces = {MediaType.APPLICATION_JSON}, consumes = {MediaType.APPLICATION_JSON})
public class UserController extends GenericController<User, String> {
#RequestMapping(method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public ResponseMessage add(#RequestBody User user) {
String id = getService().insert(user);
return ResponseMessage.created(id );
}
}
RequestBody:
{
"username":"123",
"password":"123",
"name":"123",
"phone":"123",
"email":"123#qq.com",
"status":1
}
Postman :
Postman Post
Hope it helps you!
Try it without consumer and producer options in #PutMapping.
#PutMapping(value = "/lists/{ListName}/item")
add jackson-databind in pom.xml solved my problem:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
there is NO need to add consumes:
consumes = MediaType.APPLICATION_JSON_VALUE
I also faced the same issue. Now i fixed it by the following steps
In Controller
#RequestMapping(consumes=MediaType.APPLICATION_JSON_VALUE)
In pom.xml include the below dependency
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
Do you have consumes="application/json" attribute in the #RequestMapping. If not please put that in the annotation and then try. Also if that doesn't work, try using contentNegotiator, you can google it for contentNegotiation for spring.