How to keep sitemap.xml out of webapp's deploy folder? - jsf-2

I'm using glassfish server 3.1.2 and jsf 2.1. Based on sitemaps.org standarts, sitemap file of entire web site should be in root folder. I will have multiple sitemaps and sitemap will change dynamically after i create new entries. I have read there, i want to use alternate docroot. But i can't create alternate docroot for root directory. I should find a solution as like as alternate docroot.

You could create a simple servlet to perform the job.
#WebServlet("/sitemap.xml")
public class SitemapServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/xml");
// You might want to add finer grained browser cache related headers.
InputStream input = new FileInputStream("/some/path/to/sitemap.xml");
OutputStream output = response.getOutputStream();
// Now just write input to output using your favorite way.
// ...
}
}

Related

How to modify Cache-Control setting in HttpResponse

My ASPNET Zero alway reload all css and js files instead of using cache. That is the reason it was too slow. So how can I change this setting value?
You can add asp-append-version="true" to the script or link tags in the razor pages where your css/js files are included.
Abp does provide dynamic scripts which are created at runtime creation. As such, there are limitations to what you can cache as discussed at https://github.com/aspnetboilerplate/aspnetboilerplate/issues/3673
I have found the reason, the ASPNET Zero disable Client cache by default. My solution is just commented a line of code as below
protected override void Application_BeginRequest(object sender, EventArgs e)
{
base.Application_BeginRequest(sender, e);
//DisableClientCache();
}
private void DisableClientCache()
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(CacheExpireDate);
Response.Cache.SetNoStore();
}

Unable to perform JNDI lookup using IBM WebSphere Application Server Liberty

I am using IBM WebSphere Application Server Liberty to perform JNDI lookup.I am pretty sure about giving right about the location of resources in the project. However, when i run this I am getting a name not found error.
Here is the code performing the lookup:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
PrintWriter out = response.getWriter();
response.setContentType("text/html");
try {
FlightService flightService = (FlightService)new InitialContext().lookup("java:comp/Web1/FlightService!com.airline.FlightService");
}
catch(Exception ex){
ex.printStackTrace();
}
if(flightService !=null){
out.println(flightService.getAirplaneModel());
out.println(flightService.getFrom());
out.println(flightService.getTo());
}
}
Here is the server.xml:
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-7.0</feature>
<feature>localConnector-1.0</feature>
</featureManager>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint httpPort="9090" httpsPort="9443" id="defaultHttpEndpoint"/>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<applicationMonitor updateTrigger="mbean"/>
<webApplication id="Web1" location="Web1-0.0.1-SNAPSHOT.war" name="Web1"/>
</server>
I am not sure , If i have to set any configuration related properties. Any help would be appreciated.
Looking at the server xml. I don't see JNDI entry being defined.
Based on the code, it should be trying to access a JNDI entry from a servlet. In this case, where do you define you JNDI entry in the first place?
I think you need the following to define the JNDI entry in the server xml
https://www.ibm.com/support/knowledgecenter/en/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/twlp_dep_jndi_refentry.html
Please give it a try

Servlet filter doesn't respond on given URL pattern

I have a JSF web application where all the pages that reside under directory web needs to be protected from unautheticatd use i.e., user should be in session to accesss these pages. I am using filter to validate the session for these pages. These pages are accessed via url like : /contextRoot/web/download.xhtml or /contextRoot/web/sign/upload.xhtml. Whereas other pages that reside outside web directory or in some other directory need not to go pass through session validation filter. My filter is like:
#WebFilter(filterName = "AuthenticationFilter", urlPatterns={"/web/*"}, dispatcherTypes = {DispatcherType.REQUEST})
public class AuthenticationFilter implements Filter {
private static final boolean debug = true;
private FilterConfig filterConfig = null;
public AuthenticationFilter() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
if (debug) {
log("AuthenticationFilter:doFilter()");
}
HttpSession session = ((HttpServletRequest) request).getSession(false);
if (session == null || session.getAttribute("username") == null) {
System.out.println("Your Session Not Active. You are redirected.");
//((HttpServletResponse) response).sendRedirect("home.xhtml");
} else {
System.out.println("Your Session is active. username : " + session.getAttribute("username"));
}
Throwable problem = null;
try {
chain.doFilter(request, response);
} catch (Throwable t) {
// If an exception is thrown somewhere down the filter chain,
// we still want to execute our after processing, and then
// rethrow the problem after that.
problem = t;
t.printStackTrace();
}
}
}
I am using urlPattern /web/* so that every page inside web directory will go pass this filter. The filter is right now just printing stuff for debugging. But whenever I am accessing page inside web directory or any other page, it is not going through filter. I also tried using /faces/web/* as urlPattern but that also didn't work. But when I put /* as urlPattern, every accessed page goes through the filter.
I am accessing page as
http://localhost:8080/CodesignWebApp/faces/web/sign/SelectServer.xhtml http://localhost:8080/CodesignWebApp/faces/web/sign/FileUpload.xhtml?signmethod=MICROSOFT
I am suspecting something wrong with urlPattern.
I am accessing page as
http://localhost:8080/CodesignWebApp/faces/web/sign/SelectServer.xhtml
http://localhost:8080/CodesignWebApp/faces/web/sign/FileUpload.xhtml
The URL pattern of a #WebFilter (and #WebServlet) must match exactly those URLs you see in browser's address bar (and thus not the disk file system paths you actually have in the server side; it's also literally called an "URL pattern", not "file pattern" or whatever).
So, all in all, just this should do, provided that /CodesignWebApp is webapp's context root:
#WebFilter("/faces/web/*")
public class AuthenticationFilter implements Filter {
// ...
}
(filter name is not relevant and request dispatcher method you specified is the default already)
A different alternative is to get rid of ancient JSF 1.0 style /faces/* mapping altogether and replace it by the JSF 2.0 style *.xhtml mapping. You don't want the endusers to see raw JSF source code when they remove /faces part from the URL, right?
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
This way you can just access the pages as follows:
http://localhost:8080/CodesignWebApp/web/sign/SelectServer.xhtml
http://localhost:8080/CodesignWebApp/web/sign/FileUpload.xhtml
And map the filter as follows:
#WebFilter("/web/*")
public class AuthenticationFilter implements Filter {
// ...
}
See also:
JSF Facelets: Sometimes I see the URL is .jsf and sometimes .xhtml. Why?

Allow IIS serving selected static files through ASP.NET pipeline

In my project we change one image depending on domain which was requested. Of course we can serve different files (css, js, html), but much more easy is to handle this one file and serve user correct one (let's call it logo.ico)
In web.config we set <modules runAllManagedModulesForAllRequests="false"> which causes that that IIS serve all static files for us.
Is there a way to add exception for `logo.ico' file?
To make example clear: when browser request http://mydomian.com/logo.ico I would like to run custom handler. For every other file I would like to use IIS native solution (which means <modules runAllManagedModulesForAllRequests="false">)
There is no way to add exception just for one file, but you could serve that image with ashx handler, for example url should look like (add your own logic to select image)
http://mydomian.com/ServeImage.ashx?image=logo.ico
And then just serve icon for that domain:
public class ServeImage : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/x-icon";
using (var fs = new FileStream(context.Server.MapPath("~/App_Data/logo.ico"), FileMode.Open))
{
fs.CopyTo(context.Response.OutputStream);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}

How to get an instance of the current HttpRequestBase outside of a Controller or View's context

What I'm doing:
I am creating an email mailing engine that takes html templates, replaces tokens with data and then sends off the mail to an SMTP server. Eventually we'll want a CMS UI on top of this to allow them to add/remove file templates or update the content in them via a CMS UI. Anyway I am putting the .htm files for the email templates inside my MVC web project and need to read their contents and get the string of HTML back to work with. If I move all this code out of my MVC project into like a utility C# project layer, the problem is then I have to worry about maintaining physical paths ("C:...\theMVCWebSiteFolder...\Email\Templates\SomeTemplate.htm") and that to me would have to be hard coded I think to keep track if you were to move the site to a different server, different hard drive partition, etc. So I'd like to be able to work with the files using the current application's context unless there's a way to do this agnostic to my MVC app and still not have to worry about having to ever change the location of the physical root every time we move folders.
I've got the following utility method I created in a utility class that sits in a folder somewhere in my ASP.NET MVC web project in just a folder (a folder outside of any view folders:
public static string GetFileData(string filePath)
{
if (!File.Exists(HttpContext.Current.Request.PhysicalApplicationPath + filePath))
throw new FileNotFoundException(String.Format("the file {0} was not found", filePath));
string text;
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);
using(StreamReader read = new StreamReader(fileStream))
text = read.ReadToEnd();
return text;
}
I'm trying to figure out why the context is turning up null here. I originally tried HttpContext.Current but current is coming up null so it can't find the current context in my Utility.cs method that sits in my MVC web project.
UPDATE:
Ok so the consensus is to use HttpRequestBase object and not the HttpContext.Current object. I still find it weird that the HttpContext.Current is null. But moving on, if my Utility.cs is outside any context of a controller or view, then how the heck do I get an instance of the current request (HttpRequestBase) to work with and send an instance that implements HttpRequestBase (I do not know what object that would be if I want to do this in the "MVC way" outside a controller or view) to this utility method?
No idea why this returns null but since it is a bad idea to tie your business layers with ASP.NET specifics I'd recommend you the following change to your method:
public static string GetFileData(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException(String.Format("the file {0} was not found", filePath));
return File.ReadAllText(filePath);
}
and then when you need to consume it from a web application:
public ActionResult Foo()
{
var result = MyClass.GetFileData(Server.MapPath("~/foo/bar.txt"));
...
}
and when you need to consume it in a WinForms application:
protected void Button1_Click(object sender, EventArgs e)
{
var filePath = Path.Combine(Environment.CurrentDirectory, "bar.txt");
var result = MyClass.GetFileData(filePath);
...
}
In a utility class I would remove the dependency on any web-related stuff.
For a path relative to the application root I would use:
Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, fileName)
which will give you what you probably want (a path relative to the web root directory in a web application; relative to the path containing the executable in a WinForms app, ...)
If want to rewrite that method in asp.net mvc way, you could rewrite it this way and remove coupling with HttpContext class
public static string GetFileData(HttpRequestBase request, string filePath)
{
if (!File.Exists(request.PhysicalApplicationPath + filePath))
throw new FileNotFoundException(String.Format("the file {0} was not found", filePath));
string text;
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);
using(StreamReader read = new StreamReader(fileStream))
text = read.ReadToEnd();
return text;
}
And generally in MVC HttpContext, HttpRequest and HttpResponse are abstracted into HttpContextBase, HttpRequestBase and HttpResponseBase accordingly

Resources