spring boot swagger request param time - spring-boot

Using:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.11</version>
</dependency>
In controller I have this request param setup:
#RequestParam(value = "end_time", required = false) #DateTimeFormat(iso = DateTimeFormat.ISO.TIME) LocalTime endTime)
In swagger it is required string($date-time), how to make it string($time)?
For date I use #DateTimeFormat(iso = DateTimeFormat.ISO.DATE) and it is working right.

Related

Springdoc (OpenAPI 3) SpringBoot not generated correctly

In a spring boot app with kotlin using the controller
// #PostMapping("/:csv", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) // variant 1
#PostMapping("/:csv") // variant 2
fun processKontoCsvFile(
#RequestPart("revenues") #NotNull fileWithRevenues: MultipartFile,
#RequestParam("bank") #NotNull bank: Bank
): ResponseEntity<String> {
return ResponseEntity.ok().body(bank.name + " " + fileWithRevenues.name);
}
the openapi is not generated correctly. Either the multipart file cannot be used as a selct (variant 2 above) or the enumeration value for variable bank (variant 1). See attached pictures.
Dependencies used, no extra configuration:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-data-rest</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-kotlin</artifactId>
<version>1.6.11</version>
</dependency>
What is needed to make that work?
Update:
It works with a PathVariable like so. But still don't know why not with a RequestParam
#PostMapping("/{bank}/:csv", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
fun processKontoCsvFile(
#RequestPart("revenues") #NotNull fileWithRevenues: MultipartFile,
#PathVariable("bank") #NotNull bank: Bank
): ResponseEntity<String> {
return ResponseEntity.ok().body(bank.name + " " + fileWithRevenues.name);
}

Spring Boot Validation is not working with javax.validation

I am working on a Spring Boot project and I am currently trying to implement validation. For example, I have the following class:
package abcdef.mypackage
import java.util.*
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.validation.constraints.Email
import javax.validation.constraints.NotBlank
#Entity
class User (
#Id
#GeneratedValue
var id: Long,
#Column(name="username", unique = true, nullable = false)
#NotBlank
var username: String,
#Column(name="password", unique = false, nullable = false)
var password: String,
#Column(name="firstname", unique = false, nullable = false)
#NotBlank
var firstname: String,
#Column(name="lastname", unique = false, nullable = false)
#NotBlank
var lastname: String,
#Column(name = "birthdate", unique = false, nullable = true)
var birthdate: Date? = null,
#Column(name="email", unique = true, nullable = false)
#Email
var email: String,
#Column(name="phone", unique = true, nullable = false)
var phone: String,
)
You can see, that I have annotated all fields with the validations I want to have. Incoming requests are handled by the following controller class:
package abcdef.mypackage
import org.springframework.http.ResponseEntity
import org.springframework.validation.BindingResult
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import org.springframework.web.server.ResponseStatusException
import javax.validation.Valid
#RestController
#RequestMapping("/api/v1/users/")
#Validated
class UserResource(val service: UserService) {
#PostMapping("/register")
#Validated
fun post(#Valid #RequestBody user: User, result: BindingResult) : ResponseEntity<Unit> {
if (result.hasErrors()) {
return ResponseEntity.badRequest().build()
}
try {
service.post(user)
} catch (e: Exception) {
return ResponseEntity.badRequest().build()
}
return ResponseEntity.ok().build()
}
}
When I now make a request with for example a blank username value, Spring Boot still accepts it and stores into the database. I have found some questions (and answers) on StackOverflow about missing dependencies, but I included all of those. You can take a look at my dependecies here:
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
I have no Idea what to do to get this validation working... I cannot see any issue in my dependencies. I also tried some variations with the usage of #Valid and #Validated but nothing worked for me.
I hope somebody sees my mistake. Thanks a lot!
Example: recommend data class + #field:NotBlank and not need #Validated

How document an API that produces a file (pdf) for download on Swagger?

I'm trying to discover some way to document an API that returns a PDF (or any other file) to download.
Using Spring, my Rest resource is like this:
#Override
#GetMapping(produces = "application/pdf")
public ResponseEntity<InputStreamResource> find(
#PathVariable long id
) {
Result result = service.find(id);
HttpHeaders headers = disableCache();
return ResponseEntity
.ok()
.headers(headers)
.contentLength(result.getSize())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(new InputStreamResource(result.getFileInputStream()));
}
This works very well to download the file. But I don't know the good practice to document the response using Swagger.
Actually, I tried that with Swagger annotations:
#ApiOperation(value = "Some description")
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Success.")
})
#ResponseStatus(HttpStatus.OK)
#GetMapping(produces = "application/pdf")
ResponseEntity<InputStreamResource> find(
#PathVariable long id
);
But the Swagger returns the content of InputStreamResource as Json on Swagger-ui, what is not the result.
How represent a file download on the response for Swagger?
Let try to update your code like this:
Update headers:
headers.add("Content-Type", "application/pdf");
headers.add("Content-Disposition", "attachment; filename=report.pdf");
Use this annotation:
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Success.", response = byte.class)
})
Update the pom:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
Hope it helps.
The annotations were ignored, but this worked for me:
TypeResolver typeResolver = new TypeResolver();
new Docket(DocumentationType.OAS_30)
.alternateTypeRules(AlternateTypeRules.newRule(
typeResolver.resolve(ResponseEntity.class, InputStreamResource.class),
typeResolver.resolve(Byte.class),
DIRECT_SUBSTITUTION_RULE_ORDER));

How to return JSONObject in Spring without 406 error

I am learning to use Spring, using Spring-boot.
I want to return a JSONObject from a Controller but it always return 406.
I imported a org.json.JSONObject; to create a JSONObject.
Code :
#RequestMapping(value = "/json", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public Object testJsonCall(){
JSONObject reply = new JSONObject();
reply.put("status","success");
reply.put("foo", "bar");
return reply;
}
Thanks for help.
Thanks everyone. Now I've found a solution.
Initially, I tried adding jackson-core and jackson-core-asl but it didn't make it to work.
Wierdly, I've just added toString to the return, it is working !
#RequestMapping(value = "/json", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public Object testJsonCall(){
JSONObject reply = new JSONObject();
reply.put("status","success");
reply.put("foo", "bar");
return reply.toString(); //here I added toString()
}
You need to add following jars to pom.xml.
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.4.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.1.1</version> </dependency>
<dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency>

What is the work around for Hibernate 4 persistence support for org.joda.time.contrib.hibernate.PersistentDateTime

Hi All I am new to Spring and am building application using the following dependencies
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time-hibernate</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.7.Final</version>
</dependency>
<spring.framework.version>3.1.2.RELEASE</spring.framework.version>
I am not able to persist the objects with fields with datatype DateTime from the class org.joda.time.contrib.hibernate.PersistentDateTime.
#Column(name = "LAST_MODIFIED_DATE")
#Type(type = "org.joda.time.contrib.hibernate.PersistentDateTime")
public DateTime getLastModifiedDate() {
return lastModifiedDate;
}
Can anybody suggest how to use the joda DateTime.
I had been trying this for entire day finally got the solution as the following. org.joda.time.contrib.hibernate.PersistentDateTime class persistence is not supported by higher versions of hibernate. Rather we use some very specific libraries like the
<dependency>
<groupId> org.jadira.usertype </groupId>
<artifactId> usertype.core </artifactId>
<version> 3.0.0.CR3 </version>
</dependency>
This is how we can persist the data in the database for audit purpose.
#Column(name = "CREATED_DATE")
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime getCreatedDate() {
return createdDate;
}

Resources