How to get Server Name, Port and Context - java

I have Java Web app.
I need get its URL where it is running (e.g. http://myserver:8080/mycontext).
I need it because I want to be able construct URL on some resource, that has been created.
e.g. By soap request was created resource /myresource and I need insert into soap response reference on this resource (http://myserver:8080/mycontext/myresource)
And I need to be able return URL on resource even when message come from JMS.
Is it possible to determine application URL during startup? e.g. in ServletContextListener.
Or how it is beeing solved?

You can get all those from the HttpServletRequest object, if you can get a hold of it.

Related

Get current domain name in an OSGi service component in AEM on activation

I am writing an OSGI service component in AEM.
I want to fetch current domain name in the activate method of the service component.
Currently, I'm writing a construct method, to get request from referring class/service/model/servlet to initialize the 'request' class object and using this request object to get the server name
private SlingHttpServletRequest request;
private String domainName;
#Override
public void construct(final SlingHttpServletRequest request) {
this.request = request;
}
#Override
public void setDomainName(){
this.domainName = request.getServerName();
}
And this.domainName is used in multiple service method implementations.
So, I have to call 2 extra service method,
Construct - to initialize global request object
setDomainName - to initialize domainName global object to be used across all the other service methods
Is there anyway to get domainName in activate method, so that i do not have to call the above two methods in order to use the service.
Note:- I cannot create an OSGI config for domain name, as this domain name is already being used as key property to identify the OSGI config of a given factory
Since AEM publish servers might be used for several domains, there is no way to "know" the right domain without getting the request. There might also be some magic being done by the web server and the CDN before the request is even reaching AEM.
On top of that, the activate method is not called each time the service is used, since those components are used multiple times.
So I think no, there is no way to guess what the domain of the next incoming request will be when the component is activated.
BR,
Oliver
To add to #OliverGeberts answer, this information can be added to the content (i.e. page properties of the language root) or some sort of tenant configuration.

At what point container creates request and response object?

When the client request comes, the container finds the correct servlet based on the URL and creates a pair of request and response objects.
According to me, the request and response objects only get created if the container finds valid servlet. That is, if there is no valid servlet found for the requested URL, then request and response objects don't get created.
However, I am not sure of this. Can anyone please confirm.
In chapter 12.1 Use of URL paths, the Servlet Specification states
The path used for mapping to a servlet is the request URL from the
request object minus the context path and the path parameters.
We can therefore assume that the request object (and possibly the response object) are created before any mapping logic is executed.
Note also that
Containers commonly recycle request objects in order to avoid the
performance overhead of request object creation.

How to manage requests without get parameters

I am currently using front controller pattern in a Java servlet and and redirecting requests to an appropriate handler via a "action" GET parameter. So, every link or process in the application will route to the front controller with an appropriate ?action=x query string and then the front controller uses the output from request.getParameter("action") to load and execute the appropriate handler.
How can I do this without having query strings in all of my URLs on the web application?
Here is the general approach used by most of the HTTP services framework.
You can use two things to decide about the handlers mapping:
The reference URL of entity i.e. URL part appended to the base URL of your application
The Http method, if you want to have different handlers for different HTTP operations
For example, you have this URL
http://mydomain.com/myapplication/myentity
Here the base URL part is: http://mydomain.com/myapplication/
Entity reference URL part is: myentity
Also the operation can be mapped to the HTTP method : GET(get), POST(create), DELETE(remove), PUT(update)
So you should have mapping of refURL myentity to some handler like MyEntityHandler class alongwith the operartion(optional). Pass the input request and response object for necessary information to the handler class.

Load early created object when servlet request coming

I am creating Map with data when the 1st request coming to servlet, then return it to JSP page, from that JSP page there is a another request coming to servlet and i want to have early created Map with data when 2nd request came, otherwise i have to load data again to new Map,
Is there any way to do this ? , i cant parse Map objects via HTTP request and i'am using Java
Thanks
There are three ways I can think of :
Put the data in the request scope and forward the requests using RequestDispatcher. This won't work if the requests are not forwarded and a new request is created.
Put the data in the session scope , the data will be valid through out the session for a particular client.
Put the data as ServletContext attribute , visible to all requests, sessions and throughout the web app.

How to send a username between web service requests?

Basically the problem is this:
There is a stored database procedure that takes a username as an argument and produces some XML data depending on it. It is called by a method with no arguments in an unsecured web service (let's call that web service WSA). There is also another web service (let's call it WSB) which is supposed to call WSA. In this setup, WSA should only ever be called by WSB and never by anyone else. WSB is what users call and it is the way they get the required XML data. The web services are deployed on OC4J, and they have security enabled on them. WSB is secured by OC4J and is accessed by providing the username and password of an OC4J user.
When testing a web service, OC4J provides you with a form where you can enter login information prior to invoking a web service. If you select to include security info in the header and preview the message before invoking the service, the username and password are in the message.
My problem is that I can't get the security information (or at least the username) to reach the endpoint implementation and invocation of the stored procedure.
So far I have created WSA, made a web service proxy that refers to it, and created WSB based on the proxy.
What I have tried so far to get the username (and why it doesn't work):
Had WSA implement javax.xml.rpc.server.ServiceLifecycle. This provides WSA with an instance of javax.xml.rpc.server.ServletEndpointContext, which provides me with a java.security.Principal. However, that Principal is null if I call WSB (which in turn calls WSA). If I secure WSA and call it directly, the Pricipal is not null and contains the user (but it doesn't solve the problem, because I need to call WSB, not WSA).
Created handlers (extending javax.xml.rpc.handler.GenericHandler) for both services, which were supposed to be able to process the message. One thing really baffled me here. The handler methods get called correctly - the WSB handler handles the request, then the WSA handler handles the request, then the WSA handler handles the response and finally the WSB handler handles the response. But when I tried printing the messages to a file on each step, I found out that even at the first step (when WSB handles the request) there is no security information in the message. No username, no nothing. The message is in fact quite different from what is shown on the invocation page when previewing the request message before invoking the service.
Tried injecting an instance of WebServiceContext by using the #Resource annotation, but apparently OC4J doesn't support this.
If anyone can shed some light on where I might be doing something wrong, I would be very thankful.
The problem is that "WSA is called by a method with no arguments in an unsecured web service". So, there is no security context for WSA to pick-up the user id from...
The simplest fix might be to change the WSA API to accept a user id in the request parameters.
HTH
Tom

Categories