how to get a path variable value in servlet - servlets

I want to get the path variable in servlet. Assume the url is www.demo.com/123/demo. I want to get the 123 value from the path without doing any string manipulation operation.
Note: the following servlet doesn't have any web.xml configurations. My code is:
#WebServlet(urlPatterns = { "/demo" })
public class DemoServlet extends HttpServlet {
public DemoServlet()
{
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doPost(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
sysout("demo");
}
}

The portion of the URL you are referring to is the "context". Use request.getContextPath() to get this. In the case of your example, this would return /123. If you want exactly 123 you would have to remove the leading slash.
From the documentation:
Returns the portion of the request URI that indicates the context of
the request. The context path always comes first in a request URI. The
path starts with a "/" character but does not end with a "/"
character. For servlets in the default (root) context, this method
returns "". The container does not decode this string.

Related

How to read the following path from a servlet? [duplicate]

This question already has answers here:
Servlet and path parameters like /xyz/{value}/test, how to map in web.xml?
(7 answers)
Closed 1 year ago.
I have a servlet which works on organizations address (#WebServlet("/organizations")). This way using GET or POST method on address .../organizations leads to calling of this servlet. When I need to work with a current organization (for example, 12th), I should call .../organizations/12. This way I can write #WebServlet("/organizations/*"), but how to read this number (12 in this case)? Or can I replace it with a variable somehow like #WebServlet("/organizations/{orgNumber}") (this variant didn't work)?
You did not give us your code, but you can use the request object and string operations to find the part of the request URI you are looking for.
#WebServlet("/organizations/*")
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// split the complete URI by /
final var split = request.getRequestURI().split("/");
// ...
// or use substrings
final var partOfPath = request.getRequestURI().substring(20,30);
// ...
// or use pathInfo to split only the path following the domain
final var split = request.getPathInfo().split("/");
// ...
}
}
You could map it on /organizations/* and extract information from getPathInfo():
#WebServlet("/organizations/*")
public class OrganizationsController extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String[] pathInfo = request.getPathInfo().split("/");
String id = pathInfo[1]; // {id}
String command = pathInfo[2];
// ...
//..
//.
}
}

Can I write code after RequestDispatcher?

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//some code here
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//performTask(req, resp);
//some code here
}
private void insertRequestTemplate() {
HttpSession session = req.getSession();
responsePage = req.getParameter("ResponsePage");
ServletContext ctx = getServletConfig().getServletContext();
ctx.getRequestDispatcher(responsePage).forward(req,resp);
readMessage();
public void readMessage()
{
System.out.println("calling MessageTrigger_ABean");
MessageTrigger_ABean msg = new MessageTrigger_ABean();
msg.read();
}
msg.read() has the code to read messages from MQ. Inside insertRequestTemplate method, I am calling readMessage method after ctx.getRequestDispatcher(responsePage).forward(req,resp);is this the correct way of calling this?
But inside insertRequestTemplate method, the page is not getting forwarded to the next page untill readMessage() is executed because of which the page keeps on loading for a long time until message is read from MQ. Could you please help me on this.
Most examples I have seen of a servlet forwarding the request to another servlet have the dispatcher forward invocation at the end of the method. ie. there is no more code, other than closing braces at the end of the method.
I am guessing that the forwarding doesn't happen until the invoking method completes. So where you have your msg.read() will stop the insertRequestTemplate method from completing. This will more than likely be because the code inside msg.read is being performed synchronously. Leading to http timeouts on the http request.
How you solve this will depend on what you want to do with the messages you obtain from msg.read().

Apache Sling - passing request object as part of doPost

Can someone explain and provide code snippet for passing request body (maybe it can accept value Object) as part of apache sling doPost method -
request :
{ "XDPCont" : "XDP sample string"}
Response :
I have tried with below code but it did't work.
#Override
protected void doPost(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
final Resource resource = req.getResource();
resp.getOutputStream().println(resource.toString());
resp.getOutputStream().println(
"This content is generated by the HelloServlet POST"+req.getRequestParameter("XDPCont"));
}
Can you please explain with an working code.

does returning from doGet() or doPost() automatically send a resonse

I have looked around and previously asked this question but did not get a full answer. When you explicity return from doGet() or doPost() does a response get sent regardless of if you have encoded anything or not. If so what is the default code ? Is it enough to simply response.setStatus() and return ? If not: so I have always manually send back a response ? What is the default way to just respond not using forward or redirect ?
If you do nothing, just return (or not even return) from a servlet, it will send back a status code 200(OK) empty response. Tested it in both tomcat and glassfish servers, using the servlet below:
#WebServlet("/a")
public class a extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return;
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return;
}
}
Using the network profiler tool of Chrome you can see what I said:

How do I execute multiple servlets in sequence?

I am just beginning with Servlets and managed to have some servlets that act as individual URLs for populating a database for some dummy testing. Something of the form:
public class Populate_ServletName extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain");
//Insert records
//Print confirmation
}
}
I have about 6 such servlets which I want to execute in a sequence. I was thinking of using setLocation to set the next page to be redirected but was not sure if this is the right approach because the redirects should happen after the records have been inserted. Specifically, I am looking for something like this:
public class Populate_ALL extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain");
//Call Populate_1
//Call Populate_2
//Call Populate_3
//...
}
}
Any suggestions?
Use RequestDispatcher#include() on an URL matching the url-pattern of the Servlet.
public class Populate_ALL extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
request.getRequestDispatcher("/populateServlet1").include(request, response);
request.getRequestDispatcher("/populateServlet2").include(request, response);
request.getRequestDispatcher("/populateServlet3").include(request, response);
//...
}
}
Note: if those servlets cannot be used independently, then this is the wrong approach and you should be using standalone Java classes for this which does not extend HttpServlet. In your specific case, I think the Builder Pattern may be of interest.
The RequestDispatcher#forward() is not suitable here since it throws IllegalStateException when the response headers are already committed. This will be undoubtely the case when you pass the request/response through multiple servlets which each writes to the response.
The HttpServletResponse#sendRedirect() is absolutely not suitable here since it implicitly creates a brand new request and response, hereby trashing the original ones.
See also:
How do I call a second JSP servlet while in the first JSP servlet?
RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()
communication between remote servlets
It looks like what you may need is a service that each of the servlets can use to perform some work. Then the servlets are not depending one and another, but rather all using the service.
However, here is an explanation of forwarding or redirecting requests.

Resources