I want to provide a custom 404 error page in my Spring 3.1 web application, but I cannot deactivate Jetty 8's default 404 error page.
Jetty 8, out of the box, provides a default 404 error page:
when visiting a Jetty-hosted website, and providing a URL path that is not handled by any servlet (e.g. by visiting http://www.example.com/nonexisting ), Jetty responses with its own default HTML error page:
HTTP ERROR 404
Problem accessing /nonexisting. Reason:
Not Found
Powered by Jetty://
To replace this default behavior,
I've removed the DefaultHandler from my Jetty XML file,
I've edited my web.xml to include both Servlet 2.5 and Servlet 3.0 error handler locations pointing to /error,
I've set up a dedicated #Controller for handling the request to /error,
but my website still returns Jetty's own default HTML error page.
Jetty 8's official documentation talks about setting up a "custom error pages", but the suggestions there say
to configure a custom Jetty error handler (I don't want to do this, I want to do it inside my own Spring #Controller as mentioned above)
to create a "catch all context and create a "root" web app mapped to the / URI." (I don't want to do this as inside my web.xml I have already mapped Spring MVC's DispatcherServlet to /.
How can I turn off Jetty's default error handler and have the error handling be done as pointed out above?
The solution to my problem was to add a custom org.eclipse.jetty.server.handler.ErrorHandler.
If a user doesn't explicitly specify some ErrorHandler, the Jetty server instance seems to register a default ErrorHandler.
As outlined on https://www.eclipse.org/jetty/documentation/jetty-9/index.html#custom-error-pages, to register a custom ErrorHandler, you can follow the following steps.
Implement some org.eclipse.jetty.server.handler.ErrorHandler subclass, e.g. com.example.CustomErrorHandler.
Make this subclass available to your Eclipse server instance, e.g. by bundling CustomErrorHandler in a jar file and then copying that jar file into the ${jetty.base}/lib/ext directory.
Configure your Jetty server instance to have this custom ErrorHandler registered as a bean:
file jetty.xml:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- more configuration -->
<Call name="addBean">
<Arg>
<New class="com.example.CustomErrorHandler">
<Set name="server"><Ref refid="Server" /></Set>
</New>
</Arg>
</Call>
</Configure>
Here's how to define custom error pages -
http://wiki.eclipse.org/Jetty/Howto/Custom_Error_Pages
Related
The Favicon Generator assembles a package for webmasters to use in order to have icons available for many different devices. The page comes with a file called site.manifest which is linked to via the following tag in the web page's document <head>:
<link rel="manifest" href="site.webmanifest">
According to Mozilla: "The web app manifest provides information about an application (such as name, author, icon, and description) in a JSON text file. The purpose of the manifest is to install web applications to the homescreen of a device, providing users with quicker access and a richer experience."
Unfortunately if you are using Microsoft's Internet Information Services (IIS), you'll get a 404.3 error if you try and access the site.webmanifest file.
The exact error message is as follows: "The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map."
How can I properly serve site.webmanifest files in IIS?
By default, IIS does not serve any files that does not have a MIME map associated with it in its (IIS) core settings.
To address this challenge, you will need to map the .webmanifest file extension to its appropriate MIME type.
To accomplish this, open IIS and follow the steps below;
On the left hand side, select either your web site or the entire server in the "Connections" menu.
If you select the server, your MIME mapping will apply to every web site on the server.
If you select a web site, it will only apply to a single web site.
Next, select "MIME Types" from the IIS menu:
Once there, click "add..." from the right hand menu.
In the dialog box that opens specify .webmanifest in the file name extension box application/manifest+json in the MIME type box.
Click "OK".
Congratulations; you've just defined the MIME type for .webmanifest on IIS.
For Azure I added this as the web.config
<?xml version="1.0"?>
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />
</staticContent>
</system.webServer>
</configuration>
For those using ASP.NET Core (I am using 2.1) you can configure the MIME types that can be served in the application Startup.cs file as per the static files docs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();
provider.Mappings[".webmanifest"] = "application/manifest+json";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider
});
app.UseMvc();
}
Easier solution is to rename your manifest file to site.webmanifest.json and link as
<link rel="manifest" href="site.webmanifest.json">
IIS should already have a MIME Type for .json files
This is also helpful if deploying to Azure where its not so easy to change the IIS settings.
Adding to #Ben's answer: if you have a SPA you should put StaticFileOptions code into the UseSpaStaticFiles() call:
FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();
provider.Mappings[".webmanifest"] = "application/manifest+json";
app.UseSpaStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider
});
I found that the IIS server had ".json" listed in the Request Filtering feature saying it was not allowed.
Removing that allowed the file to be served.
I have a ASP.NET web application (Sitecore), and I'm supposed to handle routes that end in .html via ASP.NET. Normally, as I've read, simply adding validateIntegratedModeConfiguration="true" in /Configuration/system.WebServer/modules in web.config should suffice.
However, I'm not seeing this behaviour.
Trying "test.html" gives me the default IIS 404 page, and the code that's supposed to run, doesn't.
The app pool is already in integrated mode and the property validateIntegratedModeConfiguration is already set to true.
What am I missing here?
If your routes have been registered using Sitecore pipelines then you will need to include html in the list of Allowed extensions. Patch the config like below to include whatever extensions you require to be processed:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<preprocessRequest>
<processor type="Sitecore.Pipelines.PreprocessRequest.FilterUrlExtensions, Sitecore.Kernel">
<param desc="Allowed extensions (comma separated)">aspx, ashx, asmx, html</param>
</processor>
</preprocessRequest>
</pipelines>
</sitecore>
</configuration>
I'm using Spring MVC (Version 4.1) on Tomcat 8, and am desperately trying to make the file upload functionality work. Currently, I have a controller configured like this:
#RequestMapping(value={"/TestCase/Upload"}, method=RequestMethod.POST)
#ResponseBody
public ResponseEntity<String> uploadFile(HttpServletRequest request,
#RequestParam("file") MultipartFile file) {
System.out.println("Hit this location.");
return new ResponseEntity("Success");
}
My web.xml has the appropriate server configuration:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
<!-- Configuration for file upload (configuring Multipart file) -->
<multipart-config>
<location>/tmp</location>
<max-file-size>500000</max-file-size>
<max-request-size>505000</max-request-size>
<file-size-threshold>10485</file-size-threshold>
</multipart-config>
</servlet>
And finally, my Spring xml configuration file has the necessary resolver specified:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="500000" />
</bean>
The Apache commons-fileupload JAR is on the classpath.
I have used this approach successfully in the past on non-Tomcat servers, but now the application isn't working - but it's failing quietly. The response has a status code of 200, but nothing inside of the file upload controller method is executed. There are no exceptions thrown in the server logs, and the only way I can get the controller method to print anything out is if I remove the "Multipart" parameter entirely. At first I thought that the controller method wasn't being hit at all, but if I change the URL mapping, then the calling code throws a 404 - so it is definitely hitting the correct mapping/method - it's just that nothing inside of the method is executing (with no exceptions thrown!)
What am I doing wrong?
It turns out Spring MVC will hide noClassDef's from the console when booting itself up. The issue was that apache-commons-io.jar was missing on the classpath. Including that JAR caused everything to work properly.
So in the future if Spring is quietly misbehaving - check to ensure all necessary libraries are explicitly included, because it certainly won't tell you!
I m developing a spring web application .
I have put all my resources folder in webcontent folder and configured it in my dispatcher.xml
<mvc:resources location="/asset/" mapping="/asset/**" />
I have configured my startup page as following
<mvc:view-controller path="/" view-name="Framework/start"/>
My application is running fine and all the resources are also loading but not on the first run. Means when I deploy my application on tomcat7 and hit the url for the first time the css are not loaded also my href which is mapped to a controller is also not working but once I am logged in and logout everything works fine.
After lots of effort i concluded that the problem was not with the resource path but the problem was due to the interceptor . The authentication interceptor that i have added was called multiple times due to the request to the resources and as there was no session created till that time it was returning false.
Hence i exclude any calls to resources folder from the interceptor in the following way-
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/asset/**"/>
<bean class="com.model.AuthenticationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
Also one imp thing mvc:exclude-mapping is added from spring 3.2 onwards so one need add the schema "http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"
I have a sample application with web flows in a number of jars (extensions) and the configuration is loaded from the classpath this works fine. But I'm struggling with the view resolver configuration that will load the JSP's from the same location as the flow definitions on the classpath?
so I have the following folder structure on the classpath
MEAT-INF/config-webflow/ext1/ flow definition and JSP's for flow extension 1 are here
The web flow configuration works fine as I set this as flow-builder-services="flowBuilderServices" base-path="classpath*:/META-INF/config-webflow">
But as yet I can not come up with a view resolver configuration to load the JSP's
Any ideas?
I had the same problem. I discovered that you get the desired behaviour by NOT setting the normal Spring MVC 'viewResolver' bean on the MvcViewFactoryCreator.
<flow-builder-services id="flowBuilderServices" view-factory-creator="viewFactoryCreator" development="true" />
<beans:bean id="viewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator" />