JSF Custom Servlet Mapping To a File - java

below code is used to map urls with /photos pattern to a /photos.jsp,since <jsp-file> tag is not valid in jsf, so how can i do this kind of mapping with jsf?
i need this for two reasons :
1- hide my underlying structure at least from naked eyes
2-simplify urls
<servlet>
<servlet-name>photos</servlet-name>
<jsp-file>/photos.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>photos</servlet-name>
<url-pattern>/photos</url-pattern>
</servlet-mapping>
thank you

hide my underlying structure at least from naked eyes
Anything in the WEB-INF folder cannot be accessed outside from your server.
simplify urls
Insert the folllowing code your faces-config.xml it will redirect everything from /photo* to /photo.jsp.
<navigation-rule>
<from-view-id>/photo*</from-view-id>
<navigation-case>
<to-view-id>/photo.jsp</to-view-id>
</navigation-case>
</navigation-rule>

Urls are supposed to be mapped to a JSF controller component (servlet or filter), not to a jsp file as expressed in the question. Below describes that photos.jsp and urls under /photo are mapped to the custom servlet Photo.java :
<servlet>
<servlet-name>photos</servlet-name>
<servlet-class>package.Photos</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>photos</servlet-name>
<url-pattern>/photos.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>photos</servlet-name>
<url-pattern>/photos/*</url-pattern>
</servlet-mapping>

Related

How to avoid matching paths that don't have a slash with servlet-mappings?

I'm trying to set up a servlet so that any requests for /foo/* will go to my Foo servlet, except for requests in the form of /foo/bar/*, which go to the Bar one. However, I want /foo/bar to go to the Foo servlet, not the Bar one. Is there a way to do this with just url-patterns in web.xml?
My mappings:
<servlet-mapping>
<servlet-name>Bar</servlet-name>
<url-pattern>/foo/bar/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Foo</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
I've tried removing the asterisks and trying a few other patterns, but the only way I can see to do this is to have a specific mapping for /foo/bar, though it seems like there should be a better way.
If you are using servlet specification v2.5 or above then you could provide multiple url-pattern elements for the same servlet-mapping like:
<servlet-mapping>
<servlet-name>Foo</servlet-name>
<url-pattern>/foo/*</url-pattern>
<url-pattern>/foo/bar</url-pattern>
</servlet-mapping>

Filter mapping in Spring MVC is not working on some URL

I am using HTML Filter to delete white spaces from out put of my jsp pages and servlets. I am learning JSP development with Spring MVC. So I am using filter mapping and error page with web.xml file and my web.xml codes are
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/error404</location>
</error-page>
<filter>
<filter-name>whitespaceFilter</filter-name>
<filter-class>test.web.htmlminify.HTMLMinifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>whitespaceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
And I have three controllers with no methods but only returning pages which are
HomeController, TestController, Error404Controller
which has homePage(), testPage() and errorPage() method which are returning following ,
return "home";
return "test";
return "error";
And I do have one jsp file outside of WEB-INF folder named abc.jsp file.
So situation is that when I access localhost, localhost/abc.jsp, localhost/testpage and localhost/error404
the filter mapping is working, as when I see source code of html webpage in browser, there is not white space in it but when i try to access localhost/ashhjb or localhost/kjdhvid/sdvfdjiu anything like that, filter mapping is not working. It means I am seeing white spaces in html pages when servlet is calling 'error' page instead of direct error controller method in browser. localhost/error404 is direct call to error page servlet. So can anyone help me and suggest me what should I do?
Thanx for helping in advance.
As #fzzfzzfzz said, I needed to add these two dispatchers
<dispatcher>REQUEST</dispatcher>
<dispatcher>Error</dispatcher>
and it worked. Thanx again #fzzfzzfzz

Why do we need a servlet name?

I have been readin Head First JSP and Servlet, I see that the web.xml has
<!-- To name the servlet -->
<servlet>
<servlet-name>ServletName</servlet-name>
<servlet-class>packy.FirstServlet</servlet-class>
</servlet>
<!-- For URL's to map to the correct servlet -->
<servlet-mapping>
<servlet-name>ServletName</servlet-name>
<url-pattern>/ServletURL</url-pattern>
</servlet-mapping>
Why hide the original servlet's location ? I can simply see that it is for security reason and some more such kinda advantages, but why have a name for each servlet ? Why can't the web.xml be simple like
<servlet>
<url-pattern>ServletURL</url-pattern>
<servlet-class>packy.FirstServlet</servlet-class>
</servlet>
It allows you to have multiple servlet mappings on a single servlet instance (even spread over multiple web.xml/web-fragment.xml files) without the unnecessary need to create a separate instance per mapping:
<servlet>
<servlet-name>someServlet</servlet-name>
<servlet-class>com.example.SomeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>someServlet</servlet-name>
<url-pattern>/enroll</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>someServlet</servlet-name>
<url-pattern>/pay</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>someServlet</servlet-name>
<url-pattern>/bill</url-pattern>
</servlet-mapping>
(note: yes, you can have multiple URL patterns per mapping, but that wouldn't cover them being split over multiple web.xml/web-fragment.xml files)
It allows you to map filters on the particular servlet without worrying about what URL patterns the servlet is/would be using:
<filter-mapping>
<filter-name>someFilter</filter-name>
<servlet-name>someServlet</servlet-name>
</filter-mapping>
Your proposal would support neither of them.
Note that since Servlet 3.0, which is out for almost 4 years already (December 2009; please make sure that you learn the matters by up to date resources ... anything older than 1~3 years should be carefully reviewed), you can easily use the #WebServlet annotation to minimze web.xml boilerplate:
#WebServlet("/servletURL")
public class SomeServlet extends HttpServlet {}
Just solely this annotation already maps it on an URL pattern of /servletURL without any web.xml entry.
We don't really need a servlet name. It's just that this is how the Java EE designers chose to declare and map servlets in XML.
Nowadays, you can declare and map a servlet using the #WebServlet annotation, and the name attribute of this annotation is optional.

Servlet mapping direct JSP files rather than using a Servlet to manage the URL requests

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>

map url to controller

in my applicationContext.xml, i put this
<bean id="something" class="com.to.theController"/>
in com.to.theController
i have this method like
#Controller
public theController{
#RequestMapping(value="/api/add", method= RequestMethod.GET)
public String apiAddHandler(Model model){
model.addAttribute("api", new Api());
return "apiForm";
}
}
when jetty startup, i can see defining beans [something,...
but when i go to http://localhost:8080/api/add , i get 404 error. what did i miss out? i already debug apiAddHandler method, this method is not called when i call the URL
Make sure Spring is finding your annotations. You should see something like "INFO DefaultAnnotationHandlerMapping:343 - Mapped URL path [/api/add] onto handler [com.example.ExampleController#6f3588ca]" in the logs.
Also, as mentioned already, you need to make sure that you have the correct url mapping in web.xml.
I'd use
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
to map all urls to the dispatcher servlet if using annotations.
If you want to serve some content outside of the dispatcher servlet add the folowing aswell
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
Do you have a <servlet-mapping> element in your web.xml to map URLs that look like /api/add to DispatcherServlet?
If not, then it doesn't matter how Spring MVC maps URLs to controllers if the request never makes it to Spring MVC in the first place.
You need to do some setups.
In your web.xml you have add a mapping for DispatcherServlet.
Something like
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*/api/add</url-pattern>
</servlet-mapping>
You have to add annotation handler to the spring configuration
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<context:component-scan base-package="learn.web.controller" />
Where learn.web.controller is the package where you have the annoted components

Categories