I'm trying to download a .gz file from a NEXRAD (Next Generation Weather Radar) api with Spring Boot.
Here is the original link:
https://noaa-nexrad-level2.s3.amazonaws.com
And this is the link where the file gets downloaded automatically on hitting it:
https://noaa-nexrad-level2.s3.amazonaws.com/1991/06/05/KTLX/KTLX19910605_162126.gz
Here is the website which gives info about NEXRAD:
https://github.com/awslabs/open-data-docs/tree/main/docs/noaa/noaa-nexrad
I'm quite new to Spring Boot and I first tried hitting a random countries url and getting a json. Here is the code I wrote for it:
#RestController
public class ApiController {
#Autowired
private RestTemplate restTemplate;
private static String url = "https://restcountries.com/v3.1/all";
#GetMapping("/countries")
public List<Object> getCountries() {
Object[] countries = restTemplate.getForObject(url, Object[].class);
return Arrays.asList(countries);
}
This code works correctly where I'm able to get a json displayed on the browser on hitting the /countries url and appending it to localhost.
But now I want to hit the NEXRAD url and download the .gz file. Can anyone help on that?
You'll need a separate endpoint to download the file. Please have a look at the accepted answer to this question: download a file from Spring boot rest service
Related
I have an app with an endpoint and a tomcat server running with it. I can hit an endpoint on postman with a file and have it uploaded to an excel file on my server.
The problem is in order to get it to work I have to add allowCasualMultipartParsing="true" in the context.xml of my tomcat I don't want to have to add this fix on my local tomcat.
I need a fix that will work despite the tomcat server it's running on. So if someone were to add a new tomcat they wouldn't have this issue. For example on tomcat 9.0.6
Its hard to demonstrate the issue because it's due to running the app on a standalone tomcat. It works when I run it without the standalone tomcat 9.0.38 .
Code for uploading file
#Controller
#RequestMapping("/ListCtrl")
public class listController {
#RequestMapping(method = {RequestMethod.POST}, value = "/list")
#Consumes (MediaType.MULTIPART_FORM_DATA)
#Produces (MediaType.TEXT_XML)
#ResponseBody public Map<String, Object> uploadFile(
#FormDataParam("file") InputStream uploadedInputStream,
#FormDataParam("file") MultipartFile file,
#RequestParam("listName") String listName,
#RequestParam Integer
listid){
Map<String, Object> resultMap = null;
resultMap = new HashMap<>();
resultMap.put("status", "successful");
resultMap.put("file", file.getName());
System.out.println(file.getOriginalFilename());
return resultMap;
}
The error I'm getting on the project that isn't working is
HTTP Status 500 - Could not parse multipart servlet request; nested exception is java. lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided
I found the solution. I've seen it before but didn't fully understand so I wanted to elaborate here in case anyone else sees it. This solution will work despite the tomcat its running on.
You need to create a META-INF folder. For me I created under a deployed resources folder and I added a context.xml. After I put allowCasualMultipartParsing="true" in the context tag.
Webapp/Deployed Resources/META-INF/context.xml.
Spark Java: Unable to process parts as no multi-part configuration has been provided
It is enough if you provide a configuration. As it has been mentioned in the spring documentation, there are two concrete implementations included in Spring.
CommonsMultipartResolver for Apache Commons FileUpload and
StandardServletMultipartResolver for the Servlet 3.0+ Part API
For better flexibility and configurabilities sake, I choose to use CommonsMultipartResolver. Among the advantages, it provides maxUploadSize, maxInMemorySize, and defaultEncoding settings as bean properties. But, you have to import it as:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
And in your code:
#Configuration
public class WebConfig {
private int maxUploadSizeInMb = 2 * 1024 * 1024; // 2 MB
...
...
#Bean("multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver cmr = new CommonsMultipartResolver();
cmr.setMaxUploadSize(maxUploadSizeInMb * 2); //sum size of all files/parts of a file. Since, a file may be partitioned
cmr.setMaxUploadSizePerFile(maxUploadSizeInMb);//maximum file size of each file
return cmr;
}
}
I want to get data from JSON which is returned from URL
(http://localhost:8042/patients/)
I prepared Model in which I have all the same fields as on returned JSON.
I just wanted to get data and save it on my MongoDB, but firstly it will be okay if I can return the same JSON on my endpoint.
I tried it like below but it doesn't work.
#RestController
#RequestMapping("/test")
public class PatientController {
#GetMapping("/patient")
public #ResponseBody ResponseEntity patient() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8042/patients/123SomeId123";
ResponseEntity<Patient> responseEntity = restTemplate.getForEntity(url, Patient.class);
return responseEntity;
}
}
If as you said above your app is running inside a docker it couldn't access to localhost unless you run your docker with --network host.
If the app you are trying to access runs also in another docker container you have to ensure that both of them are on the same network and use the internal ip of docker to access it.
You can view it with the command docker inspect "name_of_container" Inside network object in the field IpAdrress
I am using Jhipster(Angular + Springboot) Application for my existing project.
I managed to create a controller(app.resource) manually apart from the ones already generated by jhiptser(using .jh file) for achieving a file download functionality.
So, when we start the server we usually initiate two servers i.e gradlew and npm start. The second runs on port 9000 which eventually supports hot reload functionality.(front-end development)
So the problem is, I am able to access those endpoints from the server running on standard 8000 port. However, from the port which is a proxy(9000), the method is returning 404.
I tried to clean build the application several times.
NOTE: The #RequestMapping value on the new controller is different then those present already.
Does this have to do something with spring security?
Thanks in advance.
Here is the previous controller:
#RestController
#RequestMapping("/api")
public class FGAppDiagramResource {
#GetMapping(value = "/fg-app-diagram-downloadFile")
public void getImage(String fileName,String folderName, HttpServletResponse
response){
// Some Code
}
}
Here is my New controller:
#RestController
#RequestMapping("/fileDownload")
public class DownloadFileController {
private final Logger log =
LoggerFactory.getLogger(DownloadFileController.class);
public DownloadFileController() {
super();
}
#Autowired
private ApplicationProperties applicationProperties;
#GetMapping(value = "/fg-app-diagram-downloadFile/{fileName}/{folderName}")
public void getImage(#PathVariable String fileName,#PathVariable String folderName, HttpServletResponse response) {
// Some Code
}
}
Your new controller does not use /api so you must add your endpoint URL /fileDownload to proxy configuration of webpack dev server in webpack/webpack.dev.js
proxy: [{
context: [
/* jhipster-needle-add-entity-to-webpack - JHipster will add entity api paths here */
'/api',
'/fileDownload',
You may want to use /api/fileDownload to avoid changing proxy configuration and also because /api is useful for many other aspects like security and also using HTML5 URL routing strategy in Angular to get rid of # in client routes (see https://github.com/jhipster/generator-jhipster/pull/9098).
/api and /management are namespaces to avoid route conflicts, so it is usually wise to use them for your new endpoints.
I'm using Spring Boot 2.0.2.RELEASE, and not being able to upload files for a REST controller endpoint.
Following this getting starter, it says:
As part of auto-configuring Spring MVC, Spring Boot will create a
MultipartConfigElement bean and make itself ready for file uploads.
So, theoretically, It should work without any additional configurations, but it looks like this MultipartConfigElement is not being configured at all.
I'm getting this warn:
WARN .a.w.r.e.DefaultErrorWebExceptionHandler: Failed to handle request [POST http://localhost:8080/upload]: Response status 400 with reason "Required MultipartFile parameter 'file' is not present"
My Spring application starter is as simple as:
#SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
And my endpoint is:
#RestController
public class MyController {
#PostMapping("/upload")
public String hash(#RequestParam("file") MultipartFile file) {
final String test = file.getContentType();
}
This is the way I'm sending with postman:
I also made sure to unmark any default content type set by postman, with no success.
What possibly am I doing wrong?
First, add this to your properties file
servlet.multipart.enabled=true
servlet.multipart.max-file-size=20M
And create CommonsMultipartResolver bean as
(name = "multipartResolver")
Same question,but I got these files by this way.
You can found these files in this github repository:
gs-uploading-files
All you need to do is just download the zip file of this application,and find the files you need.
I used Spring Boot to implement a REST application. I have one resource that is mapped like this
#RequestMapping(value = "/{fromLat}/{fromLon}/{toLat}/{toLon:.+}", method = {RequestMethod.GET},
produces = {"application/json"})
Thus the path contains coordinates and a request looks like this
$ curl -I -X GET http://localhost:8085/foobar/53.481297/9.900539/53.491691/9.946046
Unfortunatly the last end is interpreted as a file extension which leads to a response header that offers a file download instead of just the plain data.
Content-Disposition: attachment;filename=f.txt
I thought I could handle the situation with a custom WebMvcConfigurerAdapter Bean (and without #EnableWebMvc) annotation like explained here.
public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false);
}
}
But that does not do the trick. Unfortunatly the detected file extension is not fix - thus I can not use a rule for a fix extension.
How can I configure the system to just respond with the content and without the Content-Disposition header (which leads to an f.txt download)? I would not like to use a slash ("/") at the end.
I already looked at the following ressource
Spring MVC controller browser downloads "f.txt"
Add property support for configureContentNegotiation
In Spring Framework 4.1.9 and 4.2.3 the Content-Disposition header was fixed to use the "inline" type which only suggests a file download name, should the content end up being downloaded. It won't force a Save As dialog any more.
Note also that the reason for the Content-Disposition header in the first place is to protect applications against RFD attacks. This is a very complex issue but you can see a summary in the CVE-2015-5211 report.
I had similar issues with Spring Boot as described here.
What worked for me is the following configuration:
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false);
}
}
Did you try to set:
1) Content-Disposition: inline; -> you can use:
return new ResponseEntity(body, headers, statusCode); and set Content-Disposition in headers.
Look here:
How to set 'Content-Disposition' and 'Filename' when using FileSystemResource to force a file download file?
and
Return a stream with Spring MVC's ResponseEntity
2) text/x-json - Experimental MIME type for JSON before application/json got officially registered.
#RequestMapping(value = "/{fromLat}/{fromLon}/{toLat}/{toLon:.+}", method = {RequestMethod.GET},
produces = {"text/x-json"})
It will try to display the content instead of downloading it.
Hope it will help.