I am trying to figure out how i am building a restFull Web server that will:
1: Serve a single index.html file when going to /
2: all other URLs will get caught by the controllers in a restful manner
for example:
/invoke1 -> will reach the request mapping of "/invoke1"
The problem:
First of all spring dispatcher has some weird fallout with serving html pages (i am not talking about resources and the <mvc:resources mapping ) i am talking about serving an html page and not JSP.
i solved this issue by using the default catalina servlet like so:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>
org.apache.catalina.servlets.DefaultServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/docs/*</url-pattern>
</servlet-mapping>
With this code i can serve HTML pages (Even behind security, as long as they are under the /docs/* path), So from here i can do:
#RequestMapping(method = RequestMethod.GET)
public String main() {
return "redirect:/docs/index.html";
}
But that's not what i want. from here on out the URL on the browser will be displayed as /docs/
What i want to happen is that when the user goes to / he will get the index.html but when he goes to /invoke1 he will reach the spring controller.
This is something i am trying to figure out for some time now. hope you can guide me to the right solution.
Thank you.
1) The easiest solution would be to map Spring to something like /rest/ and leave / for your index.html.
2) Another solution, though you did not want it, to wrap your index.html up in a JSP and serve it on /index.html and define your controller as intended.
3) Or use <mvc:resources>. You can serve .html from a predefined static directory and simply return in your index controller "static/index.html". cf. this StackOverflow Question.
In your configuration file you can define one mvc:view-controller to handle the redirect URL:
<beans xmlns:mvc="http://www.springframework.org/schema/mvc"
.....
xsi:schemaLocation="...
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
....>
<mvc:view-controller path="/index" view-name="/docs/index.html" />
....
</beans>
And you can change your main method to redirect to /index:
#RequestMapping(method = RequestMethod.GET)
public String main() {
return "redirect:/index";
}
Now when a request is made to /, it will come to the main method, which will send a redirect request to /index. The above mapping will forward a request for /index to the static view index.html. And /docs/index.html will not be present in the browser URL.
With Spring 3+ and its resource handling you can just do:
map servlet to / - all requests (excluding *.jsp) will be handled by Spring
configure Spring to serve your resources - (thus the index.html will be served by Spring)
configure index.html as your <welcome-file> in web.xml
The simple answer is you need to use forward ("forward:/") and not redirect ("redirect:/").
Related
I am new in Servlets and web.xml content. I would like to set a condition/dependency on two different servlets.
Consider I have below two servlets:
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>com.my.app.Servlet1</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>com.my.app.Servlet2</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
And I would like to invoke servlet2 only in case servlet1 encounters an error or fails. As to be a scenario: Assume servlet1 is my main authenticator and the user login failed due to missing parameter in URL in servlet1. In that case I would like to try the second authenticator servlet2 that contains different set of checks...
Can I achieve this by modifying web.xml only?
If not, what would be an alternative solution to accomplish this need?
Note: I do have the source code of servlet1 but not the servlet2 (only built jar)...
Thanks in advance.
You could do this using reuqestDispatcher and forward the request to the other servlet2 like following in Servlet 1s doPost method.
//Here URL is path to servlet 2
RequestDispatcher rd = request.getRequestDispatcher(“url”);
rd.forward(request,response);
I am redoing the URL mapping structure within my Java web application. I am trying to find the most efficient and proper way to map the servelets and resources to their proper URLs.
There are two strategies that I have been able to create, but I am not sure which is more efficient.
Mapping All urls to one Servlet which Handles the requests
In this case I have a Servlet named "URL", with the following servlet mapping:
<servlet-mapping>
<servlet-name>url</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
The url Servlet is set up like such as an example and works fine:
String task = request.getRequestURI().substring(request.getContextPath().length());
if ("/home".equals(task)){
RequestDispatcher dispatcher = request.getRequestDispatcher("/jsp/home.jsp");
dispatcher.forward(request, response);
}
The problem I initially had with this that all the static resources such as JS, Images, etc... weren't served. I had the option to create separate directories for the static content as a solution, but off the top of my head I switched to mapping it all directly in the web.xml.
Mapping it all directly in the web.xml.
In this case the url patterns are directly mapped to the JSPs and Servlets like so:
<servlet>
<servlet-name>home</servlet-name>
<jsp-file>/jsp/Home.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>home</servlet-name>
<url-pattern>/home</url-pattern>
</servlet-mapping>
Example:
localhost:8080/home <- home.jsp
localhost:8080/about <- about.jsp
localhost:8080/login <- doLogin servlet
Are these bad? Which would be a more efficient and proper way to map the urls to their intended JSP files and Servlets?
I use a combination of both, I define all the static pages in web.xml and right at the end of the web.xml, I create a catch-all that will handle dynamic pages.
So home, about, login, etc are all static pages, define them in web.xml
Something like account/abc and blog/some-random-article is handled dynamically.
<servlet>
<servlet-name>NotFound</servlet-name>
<servlet-class>com.site.PageNotFoundServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>NotFound</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
If in your servlet code, if you don't know how to handle the url, in other words the url is something like /asdfadfasdf which you don't handle, throw a 404 back, if the url starts with /blog (from /blog/random-article), go to the blog page with the random-article as the content.
The case of "home.jsp" is not same here
RequestDispatcher dispatcher = request.getRequestDispatcher("/jsp/home.jsp")
and
<servlet>
<servlet-name>home</servlet-name>
<jsp-file>/jsp/**Home.jsp**</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>home</servlet-name>
<url-pattern>/home</url-pattern>
</servlet-mapping>
I have a problem related to the servlet mapping. I have the following in web.xml:
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>test.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
If I access to http://localhost:<port>/MyApp/HelloWorld the servlet HelloWorldServlet is called.
I also want my servelet to respond to http://localhost:<port>/MyApp/HelloWorld/. How can I achieve this effect? I'm developing with NetBeans but it does not allow me to put a pattern ended with /.
After you've added your wildcard on your <url-pattern>
<url-pattern>/HelloWorld/*</url-pattern>
You can get the extra path associated with the URL by using HttpServletRequest.getPathInfo().
E.g.
http://localhost:<port>/MyApp/HelloWorld/one/
The result will be
/one/
From the JavaDoc:
Returns any extra path information
associated with the URL the client
sent when it made this request. The
extra path information follows the
servlet path but precedes the query
string and will start with a "/"
character.
Use a wildcard. You can redirect all the traffic going to a specific URL to the same servlet. For example, you can add the following:
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/HelloWorld/*</url-pattern>
</servlet-mapping>
This will redirect the URL with a slash to your original servlet.
One thought - this would redirect anything to this URL pattern to the servlet. If you want to have other URL's past this URL, you should create a servlet that will redirect to the correct URL (by looking at the URL specified). Alternatively, you could use a framework that provides mapping for you.
I like to know like whenever user requests a jsp page we write hello.jsp or any html file we write hello.html or any image hello.jpeg.
My question is does servlet not have any extension ? Is it called directly called by name?
For Servlets, you have to explicitly tell the Servlet Container what URLs (either specific URLs or wildcards) map to what servlet. For example:
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>com.example.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
The above example would map the URL /hello to the servlet com.example.HelloWorld.
You can also do some wildcard mapping. For example:
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
This would map requests ending in ".html" to the HelloWorld servlet. But you aren't limited to any particular extensions. You could use anything you want:
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>*.foo</url-pattern>
</servlet-mapping>
All of this configuration takes place in your web application's web.xml file.
No, you have it fully in your own hands. It's not necessarily called by its name, it's called by its url-pattern. You can name it to whatever you want, e.g. /pages/* will run the servlet whenever you call http://example.com/pages/foo.jsp or http://example.com/pages/foo (which in turn gives the pathinfo back by request.getPathInfo(), so that you can determine what action to take and/or where to forward the request to). Or *.page which runs the servlet whenever you call http://example.com/foo.page (which in turn gives URI back by request.getRequestURI()).
To preprocess requests (when one requests a page for view) you normally use doGet() method. To postprocess requests (after a POST form submit), you normally use doPost() method.
You can in fact create as many servlets as you want, e.g. RegisterServlet listening on /register which is backed by a register.jsp as view and a LoginServlet listening on /login and backed by a login.jsp as view, etcetera. You can hide JSPs from direct access by placing them in /WEB-INF so that users are forced to call them through the servlet.
In MVC world, there's usually means of only one servlet listening on a certain url-pattern, which is called the Front Controller. In Sun JSF for example, there's the FacesServlet which runs whenever an URL matching by default *.jsf or /faces/* is called. In Apache Struts for example, there's the ActionServlet which listens on by default *.do. They determines which action to take and/or which view (the JSP file) to display based on the URL, request parameters and/or mappings. You're however free to change those default url-patterns. You can even change the default url-pattern of the JspServlet in servlercontainer's web.xml, which by default listens on *.jsp. It's however recommended to stick to a sensible and standardizedurl-pattern.
It might be interesting to know that any other "undefinied" URL patterns are covered by a "default" servlet. Check the servletcontainer's web.xml, you'll see one servlet which listens on / and thus in fact serves everything. It also manages display of directoy listings. In Tomcat for example it's called the DefaultServlet and described here.
Is there a way to call a Java Servlet on click of hyperlink without using JavaScript?
Make the hyperlink have a URL that you have a servlet mapping defined for in the web.xml file.
The servlet-mapping element defines a mapping between a servlet and a URL pattern. The example below maps the servlet named myservlet to any URL that starts with /foo:
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>com.stackoverflow.examples.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
For this example, a hyperlink such as Click Me would invoke the servlet.
you declare your servlet in web.xml by setting its name, class and url-pattern
(let's say your url-pattern is /myServlet)
write mylink
override the doGet(..) method of the servlet to do whatever you want
Think that you've defined a servlet "callme" and web.xml has been configured for this servlet. Use the following syntax to call it using hyperlink
web.xml
<servlet>
<description>callme Functions</description>
<display-name>callme</display-name>
<servlet-name>callme</servlet-name> <servlet-class>com.test.Projects.callme</servlet-
class>
</servlet>
<servlet-mapping>
<servlet-name>callme</servlet-name>
<url-pattern>/callme</url-pattern>
</servlet-mapping>
in JSP:
Call the servlet
What exactly do you mean with "call a Java Servlet? The most normal (i.e. without any JavaScript magic) browser behaviour for clicking on a link is to send a HTTP request to fetch the document at the URL specified in the link and display it - and Servlets exist to respond to HTTP requests.
So you don't have to do anything special at all. Just have a regular HTML link and make sure that the servlet you want to "call" corresponds to that link's URL. Of course the next question is what that Servlet returns and what you want the browser to do with it.