How to get different URLs pointing to same servlet? - scala

I am absolutely new in Servlet technology and this is absolutely basic question, but I am all confused by the tutorials that are all too complicated for me.
I have a new servlet HelloWorldServlet. In web.xml, I have this
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>cz.hello.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/HelloWorldServlet</url-pattern>
</servlet-mapping>
</web-app>
HelloWorldServlet.scala (I prefer scala to java) looks like this
package cz.hello
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
class HelloWorldServlet extends HttpServlet {
override def doGet(req: HttpServletRequest, resp: HttpServletResponse) = {
resp.setContentType("text/plain")
resp.getWriter.println("Hello, world")
}
}
So far so good, servlet is loaded using Jetty, I am happy, I can see "hello world" on http://localhost:8080/HelloWorldServlet.
Now, I want the servlet to be able to react to GET requests to, say, http://localhost:8080/HelloWorldServlet/hello and http://localhost:8080/HelloWorldServlet/goodbye and to both of them differently. For example like (pseudocode)
override def doGet(req: HttpServletRequest, resp: HttpServletResponse) = {
resp.setContentType("text/plain")
if (req.isAddress("/hello") {
resp.getWriter.println("Hello, world")
} else {
resp.getWriter.println("Goodbye, world")
}
}
How can acchieve that?

First of all, if you want to react to POST requests, you should implement the doPost method, instead of the doGet.
Second, I would advise you to think about handling each URL in a different servlet, unless your code will be as simple as the example you provided.
Chances are your code will get more complex when developing real-world applications, so it would be much cleaner if you separate the responsibilities into two servlets. If you agree with this approach, it is just a matter of creating another <servlet> and another <servlet-mapping> object in your web.xml, like follows:
<web-app>
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>cz.hello.HelloWorldServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>GoodbyeWorldServlet</servlet-name>
<servlet-class>cz.hello.GoodbyeWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GoodbyeWorldServlet</servlet-name>
<url-pattern>/goodbye</url-pattern>
</servlet-mapping>
</web-app>
This way, requests to /hello will be handled by HelloWorldServlet, and requests to /goodbye will be handled by GoodbyeWorldServlet. Now it is just a matter of defining whether GET or POST makes more sense for you and implementing the corresponding methods(doGet or doPost, or both) at your servlets.
Your idea (comparing the contents of the URL inside the servlet) also works, but is not a good design, since you might end up with a huge if/then/else chain, which sounds like a bad idea in this case.

Related

Tomcat: depending the url, the css and javascript are run. why? [duplicate]

This question already has answers here:
Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP
(9 answers)
Closed 6 years ago.
I am trying to build a Tomcat project.
Here is my context:
In WebContent, i create a folder called 'webpages' in which I include my file About.jsp + css, javascript files.
In my /WEB-INF/web.xml, I associate /webpages/About.jsp to /about:
<servlet>
<servlet-name>About</servlet-name>
<servlet-class>com.supervision.servlets.About</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>About</servlet-name>
<url-pattern>/about</url-pattern>
</servlet-mapping>
Here is my java code:
public class Accueil extends HttpServlet {
public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException{
this.getServletContext().getRequestDispatcher( "/webpages/About.jsp" ).forward( request, response );
}
}
My problem is:
when I use this url localohost:8080/supervision/about , css and javacsript are not run
but when I use this url localohost:8080/supervision/webpages/About.jsp , it works fine:
Do you know what is the reason of this issue ? and if yes, how to solve it ?
Try to put this line /webpages/about instead of /about .

how to minimize servlet declarations for gwt-rpc in web.xml?

Sorry I am still a beginner in GWT. I have noticed that when my project was grow up , the declarations of servlets for rpc in web.xml file are many, many and many. For a single *ServiceImpl class , we need to define in web.xml as
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>com.my.testing.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/testing/greet</url-pattern>
</servlet-mapping>
If if have 30 *ServiceImpl class, they may take about 200 lines in web.xml for rpc calls. So , I would like to know
Is web.xml file the only place to declare rpc servlets ?
Has someways to skip declarative styles (I mean via annotations '#' etc) ?
GWT works pretty well without these declarations in web.xml, using Annotations:
/*
* this is your server-side rpc-implementation
*/
#WebServlet(name = "YourService", urlPatterns = {"/path/to/yourservice"})
public class YourServiceImpl extends RemoteServiceServlet implements YourService {
public void doSomething() {
//some code
}
}
/*
* this is the corresponding rpc-interface
*/
#RemoteServiceRelativePath("path/to/yourservice")
public interface YourService implements RemoteService {
void doSomething();
}
The resulting path to your servlet depends on you project structure. If your project is deployed in your servers root, you will find your servlet there (with the path you specified with urlPatterns above). However, if you deployed your project under its own URI, you will have to prepend this to the urlPattern.
If you use Guice, this case can be easy solved using ServletModule.
In this module you may programmatically define (and test in JUnit) all your RPC servlets and filters as well.
Example:
public class WebModule extends ServletModule {
#Override
protected void configureServlets() {
// configure filters
filter("/*").through(CacheControlFilter.class);
filter("/*").through(LocaleFilter.class);
// bind XSRF servlet
bind(XsrfTokenServiceServlet.class).in(Singleton.class);
serve("/gwt/xsrf").with(XsrfTokenServiceServlet.class);
// configure servlet mapping
serve("path/to/servlet").with(LoginServiceImpl.class);
}
}

GWT: How to extract a content of a javascript function using (JSNI)

I am calling a javascript function from gwt client side using JSNI like follow:
anchor.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
execute(notification.getActionCode(), notification.getParams());
}
});
private static native String execute(String functionName, String params)/*-{
try{
$wnd[functionName](params);
}catch(e){
alert(e.message);
}
}-*/;
My problem is that my javascript function contains window.open("ServletName?....").
When clicking on the anchor, the window opened with error below:
The requested resource (/es/gwt/core/ServletName) is not available.
if i replace window.open("ServletName?....") by window.open("../../ServletName?...."), the window open successfully, but these javascript functions are used also outside gwt so i cant modify it .
I dont know why the part /gwt/core is being added to the url which is causing the problem.
Is there a way in gwt before executing the javascript function, to extract its content and adding the "../.." before the url? i mean heaving the javascript function name, can we get its content before calling the execute function? in my case my javascript function is a follow:
function everlinked_AddSpace(spaceId){
window.open('ELUtilities?Service=Space&action=homePage&SpaceId='+spaceId+'&Template=apps/everlinked/templates/spaces/space_main.htm','_blank');;
}
i need to modify it in gwt client side and call it with the new modifications.
I appreciate if someone could help me.
I think you are trying to resolve your problem using a bad approach.
The easier way is to use an url re-writer, or to modify your web.xml url-pattern to route the relative path sent by your gwt app to the same servlet.
Probably you have in your web.xml something like this:
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>maynamespace.ServletName</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/ServletName</url-pattern>
</servlet-mapping>
So you can add this block to your web.xml.
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/es/gwt/core/ServletName</url-pattern>
</servlet-mapping>
Note that url-pattern has a very limited set of regular expressions (/path/* and *.ext), so in your case you have to write the full path.

Restlet API example

Is there any simple example of Restlet API with Java?
I want a simple example of Restlet API by calling Get / POST method. One client should call one method from the server through Restlet. The server should execute that method and send the reply accordingly. How can the server open those methods to respond to the client using Restlet?
here simple code which call amazon.java rest class when its match with url as
http://anydomain.com/amazone if you hit this in url than its called get method
public class RestApi extends Application {
/**
* Creates a root Restlet that will receive all incoming calls.
*/
#Override
public Restlet createInboundRoot() {
Router router = new Router(getContext());
// Defines only one route
router.attach("/amazon", Amazon.class);
return router;
}
}
amazon.java
public class Amazon extends ServerResource {
#Override
protected Representation post(Representation entity)
throws ResourceException {
System.out.println("post Method");
return super.post(entity);
}
#Override
protected Representation get() throws ResourceException {
System.out.println("get method");
return super.get();
}
}
and mapping in web.xml file as
<servlet>
<servlet-name>RestletServlet</servlet-name>
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
<init-param>
<param-name>org.restlet.application</param-name>
<param-value>com.wa.gwtamazon.server.RestApi </param-value>
</init-param>
<!-- Catch all requests -->
<servlet-mapping>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
You may want to consider looking at http://www.restlet.org/documentation/ the documentation provided by the project provides good examples to get started with using the code.
Version 2.1 is currently the stable branch and the #Get, #Post, etc. annotations, available to be used on your ServerResource, provide a slightly more flexible approach than outlined by Divyesh, although that approach is I believe still also available.

Servet: Receive JSP File does not exist in WebContent

I'm using Eclipse to program servlet. Now, I want to make a example.jsp does something like servlet ( access attribute or parameter of ServletConfig, ServletContext,...)
I put example.jsp in top of WebContent, and the project name is ProjectExample.
In web.xml, here is how I declare this servlet:
<servlet>
<servlet-name>JSP Example</servlet-name>
<jsp-file>example.jsp</jsp-file>
<init-param>
<param-name>name</param-name>
<param-value>hqt</param-value>
</init-param>
// I meet warning at <jsp-file>: that doesn't found this file
//although I have change to: `/example.jsp`, `ProjectExample/example.jsp` or `/ProjectExample/example.jsp`
</servlet>
Because Container doesn't recognize this file, so when I use: getServletConfig().getInitParameter("name") I will receive null !!!
Please tell me how to fix this.
Thanks :)
#: if something typing wrong in code, that not a problem because it's just typo. I don't know why StackOverFlow doesn't allow Copy/Paste function anymore.
I think the main problem is not in your configuration, but rather the way jsp pages are configured.
Change your <jsp-file>/example.jsp</jsp-file> and add this to JSP:
Who am I? -> <%= getServletName() %>
On my box output is:
Who am I? -> jsp
That is because all JSP share the same servlet configuration called "jsp". It is configured at $CATALINE_HOME/conf/web.xml (if you are using Tomcat). For my Tomcat 7 that configuration looks like this:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
Your servlet should has the init method, there you can read the parameters you need:
public class SimpleServlet extends GenericServlet {
protected String myParam = null;
public void init(ServletConfig servletConfig) throws ServletException{
this.myParam = servletConfig.getInitParameter("name");
}
//your servlet code...
}
This example was taken from here