I'm working with Spring MVC on google app engine and even though I've gotten a basic hello world example working, I can't get my servlet to show up when I use the request mapping of "/". Even when I specify "/" as my request mapping in my controller, I keep getting the "Hello App Engine!" page with a link to my project. I've already pulled the welcome-file declaration out of my web xml.
Basically...
package my.package.for.spring.stuff.controllers;
import ....;
// It doesn't seem to make a difference if
// I have this reqeustmapping or not...
#Controller
public class MainController {
// If I change mapping to "/main" and then go to
// localhost:8888/main then everything works as expected
#RequestMapping("/")
public String HelloWorld() {
return "MyView";
}
}
is still going to the "Hello App Engine!" page. Also, here is my web.xml...
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>SpringAppEngine</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringAppEngine</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
And then here is my spring xml...
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="my.package.for.spring.stuff" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/main/" p:suffix=".jsp" />
</beans>
Why is the app engine generated welcome file still showing up even though I'm declaring the root mapping in my controller? I know my setup should be right because when I change the requestmapping, everything works as expected.
The servlet 3.0 spec says:
A string containing only the ’/’ character indicates the "default"
servlet of the application.
And it also says:
By default all applications will have index.htm(l) and index.jsp in
the list of welcome-file-list. The descriptor may to be used to
override these default settings.
So, I guess that the container considers that the implicit index.html welcome file is an exact match, which takes precedence over the default servlet mapped to /.
The solution is to delete the index.html file or, probably, to define an explicit empty welcome file list in the descriptor.
Apparently pulling the index.html mapping out of the web.xml isn't enough, you actually have to delete the index.html. If someone can post an answer explaining why I'll still upvote and accept.
This post helped me and I think I can expand on why removing the file fixes the problem. According the GAE, any file in the war directory (except JSPs and anything in WEB-INF) gets a mapping to that file name. This implicit mapping appears to supercede any servlet rules in web.xml:
https://developers.google.com/appengine/docs/java/gettingstarted/staticfiles
Once you remove or rename index.html, your servlet rule for "/" is used instead of the implicit mapping for the static file.
Related
I need Quarkus to serve my wasm file with Content-Type header application/wasm instead of application/octet-stream. I explicitly use the quarkus-undertow extension.
First I tried to use the undertow-handlers.conf to set the content type like this:
path-suffix('.wasm') -> set("o{Content-Type}", "application/wasm")
For other headers this works without problem, but the Content-Type seems to be overwritten by a following handler.
After this I tried to add a web.xml under src/main/resources/META-INF with a mime mapping for wasm files like this:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<mime-mapping>
<extension>wasm</extension>
<mime-type>application/wasm</mime-type>
</mime-mapping>
</web-app>
This approach doesn't seem to have any effect on the Content-Type.
What is the correct way to overwrite mime type mappings for static files in Quarkus? Why does the web.xml configuration not work?
Update
The web.xml approach from above works since Quarkus 1.1.1.Final.
Did you add the quarkus-undertow extension explicitly? Because by default, it's not present and things are served by Vert.x so you need to add a Vert.x handler instead.
I have an endpoint in Google Cloud Endpoints Frameworks for App Engine (Java). The endpoint is restricted to require an API key like this:
#ApiMethod(name = "echo", path = "echo", apiKeyRequired = AnnotationBoolean.TRUE, httpMethod = ApiMethod.HttpMethod.GET)
Which is working. However if I add a trailing slash when making the call, the endpoint returns data without an api key requirement.
I have tried to restrict api access globally in the api definition, like this:
#Api(
name = "myapi",
version = "v1",
apiKeyRequired = AnnotationBoolean.TRUE,
This however does not seem to work. I have regenerated the openapi.json and redeployed both the openapi.js and the app engine app, and the endpoint is still accessible if it has a trailing slash, but not without.
Does anyone know how I can prevent this? Any insight is much appreciated.
I was unable to solve this within Google Endpoints, so I utilized tuckey's urlrewrite to remove the trailing slashes in a filter
web.xml
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>confPath</param-name>
<param-value>/WEB-INF/urlrewrite.xml</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/_ah/api/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
urlrewrite.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.1//EN" "http://www.tuckey.org/res/dtds/urlrewrite3.1.dtd">
<urlrewrite>
<rule match-type="regex">
<note>Remove trailing slash</note>
<from>^(.*)/$</from>
<to type="redirect">$1</to>
</rule>
</urlrewrite>
more info:
http://www.tuckey.org/urlrewrite/manual/4.0/index.html
Note: as of yet, it is not redirecting properly. I'm continuing to work on that, and will post updates, but now at least I'm getting a 404 for the version with the trailing slash, rather than the response data without api key, which satisfies my security needs at the moment
I am using google app engine, and I define all my servlet paths in web.xml. Is there a way to define these in code instead of xml? I ask because the web.xml file is very verbose and I have many servlets. If I could register the servlets in java code somewhere I can probably shorten things.
Thanks
You can define a "main" servlet whose job it is to dispatch to other servlets; in your web.xml, you would write something like:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>com.mydomain.myapp.Dispatcher</servlet-class>
</servlet>
</web-app>
This would map /* (your entire app) to your dispatcher class. You could then register your various servlets with the dispatcher under different paths (e.g. you could use the Spring DispatcherServlet or your own).
I have a web application where I would like to tie a JSP to address http://host:port/status and a servlet to addresses like http://host:port/status/.... Is this possible? According to this article it should be possible ("container prefers an exact path match over a wildcard path match") at least for some containers and the Java Servlet Specification contains similar examples (albeit without wildcard, on p. 12-123 in April 2013 version), but if I try the following in web.xml it appears as if the JSP is never called and all requests (also to http://host:port/status) are routed to the servlet. My JSP and servlet are hosted on Google App Engine.
<servlet>
<servlet-name>Status</servlet-name>
<jsp-file>/Status.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>Status</servlet-name>
<url-pattern>/status</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>StatusUpload</servlet-name>
<servlet-class>com.example.StatusUploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StatusUpload</servlet-name>
<url-pattern>/status/*</url-pattern>
</servlet-mapping>
Instead of mapping the same url to two different JSPs/Servlets in web.xml you can use a URL Rewriting filter like Tuckey UrlRewriteFilter which uses a configuration file urlrewrite.xml which would also be placed in WEB-INF. It uses regex in the rules.
These two rules should do what you want:
<rule>
<from>^/status$</from>
<to>/Status.jsp</to>
</rule>
<rule>
<from>^/status/(.*)$</from>
<to>/StatusUpload/?param=$1</to>
</rule>
Then in WEB-INF you would not map the JSP anymore but would map the Servlet to StatusUpload. When the user goes to /status/postfix the URL Rewriting filter will forward to the servlet (with the postfix part passed as a parameter) in the backend without the address the user sees in the address bar changing.
In my application, i need to process all the requests from users in a single servlet, however, i happen to have a folder with static content, which i would like to also serve statically.
In my web.xml file, i have the following:
<servlet>
<servlet-name>all</servlet-name>
<servlet-class>a.b.c.WidgetlistXml</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>all</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Is there a way i can exclude, say, all .zip files from this?
PS. I know this has been asked on StackOverflow before, but the latest posts were from about 2006, and they also concerned Spring or other frameworks. I use none, and since 2006 something could have changed in url-patterns. By the way, finding the docs on web.xml is not that simple either.
Thank you in advance.
Set a DefaultServlet for your static contents. Here is an example:
http://tomcat.apache.org/tomcat-7.0-doc/default-servlet.html#where