Unable to upload MultipartFile from Quarkus to Spring boot Application - spring-boot

I am facing a problem where I try to upload file from Quarkus application to Spring boot application. Uploading works but I am unable to pass filename, content-type and size with byte array.
Spring boot application is defined to receive #RequestParam("content") List<MultipartFile> content and my Quarkus Resteasy Reactive Client is defined to send #MultipartForm MyRequest myRequest
MyRequest looks like this currently:
#Data
#NoArgsConstructor
public class MyRequest {
#RestForm("type")
#PartType(MediaType.TEXT_PLAIN)
public String type;
#RestForm("content")
#PartType(MediaType.APPLICATION_OCTET_STREAM)
public byte[] content;
}
by adding #RestForm("filename") public String filename does not solve this problem.
Looking at the code at the Spring Boot end I can see that the MultipartFile is destructed to be something else...
String firstFilename = contents.get(0).getResource().getFilename()
NOTE: What I have to work with is name of the file, input stream, mime-type and size nothing more. I am aware about the reactive client not being able to upload lists.
SIDENOTE: Idea is to receive these four values and then resend the file onwards to the next api which is the Spring Boot application.

Related

Spring RestController endpoint that consumes and produces a String value returning "HTTP Status 415 – Unsupported Media Type"

I'm trying to setup a fairly simple endpoint that takes in String and produces a String. I've simplified it down to:
#RequestMapping(value="/foo",
method = RequestMethod.GET,
consumes = MediaType.TEXT_PLAIN_VALUE,
produces= MediaType.TEXT_PLAIN_VALUE)
public String foo(#RequestBody String data) {
return data;
}
I'm testing with Postman and am just getting "HTTP Status 415 – Unsupported Media Type" back. This app is running on Spring 4.1.3. I copied this endpoint into another project I have in Spring Boot, using my same Postman request (just modified the host), and it works there. So there appears to be some issue with the version of Spring this project uses. As a work-around I created a simple wrapper entity (POJO that only consists of a single String) and changed the endpoint to consume JSON/this POJO. Does anyone know specifically why it doesn't work as above and/or know of a workaround that'll let me send and receive a plain text String with this version of Spring?

How to get local to spring boot to localize messages?

How do i get the local of the user so that i can send proper localized message in response pdf file? Autowiring not working properly
#Autowire
private final Local local
You can get the Local in the controller
#Controller
public ResponseEntity controllerMethod(Locale locale) {
}

How to change the maximum size for a Multipart file in spring boot?

I try to upload a song with postman but I have a error like the The field song exceeds its maximum permitted size of 1048576 bytes."
I already tried to add this configurations in the application.properties files but it doesn't work :
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
I precise that's work with files which size is < 1048576 bytes
This is my Controller:
#PostMapping("/songs")
public ResponseEntity<?> insertSong( #RequestParam(value = "title") String title, #RequestParam(value = "song") MultipartFile file) throws IOException {
Song song= new Song(title);
songService.insertSong(song, file);
return ResponseEntity.ok("song inserted");
}
This is my service:
#Service
public class SongServiceImpl implements SongService {
#Autowired
SongRepository songRepository;
#Value("${dir.songs}")
private String songsFolderPath;
#Override
public void insertSong(Song song, MultipartFile file) throws IOException
{
if(!(file.isEmpty())){
song.setSongPath(file.getOriginalFilename());
songRepository.save(song);
if (!(file.isEmpty())){
song.setSongPath(file.getOriginalFilename());
file.transferTo(new
File(songsFolderPath+song.getSong_ID()));
}
}
}
This is my message with the error:
{"timestamp":"2018-10-10T13:27:07.090+0000","status":500,"error":"Internal Server Error","message":"Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field song exceeds its maximum permitted size of 1048576 bytes.","path":"/music-service/songs"}
I use microservices and my configuration is on gitLab and is this one:
I use postman with like this to insert i file:
For spring-boot version 2.x.x give a try with below code by including http.
spring.http.multipart.max-file-size=300MB
spring.http.multipart.max-request-size=300MB
Refer set-maxfilesize
UPDATED SpringBoot 2.0.0.RELEASE
Multipart size in a web application depends on two separate settings
1) application settings: achieved by Spring Boot configuration in application.properties
//SpringBoot 2.1.2.RELEASE
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
2) server settings: this setting is above the application settings. And in Spring Boot this server configuration can be done in two ways
2.1) In embedded tomcat, as you have found at the following link EMBEDDED_TOMCAT_MAX_SHALLOW_SIZE (this is not sufficient when deploying .war file) (no need to do this in 2.1.2.RELEASE)
2.2) In standalone server: In file {TOMCAT_HOME}/conf/server.xml find part <Connector port=“8080" and add property maxSwallowSize=“-1"/>
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxSwallowSize="-1"/>
With -1 you are disabling size control on Server, and now only settings on your spring app matters
Moreover because you are working with files I think you should set your MediaType that best fits your API (in my case i had file + additional json elements)
#PostMapping(value = "/path", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
And respect the header when calling REST-API as
headers.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE)
A wild guess - you could be using spring boot 1.x and you may be trying to utilize settings from spring boot 2.x.
Correct properties for achieving desired settings for spring boot v1.x would be the following:
spring.http.multipart.max-file-size=-1
spring.http.multipart.max-request-size=-1
spring.http.multipart.enabled=true
My guess is based on the fact that you have set a different file size in your config/properties file and yet it seems you encounter default value.

Spring cloud data flow unable to find file

I have created a microservice in springboot, there is folder under resource folder and then a file under this folder
i,e.
resource
mycustomfolder
myfile.txt
I am creating a bean, which filed populated by myfile
#Value("${file-path}")
private String filePath;
#Bean
public MyBean byBean() throws IOException {
//read file path
String path = ResourceUtils.getURL(filePath).getPath();
//populated by bean
MyBean myBean = myservice.populatedMyBean(path);
return myBean;
}
filePath value is set in application.property
dataload-config-file=src/main/resources/mycustomfolder/myfile.txt
when i am executing this springboot app it's working file.
But when i am creating a jar of it and deploying with spring cloud data flow it giving me error on creating myBean
showing exception cause
Caused by: java.io.FileNotFoundException: /tmp/spring-cloud-dataflow-4865534318197521357/test-1506882530191/test.process/src/main/resources/mycustomfolder/myfile.txt (No such file or directory)
why this is happning normally working fine, but throwing error with spring-cloud-dataflow?
Spring Cloud Data Flow can only orchestrate Spring Cloud Stream (SCSt) or Spring Cloud Task (SCT) based microservice applications. It is unclear whether your Spring Boot application complies to previously mentioned frameworks.
Please use the SCSt and SCT samples for reference. If your application does comply with the SCSt/SCT programming model, it'd be better you share the source code for review.

Custom Logging Interceptor is not getting triggered

We are developing a RESTFUL services in spring framework and the log framework we are using is apache CXF.
We get the request in the form of JSON from the consumers of our services and we need to mask some of the contents of JSON before printing in the log files.
We are trying to have a custom interceptor to intercept the logger messages but the request never reaches the custom interceptor class. Can you please provide your thoughts to resolve the issue.
Below are the additional details :
public class CustomLogInterceptor extends LoggingInInterceptor {
public String transform(String originalLogString) {
// Custom logic will be here to mask the originalLogString
}
}
spring context XML changes:
The CustomLogInterceptor class is included in the spring context XML file.
Any help is greatly appreciated!

Resources