I'm debugging a project, an online banking website backend, that uses Spring. Often, all I have to latch on to in the bug report is which buttons to click to reproduce the bug. In the browser dev console, I then see the request URL and the response. I then have to somehow find the method mapped to that URL and start debugging.
What bothers me is that Eclipse's search features(that, or my ability to use them) leave a lot to be desired. I can't seem to find the method with one particular mapping, with something like https://ourcompany.com/ourapp/delegate/rest/account/foo/info
to work with, I string-search for "/info" or "/foo" or "foo/info", and get little results. All eclipse does is find some irrelevant file containing the string and open it, and then display(collapsed) a bunch of project folders below it, which I guess also contain files with the string somewhere in them.
Is there some more streamlined way to do this? Did I leave out something small but important from the search? How do I easily find which method in mapped to an URL such as the one in the example?
You can try to set a breakpoint inside
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter
See the method
#Override
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
here you have handler object which keeps class you need. Not sure it works in 100% cases.
Assuming you are using annotations, it should be easy to find the controller just searching the Java class files. I would start by searching for the account controller. In here, I believe you will find a method mapped to "{id}/info" which should be what you're looking for.
As a sidenote, IntelliJ may be something to look into if you're looking for a fuller feature set. I work with it daily for Java, Spring, Struts, and web files, and it does a great job indexing and finding results with ease.
Related
Consider this line of jsp code:
function clearCart(){
cartForm.action="cart_clear?method=clear";
cartForm.submit();
}
Clearly it's trying to call a method on the back end to clear the cart. My question is how does the service (Tomcat most likely, correct me if I'm wrong) which hosts this site that contains this snippet of code know how and where to find this method, how it "indexes" it with string values etc. In my java file, the clear method is defined as:
public String clear( )
{
this.request = ServletActionContext.getRequest();
this.session = this.request.getSession();
logger.info("Cart is clearing...");
Cart cart = ( Cart ) this.session.getAttribute(Constants.SESSION_CART );
cart.clear();
for( Long id : cart.getCartItems().keySet() )
{
Item it = cart.getCartItems().get(id);
System.out.println( it.getProduct().getName() + " " + it.getNumber()
);
}
return "cart";
}
By which module/what mechanism does Tomcat know how to locate precisely that method? By copycatting online tutorials and textbooks I know how to write these codes, but I want to get a bit closer to the bottom of it all, or at least something very basic.
Here's my educated (or not so much) guess: Since I'm basing my entire project on struts, hibernate and spring, I've inadvertently/invariably configured the build path and dependencies in such ways that when I hit the "compile" button, all the "associating" and "navigating" are done by these framework, in other words, as long as I correctly configured the project and got spring etc. "involved" (sorry I can't think of that technical jargon that's on the tip of my tongue), and as long as I inherit a class or implement an interface, when compiling, the compiler will expose these java methods to the jsp script - it's part the work done by compiler, part the work done by the people who composed spring framework. Or, using a really bad analogy, consider a C++ project whereby you use a 3rd party library which came in compiled binary form, all you have to do is to do the right inclusion (.h/.hpp file) and call the right function and you'll get the function during run time when calling those functions - note that this really is a really bad analogy.
Is that how it is done or am I overthinking it? For example it's all handled by Tomcat?
Sorry for all the verbosity. Things get lengthy when you need to express slightly more complicated and nuanced ideas. Also - please go deep and go low-level don't go too deep, by that I mean you are free to lecture on how hibernate and spring etc. work, how its code is being run on a server, but try not to touch the java virtue machine, byte code and C++ pointers etc. unless of course, it is helpful.
Thanks in advance!
Tomcat doesn't do much except obey the Servlet specification. Spring tells Tomcat that all requests to http://myserver.com/ should be directed to Spring's DispatcherServlet, which is the main entry point.
Then it's up to Spring to further direct those requests to the code that handles them. There are different strategies for mapping a specific URL to the code that handles the request, but it's not set in stone and you could easily create your own strategy that would allow you to use whatever kind of URLs you want. For a simple (and stupid) example you could have http://myserver.com/1 that would execute the first method in a single massive handler class, http://myserver.com/2 would execute the second, etc.
The example is with Spring, but it's the same general idea with other frameworks. You have a mapper that maps an URL to the handler code.
These days it's all hidden under layers of abstraction so you don't have to care about the specifics of the mapping and can develop quickly and concentrate on the business code.
I apologize if some of my terminology is off, I'm still trying to learn:
I'm using the Dropwizard framework and I have a resource class with all my various POST/GET/etc methods. They all work fine when hit from Postman, browsers, etc. If I try something that has no matching path in the resource class I get an exception with HTTP status 405 - method not allowed.
Is there a way to default to some other method where I can display troubleshooting help -- like a list of what the available APIs are or a link to some documentation? Sort of like a try catch type of logic. Not sure what the options are or if there is a best way to do this.
Any help is appreciated. Thanks!
I don't think you might want to do that. REST over HTTP is driven "mostly" by the HTTP method and the end-point the same will act upon it.
In any stack, try to avoid that since you have specific actions for specific resources...anything else should be treated as something the server didn't understand, in the same way the HTTP protocol would behave.
Being said that, just apply a wildcard, usually * to one of the methods as a fallback action. That should work on Jersey and Spring Boot (MVC) as well.
How can I get themedisplay object in XYZServiceImpl?
My scenarios is like I am trying to fetch all document using web services but I need to WebDAV URL for each document using which user can download document.
I have done some googling for the same and I found following methods which provides the webdav and thumbnail but for that I required themedisplay object.
1.) DLUtil.getWebDavURL(themeDisplay, folder, fileEntry);
2.) DLUtil.getThumbnailSrc(fileEntry, dlFileShortcut, themeDisplay)
Also I need to check permission for each folder and document to get permission checker object I need themedisplay object.
Can anyone help me to get out from this as soon as possible OR any alternate solution to get this object?
The only (maintainable) way to get themeDisplay in your API calls is by requiring it as a parameter to the interface. In general though, this is a bad habit, as themeDisplay contains a lot of stuff from the front end layer, and typically your services should be well decoupled from the front layer. In fact, they might be called from contexts where there is no themeDisplay, in pure API calls.
Thus, the methods that you point to are made to be used from places where ThemeDisplay is available, but I'd like them better if they just required the necessary details instead of requiring the whole lot of themeDisplay information. On the other hand, that would make 4 instead of 1 parameter
If you build a service, you shouldn't require a themeDisplay as parameter. This might be easier said than done - it'll be more work for you, but provide cleaner code. On the other hand, you might have to duplicate the method that I've linked to above. There is no "correct" way to solve the problem under these circumstances, you'll have to judge for yourself
Edit: Answering to your comment: You can't get themeDisplay in a call that's coming in through the API - it's just not there. Now if you really need it and there's no way around: Look at the actual implementation of the method that you're going to call (which I've conveniently linked above) and create & initialize a ThemeDisplay object with the data that is required by the method you're going to call. And always remember that this is a workaround, don't do this routinely
I'm working on a servlet to perform some logic specific to a resourceType in sling and set information to the request to be accessible via the jsp then handing off the request to the jsp similarly to the first solution provided in this answer.
Here's some example code to represent my situation:
#SlingServlet(
resourceTypes="myapp/components/mycomponent",
methods="GET",
extensions={"html"}
)
...
#Reference
private ServletResolver serlvetResolver;
protected void doGet(....) {
setPropertiesToRequest();
Servlet servlet = servletResolver.resolveServlet(resource, "....jsp");
servlet.service(slingRequest, slingResponse);
clearPropertiesFromRequest();
}
Because of this, I've noticed that I've lost sling's selector handling (I've had to roll my own simpler version to determine which jsp to render. Full featured sling selector handling is described in more detail here). I wanted to reach out to the stack overflow community and ask what else I may be missing out on by depriving the default get handler of the request. I've scanned through the source code but I think there may be more going on.
Secondly, I'd be interested in thoughts on how and where this approach may impact performance of the request resolution.
Thanks, Thomas
Processing the business logic in Java and delegating to scripts for rendering sounds like a job for the recently released Sling Models. Using that should remove the need to implement your own handling of selectors, as those won't affect the model selection, only the rendering scripts.
Not sure what you are trying to achieve here, but the main problem seems to me that your SlingServlet handles the html extension and by itself does not have selectors to filter a bit more. Thus it of course intercepts all the requests to your component. Then you have to take care of the selectors again to be able to choose the correct JSP.
The question is, why do you use a SlingServlet for it when you anyway do the rendering by JSP?
Can't you implement your logic in the JSP or better in a bean referenced in the JSP?
In our company we use our custom tag that takes care of this, but there are public frameworks available from other Adobe Partner:
https://github.com/Cognifide/Slice
http://neba.io/index.html
My goal is to be able to use HttpUnit to crawl around my webpage and see what is and is not firing in the background... I have gotten it to connect to my page, and if I set
HttpUnitOptions.setLoggingHttpHeaders(true);
I see the sorts of background calls that I care about. However, I do not know how to see those interactions within the program. most of the getText and getInputStream calls fo the WebResponse object seem to just be the HTML call, and don't log the various javascript calls that fire in the background. Is there a way to get a list of all of the things going on in the background? HttpUnit's documentation seems sparse.
Thanks!
I just stumbled upon the answer. it looks like you need to make a class that implements WebClientListener, and then call wc.addClientListener(new YourListener()); where wc is a WebClient.
I don't delete this so others can see...and perhaps there is more nuance to it than that.