I need to compose a spring controller (server side of course) for uploading files - when I get the file I need to run some validations.
The thing is - my clients may try to upload some really big file and I would like to run this validation based on a meta data they will supply.
What is the best practice for this?
What should be the resource they should run the validation against?
For example, the file resource may seem like this:
POST .../files
GET .../files/{id} or ../files to get all
DELETE ../files/{id}
Of course the validation will be in each method - but as I said before, I would like to enable the client to run the validation in a decoupled manner.
Thanks
Related
I am trying to host a React site from a Play Framework server. The React front-end is developed in a separate project and its build artifacts (static html/js/css/etc. files) are copied into my Play project's public folder.
Now I tried navigating to e.g. /page1 (where that's a React route), but I get a 404 because of course the server does not have such a route.
What I want is to replicate nginx's try_files $uri /index.html kind of functionality - if the path that's being asked for can be served (i.e. it corresponds to an asset the server knows about), it is served. Else, serve the contents of index.html without rewriting the url, so that React's routing can work.
I've tried getting this to work with just the routes file and also as a controller (with an if/else). I haven't been able to exactly replicate what in nginx is a one-liner. How could I do this?
As #vdebergue says, you can get a simplified version of what you want by adding a catch-all at the bottom of your conf/routes file.
However if you have other files in public that you'd like to still be served up correctly (for example, image files), you need to use something a little more powerful.
I wrote about this in my blog in July, but as per Stack Overflow convention, I'll expand upon it here as well. Basically, you can copy this Gist, which declares a FrontEndServingController.
The key functionality that this controller gives above the built-in Assets controller is that on first use, it recursively scans your public directory to find real files, so it knows when to serve them up, and when to serve up index.html (your React app).
Then you use it in your routes file like this:
GET / controllers.FrontEndServingController.index
GET /*file controllers.FrontEndServingController.frontEndPath(file)
You can do it simply in the route file. At the bottom of the file, add this catch all rule:
# your other routes above
# ...
GET /$any<.*> controllers.Assets.at(path="/public", file="index.html")
Consider a Java standalone uberjar, which acts as a HTTP server and is run as a Linux service. Some of its functionality depends on an external config file, which might change once in while.
I try to avoid restarting the app every time the config changes. How could this be properly done? I immediately thought of sending a SIGHUP. Could this be caught by java app? Or maybe there is another way to achieve this?
Assuming the configuration file is accessible on the local file system, and the location is known, why not use the Watch Service?
https://docs.oracle.com/javase/tutorial/essential/io/notification.html
I would use HTTP for sending the command to reload the config file. This will require introducing a special HTTP request (for example, a custom header X-Uberjar-Reload-Config that will trigger the operation when used with the root URI). I would set the value of that header to the MD5 or SHA1 hash of the config file, so that the reloading is performed only if the submitted hash sum matches that of the config file.
I need to load a file from within a directory in the root of a WAR using Spring
This is the directory structure
rootOfWar
--static-dir
---- my-file.css
--WEB-INF
---- classes
.....
It is a normal WAR.
In a Spring #RestController I need to be able to read and write to my-file.css file. What is the best way to get the File, ServletContextResource or?
More Details
- The location of the file is out of my control I cannot move the file.
- The jee container is Tomcat.
- The Spring version is current 4.1.6
- The Spring environment is not using XML only annotations with WebApplicationInitializer, WebMvcConfigurerAdapter and an annotation configuration class.
Is there another way to do this like specify a file as a resource in the configuration so that it is loaded by the frame work and accessible within the application?
Basically I have JEE knowledge but my Spring knowledge on best practices concerning read/write are lacking.
If you need to modify a file you should not make it part of the WAR. Store it somewhere outside the web package and reference it there. Everything else will lead to problems, especially when you deploy to Websphere which is often run in a restricted environment where writes are rejected.
But I consider overwriting files in the web path bad design, because you are likely to run into caching issues. Better write a servlet that generates the CSS you need. If you would be able to name the content that should overwrite your css file, you are also able to render this dynamically.
Something like this may be already sufficient:
#RequestMapping(value = "/my.css", produces = "text/css;charset=UTF-8")
public String showCss() {
return "<here goes your css>";
}
(This is written from my memory and not tested).
The good thing is that you can modify the css any time you want and even set caching information as needed.
I'm trying to add the following behaviour to my jersey service:
Load/Parse some files from the WEB-INF folder
Store it in a singleton for quick access through the application's life.
Right now the solution that I have working is:
Get the ServletContext for a ressource request
For each request which needs to access the files, call this method getSomething(criteria, servletContext)
I have to pass the servletContext around so that I may use it to load the ressource using method getRessourceAsStream() as otherwise, I cant get the right path. This is my main pain point.
I'd like to be able to make the server automatically do this once the server is ready in the application server but I'm unable to find where exactly this could be done. This would eliminate the need for me to always pass the servletContext around and would allow me to use that singleton in some of my custom deserializers and would make the code that uses this singleton cleaner.
Any time you find yourself wanting to do some work on startup in a Servlet application, use a ServletContextListener, specifically the contextInitialized(ServletContextEvent) method.
I have been searching on this but the info I am finding seems overly complex for what I am trying to do or involves having to specify exactly what type of file is being downloaded and use a specific Java class for that, I'm wondering if there is a way to not have to do this and to be able to use one way of doing this regardless of the file type as I am not generating the file, just taking it from where it exists in my directory. I have a set of files in a folder locally, say:
/media/files/files
and in this directory I have a variety of different files, .jpg, .doc. .xls, .png, etc and want the simplest way that I can take a given file path, retrieve it from the directory and send it back to a JSP so that it will enable the user to download the file. The info I am finding always seems to involve de-serializing from a blob, pulling from a remote location, or something like this to where the code is rather lengthy and I figure there must be a fairly simple way to do what I am trying to do given that I have the files locally and they are in regular format (not in a DB, etc)
Any advice is appreciated
EDIT Thanks to Costi I think I am on the right path now but I tried this, below, and am still not able to access the file:
I have put this in my server.xml file in my tomcat /conf:
<Context path="/files" docBase="/media/files/" />
and then tried accessing a file at http://myip:8080/files/test.txt but it is not working, in my Spring web.xml the only Servlet-mapping I have is:
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/d2/*</url-pattern>
</servlet-mapping>
Any advice is greatly appreciated
FIXED: Forgot that the server.xml in Eclipse overrides the server.xml in the tomcat server which was the issue as to why it wasn't working
If you do not want any logic wrapped around the download, you can simply make the files available as static resources, provided that the authentication/authorisation stuff is handled by the container if needed. For this to work, you simply need to map Spring DispatcherServlet so that it won't handle requests to /media/files/, one simple way to achieve this would be to have the spring servlet mapped to some extension like /.html, or have mapped to a subdirectory instead of /. This way, the container will handle requests to your /media/ stuff and it will simply serve static files.
If you need to interfere with the download somehow (for instance, if you handle auth stuff outside the container or you want to take some action prior to or after every download), then you can have a View returned from your spring controller that simply proxies the requested file to the output stream, after setting the proper headers like Content-Type, length, disposition and so on. I don't know of any such built-in view, but it's pretty easy to create one yourself and perhaps write your own ViewResolver that will return an instance of that view for file names under /media/whatever.
I hope this helps.