How can I get the directory of my deployed web application? - servlets

How to get current working directory for struts2 web application?
String currentDir = System.getProperty("user.dir");
String currentDir = new File(".").getAbsolutePath();
return /usr/share/tomcat.
I need path to web application, so I could read a file from war.

You need to get the ServletContext's real path: ServletContext.getRealPath(String)
That said, why do you want to read a file that's in a war file, and why do you want to do it this way?
Prefer putting the file on the classpath and using getResourceAsStream:
API
Docs

Related

Read an excel file in ASP.NET Core hosted in Azure

I have an endpoint that should return a value from an excel file.
On localhost this works by enabling UseStaticFiles middleware using this code, and adding excel file into the Resources folder:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "Resources")),
RequestPath = "/Resources"
});
However when I publish it in the Azure hosting it shows this error and I cannot acces my application nor this excel file.
After I remove the UseStaticFiles middleware, application works well except for the missing excel file.
So how should I publish and access this file in the Azure environment?
The UseStaticFiles method only, and I quote, "Enables static file serving". This does not enable you to return a value from a specific cell in an Excel file.
If you're looking for serving static files you could for instance have a look at putting the file in Azure Storage and using the desired public access level.
If you're looking to read from an Excel file, you might want to have a look at a way to do so that does not require Interop since you will not have Excel available on an App Service.
On option would be to use the OpenXML XML SDK.
The SDK is built on the System.IO.Packaging API and provides strongly-typed classes to manipulate documents that adhere to the Office Open XML File Formats specification.
[...]
The Open XML file formats are useful for developers because they are an open standard and are based on well-known technologies: ZIP and XML.
Another would be an open source solution like ClosedXML which is a wrapper around OpenXML making working with them easier.
ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API.
I combined Clean Windows Azure Website and Accessing wwwroot folder to come up with the solution.
No middleware is required, just by using IWebHostEnvironment service I could access needed excel file, which is now based in the wwwroot/Resources/ directory within my project.
private readonly IWebHostEnvironment _env;
public ProjectService(IWebHostEnvironment env)
{
_env = env;
}
public double GetExcelValue()
{
string excelFilePath = Path.Combine(_env.WebRootPath, "Resources/file.xlsx");
(...)
}

Entity Framework migration: access sql file within ASP.NET

I have a ASP.NET Web API project. I'm using Entity Framework Migrations. Currently, I have a custom script that is to be executed during a migration. I'm using the SqlFile method for this:
SqlFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Migrations/Scripts/MyCustomScript.sql"));
This works fine in the integration tests, IF I set the "Copy to Output Directory" of the script to "Copy always".
However, when running the website, the script is copied to <websiteroot>\bin\Migrations\MyCustomScript.sql, while AppDomain.CurrentDomain.BaseDirectory points to the websiteroot. Therefore, an error is thrown stating that the script cannot be found: it resides in the bin folder, not in the root.
How can I load the script so that things work both in the tests and in the actual website?
I would include the script in you dll and than load the script from the dll directly. Than you do not need any if statements and you always know you have the correct scripts included. Set the build action to Embedded resource. Then you can get the script like:
Assembly assembly = Assembly.LoadFile(dll);
using (Stream stream = assembly.GetManifestResourceStream(resourcepath))
using (StreamReader reader = new StreamReader(stream))
{
string script = reader.ReadToEnd();
I would fix it this way (it's not the best way, but it's a way)
string sqlfilepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Migrations/Scripts/MyCustomScript.sql");
if (!File.Exists(sqlfilepath))
sqlfilepath = "your other path where it might exist";

How to save generated file temporarily in servlet based web application

I am trying to generate a XML file and save it in /WEB-INF/pages/.
Below is my code which uses a relative path:
File folder = new File("src/main/webapp/WEB-INF/pages/");
StreamResult result = new StreamResult(new File(folder, fileName));
It's working fine when running as an application on my local machine (C:\Users\userName\Desktop\Source\MyProject\src\main\webapp\WEB-INF\pages\myFile.xml).
But when deploying and running on server machine, it throws the below exception:
javax.xml.transform.TransformerException:
java.io.FileNotFoundException
C:\project\eclipse-jee-luna-R-win32-x86_64\eclipse\src\main\webapp\WEB INF\pages\myFile.xml
I tried getServletContext().getRealPath() as well, but it's returning null on my server. Can someone help?
Never use relative local disk file system paths in a Java EE web application such as new File("filename.xml"). For an in depth explanation, see also getResourceAsStream() vs FileInputStream.
Never use getRealPath() with the purpose to obtain a location to write files. For an in depth explanation, see also What does servletcontext.getRealPath("/") mean and when should I use it.
Never write files to deploy folder anyway. For an in depth explanation, see also Recommended way to save uploaded files in a servlet application.
Always write them to an external folder on a predefined absolute path.
Either hardcoded:
File folder = new File("/absolute/path/to/web/files");
File result = new File(folder, "filename.xml");
// ...
Or configured in one of many ways:
File folder = new File(System.getProperty("xml.location"));
File result = new File(folder, "filename.xml");
// ...
Or making use of container-managed temp folder:
File folder = (File) getServletContext().getAttribute(ServletContext.TEMPDIR);
File result = new File(folder, "filename.xml");
// ...
Or making use of OS-managed temp folder:
File result = File.createTempFile("filename-", ".xml");
// ...
The alternative is to use a (embedded) database or a CDN host (e.g. S3).
See also:
Recommended way to save uploaded files in a servlet application
Where to place and how to read configuration resource files in servlet based application?
Simple ways to keep data on redeployment of Java EE 7 web application
Store PDF for a limited time on app server and make it available for download
What does servletcontext.getRealPath("/") mean and when should I use it
getResourceAsStream() vs FileInputStream
just use
File relpath = new File(".\pages\");
as application cursor in default stay into web-inf folder.

c# get path for directory in project

I'm trying get the path of a folder in my project called EmailAttachments. I tried
File.Exists("~/EmailAttachments/TestReport.pdf")
but that returns false. How can I get the path to a directory in the program so I can write files to it and retrieve them later?
This is in asp.net, not winforms
If you're trying to get the ASP.NET local path, use Server.MapPath("~/EmailAttachments/TestReport.pdf") to get its fully qualified path.

SubSonic connection string for SQLite

I'm writing a desktop app which needs a simple persistence layer - I found out about SubSonic and it's capability to work with SQLite. However I need to keep the database file in user's AppData folder and don't know how to put such value into app.config - I don't want to use absolute paths.
Can app.config somehow access enviroment variables or reference application data folder?
For subsonic v2.x I would ignore the app.config connection string and just set it at runtime before working with the database. The provider name stays the same of course.
string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), #"MyApplication\Northwind.db3");
DataService.Providers["Northwind"].DefaultConnectionString =
String.Format(#"Data Source={0};Version=3;New=False;Connection Timeout=3", dbPath);
There's no way to specify the AppData folder in the app.config for a connections string.
But what you could do is write the value to the config file either during install or when the application is first run.
The "framework way" of finding appdata is to use Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
This will find the correct appdata path regardless of platform.
There are several ways if you are using ASP.NET , in either language
Server.MapPath("~") will return the root of the application as a full path name then you can just add "/app_data" to it to get you're full path.
Alternatively inspect the HttpContext.Current.Request and HttpContext.Current.Application
there are numerous ( and much better then the one I just mentioned ) properties that will provide you with the same folder - being the root of the application as s full path.
Note that these should all work even if you have the application as a virtual folder and a regular folder with an application configures in IIS on that folder
However this is only possible at runtime , so it can't really be mentioned in the app.config. you could try using relaltive paths from where the app.config is resident IE "../App_Data" or "/App_data" but I'm not sure of you're exact requirements.
Good luck

Resources