Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Creation of a sample JODConverter Rest API using spring boot.
- Loading branch information
1 parent
548f74a
commit 20d4430
Showing
7 changed files
with
359 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
## JODConverter - Sample - Rest API | ||
|
||
This is a sample application of a rest api that uses the spring boot integration module of the Java OpenDocument Converter (JODConverter) project to offer document conversion capabilities. The goal was to emulate a LibreOffice Online server that | ||
would support the customization of custom (known) load/store properties. | ||
|
||
### Running the Project using gradle | ||
|
||
First, [build the entire jodconverter project](https://github.com/sbraconnier/jodconverter#building-the-project) | ||
|
||
Then, run | ||
|
||
```Shell | ||
gradlew :jodconverter-samples:jodconverter-sample-rest:bootRun | ||
``` | ||
|
||
Once started, use your favorite browser and visit this page: | ||
|
||
``` | ||
http://localhost:8080/swagger-ui.html | ||
``` | ||
|
||
Happy conversions!! |
34 changes: 34 additions & 0 deletions
34
jodconverter-samples/jodconverter-sample-rest/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
description = 'JODConverter - Sample Rest Web Api' | ||
|
||
buildscript { | ||
ext { | ||
// Latest version -> https://mvnrepository.com/artifact/org.springframework.boot/spring-boot | ||
springBootVersion = '1.5.9.RELEASE' | ||
swaggerVersion = '2.8.0' | ||
} | ||
repositories { | ||
mavenCentral() | ||
} | ||
dependencies { | ||
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" | ||
} | ||
} | ||
|
||
apply plugin: 'java' | ||
apply plugin: 'eclipse' | ||
apply plugin: 'idea' | ||
apply plugin: 'org.springframework.boot' | ||
|
||
sourceCompatibility = 1.8 | ||
targetCompatibility = 1.8 | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
compile project(':jodconverter-spring-boot-starter') | ||
compile 'org.springframework.boot:spring-boot-starter-web' | ||
compile "io.springfox:springfox-swagger2:$swaggerVersion" | ||
compile "io.springfox:springfox-swagger-ui:$swaggerVersion" | ||
} |
214 changes: 214 additions & 0 deletions
214
...ter-sample-rest/src/main/java/org/jodconverter/sample/springboot/ConverterController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
/* | ||
* Copyright 2004 - 2012 Mirko Nasato and contributors | ||
* 2016 - 2017 Simon Braconnier and contributors | ||
* | ||
* This file is part of JODConverter - Java OpenDocument Converter. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.jodconverter.sample.springboot; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
import org.apache.commons.io.FilenameUtils; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import org.jodconverter.DocumentConverter; | ||
import org.jodconverter.LocalConverter; | ||
import org.jodconverter.document.DefaultDocumentFormatRegistry; | ||
import org.jodconverter.document.DocumentFormat; | ||
import org.jodconverter.office.OfficeException; | ||
import org.jodconverter.office.OfficeManager; | ||
|
||
import io.swagger.annotations.Api; | ||
import io.swagger.annotations.ApiOperation; | ||
import io.swagger.annotations.ApiParam; | ||
import io.swagger.annotations.ApiResponse; | ||
import io.swagger.annotations.ApiResponses; | ||
|
||
/** | ||
* Controller that will process conversion requests. The mapping is the same as LibreOffice Online | ||
* (/lool/convert-to) so we can use the jodconverter-online module to send request to this | ||
* controller. This controller does the same as LibreOffice Online, and also support custom | ||
* conversions through filters and custom load/store properties. | ||
*/ | ||
@Controller | ||
@RequestMapping("/lool/convert-to") | ||
@Api("Conversion Operations which emulate a LibreOffice Online server conversion capabilities.") | ||
public class ConverterController { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(ConverterController.class); | ||
|
||
private final OfficeManager officeManager; | ||
private final DocumentConverter defaultConverter; | ||
|
||
/** | ||
* Creates a new controller. | ||
* | ||
* @param officeManager The manager used to execute conversions. | ||
* @param defaultConverter The default converter used to execute conversions. | ||
*/ | ||
public ConverterController( | ||
final OfficeManager officeManager, final DocumentConverter defaultConverter) { | ||
super(); | ||
|
||
this.officeManager = officeManager; | ||
this.defaultConverter = defaultConverter; | ||
} | ||
|
||
@ApiOperation( | ||
"Convert the incoming document to the specified format (provided as request param) and returns the converted document.") | ||
@ApiResponses( | ||
value = { | ||
@ApiResponse(code = 200, message = "Document converted successfully."), | ||
@ApiResponse(code = 400, message = "The input document or output format is missing."), | ||
@ApiResponse(code = 500, message = "An unexpected error occured.") | ||
} | ||
) | ||
@PostMapping(produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) | ||
public Object convertToUsingParam( | ||
@ApiParam(value = "The input document to convert.", required = true) @RequestParam("data") | ||
final MultipartFile inputFile, | ||
@ApiParam(value = "The document format to convert the input document to.", required = true) | ||
@RequestParam(name = "format") | ||
final String convertToFormat, | ||
@ApiParam(value = "The custom FilterOptions to apply when loading the input document.") | ||
@RequestParam(name = "loadOptions", required = false) | ||
final String loadOptions, | ||
@ApiParam(value = "The custom FilterOptions to apply when storing the output document.") | ||
@RequestParam(name = "storeOptions", required = false) | ||
final String storeOptions) { | ||
|
||
LOGGER.debug("convertUsingRequestParam > Converting file to {}", convertToFormat); | ||
return convert(inputFile, convertToFormat, loadOptions, storeOptions); | ||
} | ||
|
||
@ApiOperation( | ||
"Convert the incoming document to the specified format (provided as path param) and returns the converted document.") | ||
@ApiResponses( | ||
value = { | ||
@ApiResponse(code = 200, message = "Document converted successfully."), | ||
@ApiResponse(code = 400, message = "The input document or output format is missing."), | ||
@ApiResponse(code = 500, message = "An unexpected error occured.") | ||
} | ||
) | ||
@PostMapping(value = "/{format}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) | ||
public Object convertToUsingPath( | ||
@ApiParam(value = "The input document to convert.", required = true) @RequestParam("data") | ||
final MultipartFile inputFile, | ||
@ApiParam(value = "The document format to convert the input document to.", required = true) | ||
@PathVariable(name = "format") | ||
final String convertToFormat, | ||
@ApiParam(value = "The custom FilterOptions to apply when loading the input document.") | ||
@RequestParam(name = "loadOptions", required = false) | ||
final String loadOptions, | ||
@ApiParam(value = "The custom FilterOptions to apply when storing the output document.") | ||
@RequestParam(name = "storeOptions", required = false) | ||
final String storeOptions) { | ||
|
||
LOGGER.debug("convertUsingPathVariable > Converting file to {}", convertToFormat); | ||
return convert(inputFile, convertToFormat, loadOptions, storeOptions); | ||
} | ||
|
||
private ResponseEntity<Object> convert( | ||
final MultipartFile inputFile, | ||
final String outputFormat, | ||
final String loadOptions, | ||
final String storeOptions) { | ||
|
||
if (inputFile.isEmpty()) { | ||
return ResponseEntity.badRequest().build(); | ||
} | ||
|
||
if (StringUtils.isBlank(outputFormat)) { | ||
return ResponseEntity.badRequest().build(); | ||
} | ||
|
||
// Here, we could have a dedicated service that would convert document | ||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { | ||
|
||
final DocumentFormat targetFormat = | ||
DefaultDocumentFormatRegistry.getFormatByExtension(outputFormat); | ||
|
||
final Map<String, Object> loadProperties = | ||
Optional.ofNullable(loadOptions) | ||
.filter(StringUtils::isNotBlank) | ||
.map( | ||
options -> | ||
Stream.of(options) | ||
.collect( | ||
Collectors.toMap(opts -> "FilterOptions", opts -> (Object) opts))) | ||
.orElse(null); | ||
|
||
final Map<String, Object> storeProperties = | ||
Optional.ofNullable(storeOptions) | ||
.filter(StringUtils::isNotBlank) | ||
.map( | ||
options -> | ||
Stream.of(options) | ||
.collect( | ||
Collectors.toMap(opts -> "FilterOptions", opts -> (Object) opts))) | ||
.orElse(null); | ||
|
||
final DocumentConverter converter = | ||
loadProperties == null && storeProperties == null | ||
? defaultConverter | ||
: LocalConverter.builder() | ||
.officeManager(officeManager) | ||
.loadProperties(storeProperties) | ||
.storeProperties(storeProperties) | ||
.build(); | ||
|
||
// Convert... | ||
converter | ||
.convert(inputFile.getInputStream()) | ||
.as( | ||
DefaultDocumentFormatRegistry.getFormatByExtension( | ||
FilenameUtils.getExtension(inputFile.getOriginalFilename()))) | ||
.to(baos) | ||
.as(targetFormat) | ||
.execute(); | ||
|
||
final HttpHeaders headers = new HttpHeaders(); | ||
headers.setContentType(MediaType.parseMediaType(targetFormat.getMediaType())); | ||
headers.add( | ||
"Content-Disposition", | ||
"attachment; filename=" | ||
+ FilenameUtils.getBaseName(inputFile.getOriginalFilename()) | ||
+ "." | ||
+ targetFormat.getExtension()); | ||
return ResponseEntity.ok().headers(headers).body(baos.toByteArray()); | ||
|
||
} catch (OfficeException | IOException ex) { | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ex); | ||
} | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
...mple-rest/src/main/java/org/jodconverter/sample/springboot/SpringBootRestApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* Copyright 2004 - 2012 Mirko Nasato and contributors | ||
* 2016 - 2017 Simon Braconnier and contributors | ||
* | ||
* This file is part of JODConverter - Java OpenDocument Converter. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.jodconverter.sample.springboot; | ||
|
||
import java.util.Collections; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
import springfox.documentation.builders.PathSelectors; | ||
import springfox.documentation.builders.RequestHandlerSelectors; | ||
import springfox.documentation.service.ApiInfo; | ||
import springfox.documentation.service.Contact; | ||
import springfox.documentation.spi.DocumentationType; | ||
import springfox.documentation.spring.web.plugins.Docket; | ||
import springfox.documentation.swagger2.annotations.EnableSwagger2; | ||
|
||
@SpringBootApplication | ||
public class SpringBootRestApplication { | ||
|
||
public static void main(final String[] args) { | ||
SpringApplication.run(SpringBootRestApplication.class, args); | ||
} | ||
|
||
@Configuration | ||
@EnableSwagger2 | ||
public class SwaggerConfig { | ||
@Bean | ||
public Docket api() { | ||
return new Docket(DocumentationType.SWAGGER_2) | ||
.useDefaultResponseMessages(false) | ||
.select() | ||
.apis(RequestHandlerSelectors.basePackage("org.jodconverter.sample.springboot")) | ||
.paths(PathSelectors.regex("/lool/convert-to.*")) | ||
.build() | ||
.apiInfo(apiInfo()); | ||
} | ||
|
||
private ApiInfo apiInfo() { | ||
return new ApiInfo( | ||
"JODConverter REST API", | ||
"JODConverter REST API for Online conversion. JODConverter automates conversions between office document formats using LibreOffice or Apache OpenOffice.", | ||
"0.1", | ||
"Terms of service", | ||
new Contact("John Doe", "www.jodconverter.org", "johndoe@company.com"), | ||
"Apache License Version 2.0", | ||
"https://www.apache.org/licenses/LICENSE-2.0", | ||
Collections.emptyList()); | ||
} | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
jodconverter-samples/jodconverter-sample-rest/src/main/resources/application.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
server: | ||
port: 8080 | ||
|
||
spring: | ||
http: | ||
multipart: | ||
max-file-size: 5MB | ||
max-request-size: 10MB | ||
application: | ||
name: JODConverter Sample Rest Api | ||
|
||
jodconverter: | ||
enabled: true | ||
|
||
logging: | ||
level: | ||
root: debug |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters