doGet Method of the Faces Servlet - java

I'm using Apache Tomcat 7.0 Servlet Container. I've been trying to look at the request handling in JavaServer Faces. I can see the following chunk of config in the web.xml :
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
I've looked at the source of the Faces Servlet, but I haven't found doGet method inside. I thought doGet method is one of the principal method to handle HTTP GET request in the Java Servlets. So who exact handles incoming GET request in JSF? I would like to look at the method, which do that.

FacesServlet doesn't extend from HttpServlet class containing a.o. doGet(). It just implements Servlet interface which offers the base service() method. Look here.
JSF is designed to be compatible with both servlets and portlets. Portlets doesn't use HttpServlet, but PortletServlet which shares the common Servlet interface.

Related

How to fix 'cannot be cast to javax.servlet.Servlet' error while trying to package REST App with Servlet

I am trying to setup Angular 7 with a maven based back-end java project into a single war file. At the moment I am trying to configure the web.xml file where I am currently having this problem. I am not sure at all if my approach is valid or 'good' therefore I will first describe what I am trying to do (if you think better on this aspect please do correct me).
So I have a couple of JAX-RS classes which I'd like to serve as a REST API. For this purpose I have created corresponding javax.ws.rs.core.Application classes to provide these REST components. Then I am including the Application classes in the web.xml file. Below are the files:
web.xml
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
<servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
<url-pattern>/rmz/*</url-pattern>
</servlet-mapping>
Another variation of web.xml that I tried
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
<servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>backend.backendservice.StammSolvaraJahrRestApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
<url-pattern>/rmz/*</url-pattern>
</servlet-mapping>
Application class
public class StammSolvaraJahrRestApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> sets = new HashSet<>();
sets.add(StammSolvaraJahrRest.class);
return sets;
}
}
The error that I get is: java.lang.ClassCastException: backend.backendservice.StammSolvaraJahrRestApplication cannot be cast to javax.servlet.Servlet and if I remove the <servlet-class> then I'll get No servlet class has been specified for servlet. I am following https://docs.oracle.com/cd/E24329_01/web.1211/e24983/configure.htm#RESTF183 and How to deploy a JAX-RS application? among others but it seems not to be working.
There are two ways to define your JAX-RS servlet.
1) With Application Subclass like the one you have, you can skip the web.xml config and just add the application annotation
#ApplicationPath("resources")
public class StammSolvaraJahrRestApplication extends Application
2) With web.xml config
<servlet>
<display-name>JAX-RS Servlet</display-name>
<servlet-name>package.hierarchy.StammSolvaraJahrRestApplication</servlet-name>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>package.hierarchy.StammSolvaraJahrRestApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>JaxRSServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
If you skip the servlet mapping from the last one, it will use your your #ApplicationPath specified value, or "/resources" if the previous one is missing.
The problem is just what it says. This line in your web.xml requires a javax.servlet.Servlet:
<servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
Since an Application is not a javax.servlet.Servlet, you're getting the error at runtime when your XML file is processed.
If you can, I would suggest that you start with a Spring Boot starter application. Spring Boot handles all of this for you. It can even embed a Tomcat server inside a jar file so that you can run your server like a simple Java application. Doing this would save you having to worry about what you're dealing with here.

How to use DispatcherServlet in tomcat with multiple servlets

I am working with a tomcat app with multiple servlets.
I want to be able to initialize these and do dependency injection on server start up.
I understand that I will have to declare a org.springframework.web.servlet.DispatcherServlet .
But I am not sure how should my web.xml look like. Currently it looks like following:
<servlet>
<servlet-name>AddAccount</servlet-name>
<servlet-class>com.addressbook.servlets.AddAccount</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AddAccount</servlet-name>
<url-pattern>/AddAccount</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>com.addressbook.servlets.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
Currently, any request to add an account is sent directly to /AddAccount and for login the request is sent to /Login.
With DispatcherServler, how should my new web.xml and request structure look like? Do I have to make a new servlet that implements DispatcherServlet and forward each request to this new servlet which then forwards to correct Servlet?
You dont need multiple servlets for several kind of actions in your app. The DispatcherServlet is a front controller that handles all requests and dispatches them to your controllers. As Sotirios suggested, have a look at the Spring MVC manual first. Only the Dispatcher servlet is neccessary.

App engine default page to be servlet

I have App engine application, with that servlet:
<servlet>
<servlet-name>Authorization</servlet-name>
<servlet-class>x.y.z.Authorization</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Authorization</servlet-name>
<url-pattern>/pattern</url-pattern>
</servlet-mapping>
everything works.
servlet invokes with this pattern http ://localhost/pattern
now I want to create AutorizationServlet default page. I need to invoke that servlet with this pattern:
http ://localhost
if I write <url-pattern></url-pattern> I have AppEngineConfigException:
Try this :
<url-pattern>/</url-pattern>

Why use <servlet-mapping> in web.xml(Deployment Descriptor) in jsp/servlet?

<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/HelloWorld.do</url-pattern>
</servlet-mapping>
Why do we use url-pattern inside servlet-mapping tag. Why not in servlet tag itself.
It's seems just an extra tag to write.
Is it just because servlet/jsp spec writers decided to do so or has it some logical reason behind its existance ?
This is more likely due to the fact that servlets were intended to support multiple protocols, and not just HTTP. URL patterns are specific to HTTP alone, and therefore the mapping of the servlet to HTTP URL patterns is done in a servlet-mapping tag, instead of the servlet tag which is used for declaring the more generic properties of the servlet.
u may try to write another that also linked to the same servlet,and then u will know that the servlet can have more than one servlet-mapping.
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/HelloWorld.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/HelloWorld2.do</url-pattern>
</servlet-mapping>
I agree with Vineet Reynold that servlet-mapping is used to provide support for different protocols available for communication in network. therfore, url-pattern tag let know the servlet the type of protocol ie. HTTP requesting the service.
The limitations and weaknesses of the standard servlet url pattern was a driving factor behind many of the early MVC frameworks (Struts etc). No support for regular expression matching, or even ant-style patterns. No support for url exclusion patterns etc etc.
As to why the specification is the way it is (and still continue to be), I have no idea. The only people who know for sure are the ones who wrote the specs.

Hide .jsp extension in JSP project using servlet mapping

I am writing an application in JSP, and I need to remove the ".jsp" extension from the URL. For example, I need:
http://example.com/search.jsp?q=stackoverflow
To be:
http://example.com/search?q=stackoverflow
I know that this can be done using the ".htaccess" file, but I need some other way. I have tried the following code:
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.</url-pattern>
</servlet-mapping>
However, this did not work. Does anyone have some suggestions for ways to accomplish this? Thanks in advance for any help.
With a servlet mapping you need to specify each JSP individually like follows:
<servlet>
<servlet-name>search</servlet-name>
<jsp-file>/search.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>search</servlet-name>
<url-pattern>/search</url-pattern>
</servlet-mapping>
It's easier if all those JSPs are in a common path. E.g. /app/*.
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>com.example.FriendlyURLServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
with
request.getRequestDispatcher("/WEB-INF" + request.getPathInfo() + ".jsp").forward(request, response);
This assumes the JSPs to be in /WEB-INF folder so that they cannot be requested directly. This will show /WEB-INF/search.jsp on http://example.com/app/search.
Alternatively, you can use Tuckey's URLRewriteFilter. It's much similar to Apache HTTPD's mod_rewrite.

Categories