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

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];
// ...
//..
//.
}
}

Related

Servlets, How to make server available by the name in annotation? [duplicate]

This question already has an answer here:
How to set my webapp to appear as ROOTfor localhost:8080
(1 answer)
Closed 1 year ago.
I'm only starting to learn Servlets.
I have a simple template code below.
I thought that after writing annotation "#WebServlet("/hello-servlet")" my page will be available by the URL "http://localhost:8080/hello-servlet".
The problem is that it is not available by that adress only by "http://localhost:8080/demo_war_exploded/".
I do know that the problem is connected with Tomcat configurations. In settings it is said that url is "http://localhost:8080/demo_war_exploded". And deployment is "war exploded".
How can I make the server available by the name in annotation?
#WebServlet("/hello-servlet")
public class HelloServlet extends HttpServlet {
private String message;
public void init() {
message = "Hello World!";
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>" + message + "</h1>");
out.println("</body></html>");
}
public void destroy() {
}
}
I found out the answer - you just need to delete application context from deployment

how to get a path variable value in servlet

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.

getParameter returns null in the servlet [duplicate]

This question already has an answer here:
HTTP request parameters are not available by request.getAttribute()
(1 answer)
Closed 6 years ago.
i am trying to pass a string from my jsp to the servlet via href. I use this
Title1
then in the servlet i am trying to get the value of the select with this
String s = request.getParameter("select");
But it returns null. Why is that? Thank you!
EDIT I post the code of the servlet
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userOption = request.getAttribute("select");
System.out.println("Select is:" + userOption);
//in the console i get: Select is:null
That should not be String userOption = request.getAttribute("select");
Please understand that attributes are not parameters
It should be String userOption = request.getParameter("select");

Lifecycle/Scope of #WebServlet [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do servlets work? Instantiation, session variables and multithreading
I have a weird (but probably expected) behaviour in my WebServlet. Environment is:
- Apache 2.2.x
- Glassfish 3.1.1 + mod_jk
- JSF Mojarra 2.1.3
I have an abstract servlet that implements some code to check in the FacesContext/Session if there is a specific #SessionScoped managed bean and if so, whether the user is signed-in. If user is signed-in, then proceeds to the file delivery. The implementing #WebServlet only provides the actual file download.
Abstract Servlet:
public abstract class SecureDownloadServlet extends HttpServlet {
#EJB
private UserProductBean userProductBean;
private UserInfoView userInfoView = null;
private UserInfoView getUserInfoView(HttpServletRequest req) {
FacesContext context = FacesContext.getCurrentInstance();
if (context != null) {
userInfoView = (UserInfoView) context.getApplication()
.getELResolver().getValue(FacesContext.
getCurrentInstance().getELContext(), null, "userInfoView");
}
if (userInfoView == null) {
userInfoView = (UserInfoView) getServletContext().
getAttribute("userInfoView");
}
if (userInfoView == null) {
userInfoView = (UserInfoView) req.getSession().
getAttribute("userInfoView");
}
return userInfoView;
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse response)
throws IOException, ServletException {
if (getUserInfoView(req) == null || !getUserInfoView(req).getLoggedIn()) {
response.sendRedirect("message.xhtml?msg=noLogin");
return;
}
doDownload(req, response);
}
public abstract void doDownload(HttpServletRequest req,
HttpServletResponse response)
throws IOException, ServletException;
}
Then I have a #WebServlet that extends the above abstract HttpServlet and implements the abstract method:
#WebServlet(name = "SecureImageServlet", urlPatterns = {"/print","/m/print"})
public class SecureImageServlet extends SecureDownloadServlet {
#Override
public void doDownload(HttpServletRequest req, HttpServletResponse response)
throws IOException, ServletException {
// some code
}
}
Now here is the issue:
- From computer A, sign in, then call the SecureImageServlet servlet to get a file (i.e. http://www.example.com/print?id=12345). The userInfoView session bean is initialized as expected, and the file is delivered.
- From computer B, without being signed-in, call http://www.example.com/print?id=12345. The userInfoView is already initialized with the session of user on computer A!!! And the file is delivered too.
It looks like the WebServlet becomes ApplicationScope or something like that. Is it the #EJB injection that does that?
Note the the instance of userInfoView is the same (the object id in the debugger shows the same number) which means somehow the computer B is seen as the same user as computer A
Edited format
Ok, a friend of mine (without an account on SO :) ) pointed out my mistake:
I am using userInfoView as a class member instead of keeping it within the request scope. I fixed it by removing the class member and voila!

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