Dynamic URL routes with java EE - java

I'm super new to java web application development. Working on basic Todos app. So far app is working fine. I wish to add dynamic url routes like updateTodos, deleteTodos to existing path.
Expected behavior as shown below
/todos
*render todos list*
/todos/update
*render updateTodos.jsp*
/todos/delete
*render deleteTodos.jsp*
Below is my code
#WebServlet(urlPatterns = "/todos")
public class UserTodos extends HttpServlet {
private TodoService todoService = new TodoService();
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
if(request.isRequestedSessionIdValid()){
request.setAttribute("userName", request.getParameter("userName"));
request.setAttribute("allTodos", todoService.retrieveTodos());
request.getRequestDispatcher("WEB-INF/views/todos.jsp").forward(request, response);
}else{
response.sendRedirect("/login");
}
}
}
My understanding is so far that the annotation #WebServlet triggers the class file based on route defined. Can I achieve the above with a single class file?
Something like being done in JS web-framework Express-JS
If I sum-up my whole query is - Is it possible to multiple doGet and doPost methods in a single class file which will be executed based on user's URL accessed?
Update
I was able to achieve this, not sure whether this is correct implementation or not :/

Related

Attaching query parameters in a ClientRequestFilter

I simply need to attach query parameters onto an outgoing request. (Java EE 7.0, JAX-RS 2.0)
In specifics, I currently using the RESTeasy Client ver 3.0.14, so I make my calls using the fancy interface-proxy system. I was attempting to produce something like this:
myapplication/api/path?timestamp=000
with:
#Provider
public class MyRequestFilter implements ClientRequestFilter {
#Context
private HttpServletRequest servletRequest;
public void filter(ClientRequestContext requestContext) throws IOException {
servletRequest.getParameterMap().put("timestamp", new String[]{
String.valueOf(new Date().getTime())
});
}
}
I made sure I was registering it with client.register(MyRequestFilter.class) as well. Feel free to ask questions. Thanks!
Credit to #peeskillet --
Rebuild the URI from the requestContext like this:
requestContext.setUri(UriBuilder.fromUri(requestContext.getUri()).queryParam("key", value).build());
You can now see the new query parameter with
requestContext.getUri().toString();
Again, verify that you register it when making the REST Client
client.register(MyRequestFilter.class);

Share Session between liferay portlet and servlet

I'm trying to share a session between a liferay portlet and a servlet, running in the same WAR.
I'm setting the attribute like this in the LoginPostAction (Hook):
#Override
public void run(HttpServletRequest request, HttpServletResponse response) throws ActionException {
Gebruiker g = new Gebruiker();
request.getSession().setAttribute("gebruiker", gebruiker);
}
Trying to get this Gebruiker object in my servlet, through an AJAX-request:
#RequestMapping(value="/haalContactGegevens", method = RequestMethod.POST)
public #ResponseBody ContactGegevensMessage getContactGegevens(HttpServletRequest request, HttpServletResponse response) {
Gebruiker gebruiker = (Gebruiker)request.getSession(true).getAttribute("gebruiker");
}
But here my 'Gebruiker-object' stays null.
What am I doing wrong?
thx
Easy: The LoginPostAction is handled by Liferay (even though technically implemented in your webapp's context/classloader. However, if you look at the httpServletRequest's context path, it's Liferay's.
When you implement a servlet in your own webapp, it will have its own session, unrelated to Liferay's.
You should rather implement a portlet and utilize its serveResource lifecycle method to handle the Ajax request - this will make you part of the whole portal environment. However, you should also minimize use of the Http-level session: It's prone to become a source for memory leaks sooner or later.
Note: While implementing a portlet will give you access to the HttpServletRequest (through PortalUtil), this is discouraged for the reasons given above. But as I don't know what you're trying to achieve, this would be part of the quickfix for the code that you give in your question.

passing data btw classes using request.setParameter, request.getParameter

I have 2 java classes and I want to transfer data between them.
I take user id as parameter in a previous jsp form, and in a java class, using setAttribute I create a atribute named st_id.
then in another java clas I want to retrieve this data, but I get null.pointer exception.
first java file;
public class Signin implements Action {
public String process(HttpServletRequest request, HttpServletResponse response) throws Exception {
Student stu = new StDAO().getUser(request.getParameter("st_id").toString());
request.setAttribute("st_id", request.getParameter("st_id").toString());
...
second;
public class addCourseStu implements Action{
#Override
public String process(HttpServletRequest request, HttpServletResponse response) throws Exception {
TakeCourseDAO pf = new TakeCourseDAO();
String s= (String) request.getAttribute("st_id");
So s is null, it's not my intention.
A request exists from the time the web browser sends it to the web server until the web server (via the servlet) has made its response.Every request for a servlet has its own accessibilty scope. From a servlet, you can:
add new attributes to the request's scope
obtain exisiting attributes from the request's scope
remove exisiting attributes from the request's scope
As you are getting null it is quite obvious that the attribute is not accessed within the scope.
You can try alternatives like Session scope or Application scopes which ever suits you
It is not entirely clear what you want to do but I gather that you want to maintain some state on the server between two requests right?
Look into sessions & cookies for this.
What you do here is weird as it seems you are setting an attribute on an incoming request in the first file.

How to control servlet execution by URLs?

If the urlPatterns controls basic URL rewrite, can I not use .htaccess to rewrite the URL? I'm looking at this code: http://www.objectdb.com/tutorial/jpa/eclipse/ee/servlet
...
#WebServlet(name = "GuestServlet", urlPatterns = {"/guest"})
public class GuestServlet extends HttpServlet {
...
This page works great when I access http://localhost:8080/Guestbook/guest, but what if I wanted to do http://localhost:8080/Guestbook/guest/edit?id=4, how would I set that up in this controller?
In PHP the logical steps would be http://localhost:8080/Guestbook/controller/function. In java it seems like I can only use doGet(), is this right?
I'm trying to envision how the overall URL structure affects the execution of controllers.
Use an URL pattern of /guest/* and use HttpServletRequest#getPathInfo() to extract the path information.
Here's a kickoff example (trivial checks omitted):
#WebServlet("/guest/*")
public class GuestServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String[] pathInfo = request.getPathInfo().split("/");
String action = pathInfo[1]; // edit
String id = pathInfo[2]; // 4
// ...
}
}
Invoking http://localhost:8080/Guestbook/guest/edit/4 will set action to edit and id to 4. You could from this step on make use of the strategy pattern to invoke specific business actions.
You could of course also go for an action based MVC framework which abstracts all the servlet boilerplate away, such as Spring MVC.
See also:
Design Patterns web based applications
resource http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/annotation/WebServlet.html
basically you need to change
#WebServlet(name = "GuestServlet", urlPatterns = {"/guest"})
to
#WebServlet(name = "GuestServlet", urlPatterns = {"/guest", "/guest/edit"})
now your servlet should handle the "/guest/edit" URL pattern also

Handling ajax requests with spring

Here is my problem, I need to map a AJAX request using spring. Now, I know that I need these two guys:
HttpServletRequest, to get the message the client sent to me and parse it from JSON(most likely) to a Map and HttpServletResponse to put my message to the client.
What I do not know is the right(simple, concise) way to do that...
Here is a code sample from the springframework site:
/**
* Normal comments here
*
* ##org.springframework.web.servlet.handler.metadata.PathMap("/foo.cgi")
* ##org.springframework.web.servlet.handler.metadata.PathMap("/baz.cgi")
*/
public class FooController extends AbstractController {
private Cruncher cruncher;
public FooController(Cruncher cruncher) {
this.cruncher = cruncher;
}
protected ModelAndView handleRequestInternal (
HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView("test");
}
}
Which is nice. Except that, as far as I can see, I cannot map a URL for each method in that class as I would do with this kind of synchronous request:
#Controller
#RequestMapping("/test")
public class ControllerTest {
#RequestMapping(value = "/test.htm", method = RequestMethod.GET)
public void showSearchView(Model model) {...}
...
}
Can I do something that simple for AJAX requests?
Not sure where you found that first example on SpringSource! That is the old-bad(tm) way of doing it. I'm pretty sure AbstractController is even marked deprecated in Spring 3.
The second way works fine for mapping AJAX requests. If you really want to parse it all yourself, HttpServletRequest and HttpServletResponse are legal parameters for that handler method. However, Spring will happily do it for you: http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
(If you're stuck on an older version of Spring there are also 3rd party libraries for adding JSON mapping to handlers.)
This is the answer I found. I modified the method shown in my post and added a HttpServletRequest to the method arguments.
public void showSearchView(Model model, HttpServletRequest req, HttpServletRequest resp) {
if(req==null||resp==null)throw new RuntimeException("OLOLOLOLOL xD");
}
That's it. If anyone have a better answer or comments, I'd be glad to hear.

Categories

Resources