There are different methods to create cookies in HttpClient, I am confused which one is the best.
I need to create,retrieve and modify cookies.
For example , I can use the following code to see a list of cookies and modify them but how to create them ?
Is this a proper method for retrieving them? I need them to be accessible in all classes.
In addition methods that I have found usually require httpresponse, httprequest objects to send the cookie to browser, but how about if I do not want to use them?
Code
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
public class GetCookiePrintAndSetValue {
public static void main(String args[]) throws Exception {
HttpClient client = new HttpClient();
client.getParams().setParameter("http.useragent", "My Browser");
GetMethod method = new GetMethod("http://localhost:8080/");
try{
client.executeMethod(method);
Cookie[] cookies = client.getState().getCookies();
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
System.err.println(
"Cookie: " + cookie.getName() +
", Value: " + cookie.getValue() +
", IsPersistent?: " + cookie.isPersistent() +
", Expiry Date: " + cookie.getExpiryDate() +
", Comment: " + cookie.getComment());
cookie.setValue("My own value");
}
client.executeMethod(method);
} catch(Exception e) {
System.err.println(e);
} finally {
method.releaseConnection();
}
}
}
AND I've tried to create a cookie using following code but it does not
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
....
public String execute() {
try{
System.err.println("Creating the cookie");
HttpClient httpclient = new HttpClient();
httpclient.getParams().setParameter("http.useragent", "My Browser");
GetMethod method = new GetMethod("http://localhost:8080/");
httpclient.executeMethod(method);
org.apache.commons.httpclient.Cookie cookie = new
org.apache.commons.httpclient.Cookie();
cookie.setPath("/");
cookie.setName("Tim");
cookie.setValue("Tim");
cookie.setDomain("localhost");
httpclient.getState().addCookie(cookie);
httpclient.executeMethod(method);
System.err.println("cookie");
}catch(Exception e){
e.printStackTrace();
}
Output is as following but no cookie will be created.
SEVERE: Creating the cookie
SEVERE: cookie
Scenario
1)User has access to a form to search for products (example.com/Search/Products)
2)User fills up the form and submit it to class Search
3)Form will be submitted to Search class
4)Method Products of Search class returns and shows the description of product
(example.com/Search/Products)
5)User clicks on "more" button for more description about product
6)Request will be sent to Product class (example.com/Product/Description?id=4)
7)User clicks on "add to cookie" button to add the product id to the cookie
Product class is subclasse of another class. So it can not extend any more class.
In the second example, you are creating a new client-side cookie (i.e. you are impersonating a browser and are sending the cookie to the server).
This means that you need to provide all the relevant information, so that the client can decide whether to send the cookie to the server or not.
In your code you correctly set the path,name and value, but the domain information is missing.
org.apache.commons.httpclient.Cookie cookie
= new org.apache.commons.httpclient.Cookie();
cookie.setDomain("localhost");
cookie.setPath("/");
cookie.setName("Tim");
cookie.setValue("Tim");
This works if what you are trying to achieve is to send a cookie to an http server.
Your second example, though, spans from an execute method, an since you are hinting at struts2 in your tag, maybe the class containing it is meant to be a struts2 Action.
If this is the case, what you are trying to achieve is to send a new cookie to a browser.
The first approach is to get hold of a HttpServletResponse as in:
So your Action must look like:
public class SetCookieAction
implements ServletResponseAware // needed to access the
// HttpServletResponse
{
HttpServletResponse servletResponse;
public String execute() {
// Create the cookie
Cookie div = new Cookie("Tim", "Tim");
div.setMaxAge(3600); // lasts one hour
servletResponse.addCookie(div);
return "success";
}
public void setServletResponse(HttpServletResponse servletResponse) {
this.servletResponse = servletResponse;
}
}
Another approach (without HttpServletResponse) could be obtained using the CookieProviderInterceptor.
Enable it in struts.xml
<action ... >
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="cookieProvider"/>
...
</action>
then implement CookieProvider as:
public class SetCookieAction
implements CookieProvider // needed to provide the coookies
{
Set<javax.servlet.http.Cookie> cookies=
new HashSet<javax.servlet.http.Cookie>();
public Set<javax.servlet.http.Cookie> getCookies()
{
return cookies;
}
public String execute() {
// Create the cookie
javax.servlet.http.Cookie div =
new javax.servlet.http.Cookie("Tim", "Tim");
div.setMaxAge(3600); // lasts one hour
cookies.put(cookie)
return "success";
}
}
(credits to #RomanC for pointing out this solution)
If you subsequently need to read it you have two options:
implement ServletRequestAware in your Action and read the cookies from the HttpServletRequest
introduce a CookieInterceptor and implement CookiesAware in your Action, the method setCookieMap allows to read the cookies.
Here you can find some relevant info:
Using cookies with Struts 2 and Struts
First of all you propably do not want to use HttpClient, which is a client (e.g. emulates a browser) and not a server (which can create cookies, that the user's browser will store).
That said, I'm first explaining what happens in your first code example:
You send a GET request to a server
The server sends you some cookies alongside it's response (the content)
You modify the cookies in your HttpClient instance
You send those cookies back to the server
What the server does with your changed cookies entirely depends on what that server is programmed to do
At the next request the server might send those changed cookies back to you or not, which as I allraedy said depends on what it is programmed to do.
As for you second example:
You create a cookie
You set some information on the cookie
You send the cookie to the server (inside your GET request)
The server now does with your cookie what it is programmed to do with it. Propably the server ignores your cookie (e.g. does not send it back to you).
On the other hand what you propably want to do is write a web application (e.g. the server side), that creates the cookie and changes it depending on the client's input (the browser).
For that you can use the Servlet API. Something along the lines:
javax.servlet.http.Cookie cookie = new
javax.servlet.http.Cookie("your cookie's name", "your cookie's value");
//response has type javax.servlet.http.HttpServletResponse
response.addCookie(cookie);
Creating a web application is way out of scope of a simple stackoverflow answer, but there are many good tutorials out there in the web.
There is no way around creating a web application if the user should use a browser to see your products. There are just different ways to create one, different frameworks. The servlet API (e.g. HttpServletResponse and HttpServletResponse) is the most basic one.
I'd say it (the servlet API) is also the easiest one you can find to solve this exact problem with java, even though it is not exactly easy to get started with web applications at all.
Related
I am practicing maintaining sessions between client and server. For that I used simple solution with JSESSIONID stored inside cookie. So my little program works like this:
index.html:
<html><body>
<form action="testing">
<input type="text" name="animal">
<button>Go</button>
</form>
</body></html>
MyServlet.java (mapped in XML as /testing):
public class MyServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
String name = req.getParameter("animal");
PrintWriter pw = resp.getWriter();
pw.print("Welcome " + name + "<br>");
HttpSession session = req.getSession();
if (session.isNew()) {
pw.print("New session: " + session.getId() + "<br>");
} else {
pw.print("Old session: " + session.getId() + "<br>");
}
pw.print("<a href=\'index.html\'> Home </a>");
}
}
So, if I submit something from FORM more than twice, Server should "find" my JSESSIONID stored in heap. Here is a picture of how it would look when FORM is submitted (I typed 'parrot' inside input):
But then I disabled cookies in my browser. After, my server never finds user's JSESSIONID because user never actually stores it anywhere. Remember that before, JSESSIONID was stored in a cookie, but since I disabled them, it can't possibly store it there anymore. So now, I am stuck.
What can I do in this case? I came across response.encodeURL() that uses URL and appends its JSESSIONID into URL. But I have trouble understanding how to implement it and how it works internally. Can someone tell me how to fix this using encodeURL() and actually explain how does code work after made such implementation?
As per the specification, the server should support a few ways of tracking sessions: with cookies, SSL sessions, or URL rewriting.
You are asking about URL rewriting, which works like this:
URL rewriting is the lowest common denominator of session tracking. When a client will not accept a cookie, URL rewriting may be used by the server as the basis for session tracking. URL rewriting involves adding data, a session ID, to the URL path that is interpreted by the container to associate the request with a session.
The session ID must be encoded as a path parameter in the URL string. The name of the parameter must be jsessionid. Here is an example of a URL containing encoded path information:
http://www.myserver.com/catalog/index.html;jsessionid=1234
URL rewriting exposes session identifiers in logs, bookmarks, referer headers, cached HTML, and the URL bar. URL rewriting should not be used as a session tracking mechanism where cookies or SSL sessions are supported and suitable.
Notice that it's a path parameter, not a query parameter. Your query params will follow that, like this:
http://www.myserver.com/catalog/index.html;jsessionid=1234?param1=value1¶m2=value2&...
This mechanism is supported automatically by the server to track sessions, but it becomes pretty obvious that you need to give the server a helping hand. And you do that by making sure that all your links include the jsessionid otherwise your server won't identify your request with a session.
You can use encodeURL in your Java code:
Encodes the specified URL by including the session ID, or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL. For example, if the browser supports cookies, or session tracking is turned off, URL encoding is unnecessary.
For robust session tracking, all URLs emitted by a servlet should be run through this method. Otherwise, URL rewriting cannot be used with browsers which do not support cookies.
You need to do the same inside your JSP files. That's usually done with something like <c:url> instead of writing URLs directly into the file:
[...] You can use the url tag to rewrite URLs returned from a JSP page. The tag includes the session ID in the URL only if cookies are disabled; otherwise, it returns the URL unchanged. Note that this feature requires that the URL be relative. [...]
Here is something you can do. This is used to append your JSESSIONID to a url you would retrieve to the user, so they can navigate in it and maintain the information of who they are. About understanding how it works internally is simple as you see, it just append the id to a url you pass, how the user information are stored, is your function on the server side, you will use the id given by the user in the next requests to retrieve information to them.
/**
* Almost minimal processing for a servlet.
*
* #param nextUrl The url the caller would like to go to next. If
* supplied, put an encoded url into the returned
* html page as a hyperlink.
*/
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
out.print("OK");
String param = req.getParameter("nextUrl");
if (param!=null) {
// append an encoded url to carry the sessionids
String targetUrl = resp.encodeURL(param);
out.print(". You want to go <a href=\"");
out.print(targetUrl);
out.print("\">here next</a>.");
}
}
Edit:
You put it in this part of your code
pw.print("<a href=\'" + resp.encodeURL("index.html") + "\'>Home</a>");
I am working on a platform made in VAADIN. If you want to see it is www.wikire.it.
In this home page, to login, you have to click on "Accedi" and then compile textfields into the modal form that appears.
The platform has also another application (different from that mentioned before) that works as backoffice.
The purpose is to make a button in the backoffice that logges into the site with some credentials(is not important how to get it).
I am new in this platform, I have some ideas but i don't know what to do (as workflow) :
- Rest Services
- Web services from the site
How can I satisfy my purpose ?
Sorry if is a generic question, but I need it for my work and i don't know what to do for first.
One way you can do this without changing much in your existing site is to:
use the Apache's HttpClient library to launch, triggered by some user action like a button or link click in your backoffice app, a (POST) request with the necessary parameters (username, password, eventual hidden fields) towards your site's login address (I believe in your case it's http://www.wikire.it/logon)
upon a successful login, the site will (probably) send back to your HttpClient instance at least one cookie used for authentication -- get a hold of it :) (in the example I've provided -- see below -- I am assuming this cookie is named JSESSION, the usual case for Java apps creating a user session; if your site is done using a different technology like PHP, etc. make sure you find out how the session / authentication cookie looks like for that technology)
set an identical cookie (for the site's domain, wikire.it and / as path) in your response to the request that had been done in the backoffice (Remember: A. the auth cookie you receive back from the site is set / present for the HttpClient instance for the moment, not for the actual client, which is your browser! and B. handling a Vaadin event, within a listener, eventually implies a response that will be sent back to your browser
to finish handling the user click, ask the Vaadin Page to execute a window.open('http://www.wikire.it/') JavaScript call (i.e. passing your target site's address and, maybe, '_blank' as a second parameter to force opening the page in a new window / tab; this might get blocked though by a browser that wouldn't allow opening popups so... take care)
That should do it. Note that logging into a site is completely independent of Vaadin -- you just have to find a way to set the cookie for the browser and make it execute that last JavaScript call.
I've created 2 sample projects here: https://github.com/octavian-nita/so/tree/master/so-42927030-vaadin-login-to-site-button. site is a very basic java / jsp app protected by a login page (the user name you can use to login is Johnny, the password doesn't matter) to serve as target site to login to. backoffice is a tiny Vaadin app with a button you can click to login to site.
For your convenience, I'm highlighting the relevant bits of code below.
Adding a Maven Dependency on HttpClient
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
Creating a Routine That Logs Into a Site and Returns the Auth Cookie
This implies you know the path used for the login action (usually what's specified in the login form).
private Cookie login(URI targetUri, String loginPath, Map<String, String> params) throws IOException {
requireNonNull(targetUri);
requireNonNull(loginPath);
// Keep track of cookies we might receive in an HttpClient:
final CookieStore cookies = new BasicCookieStore();
// Build and work with an (AutoCloseable) HttpClient that uses the cookie store:
try (CloseableHttpClient client = HttpClients.custom().setDefaultCookieStore(cookies).build()) {
// Prepare (login) request parameters:
List<NameValuePair> reqParams = new ArrayList<>();
if (params != null) {
for (Map.Entry<String, String> entry : params.entrySet()) {
reqParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
}
// Execute the login (POST) request with the given parameters:
HttpPost post = new HttpPost(targetUri + loginPath);
post.setEntity(new UrlEncodedFormEntity(reqParams));
CloseableHttpResponse response = client.execute(post);
// Eventually, check the response to see if successful
response.close();
// Look for a JSESSIONID-named cookie stored in the HttpClient and return it to be used by calling code:
for (org.apache.http.cookie.Cookie cookie : cookies.getCookies()) {
if ("JSESSIONID".equalsIgnoreCase(cookie.getName())) {
String domain = targetUri.getHost();
if (domain.startsWith("www.")) {
domain = domain.substring(4);
}
Cookie authCookie = new Cookie(cookie.getName(), cookie.getValue());
authCookie.setDomain(domain);
authCookie.setPath("/");
// Eventually, set expiry (to allow longer login) and other things...
return authCookie;
}
}
return null; // some sort of error?
}
}
Setting the Auth Cookie in the Browser and Opening the Site, in Vaadin
#Title("Backoffice for SO Question #42927030")
public class MainUI extends UI {
private Cookie login(URI targetUri, String loginPath, Map<String, String> params) throws IOException {
// ...
}
#Override
protected void init(VaadinRequest vaadinRequest) {
setContent(new VerticalLayout(new Button("Log into site...", event -> {
try {
URI targetUri = new URI("http://localhost:8080");
Map<String, String> params = new HashMap<>();
params.put("username", "Johnny");
params.put("password", "incorrect :)");
// Eventual hidden fields, etc.
// params.put("...", "...");
Cookie targetAuthCookie = login(targetUri, "/log-me-in", params);
// We're not ready just yet: we still need to 'transfer' the cookie
// the HTTP client received to the current browser:
VaadinService.getCurrentResponse().addCookie(targetAuthCookie);
// Upon responding to the Vaadin 'click' request, open the target URL (eventually in a new page / tab):
Page.getCurrent().getJavaScript().execute("window.open('" + targetUri + "');");
} catch (Exception ex) {
ex.printStackTrace();
}
})));
}
#WebServlet(urlPatterns = "/*", name = "MainUIServlet", asyncSupported = true)
#VaadinServletConfiguration(ui = MainUI.class, productionMode = false)
public static class MainUIServlet extends VaadinServlet {}
}
Let us know how this goes for you...
First of all, I want to send parameters from html to Servlet and it works.
Then I create an array from parameters and I want to send that array to another servlet. and just print it in Servlet2.
Here is my code:
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//System.out.println("XML servlet called!");
response.setContentType("text/html");
response.getWriter();
//read value from selection
String videoname = request.getParameter("video");
String videoformat = request.getParameter("format");
String videoquality = request.getParameter("quality");
//System.out.println("Name" + videoname);
//System.out.println("format" + videoformat);
//System.out.println("quality" + videoquality);
String [] chain1 = {"v1","f1","q1"};
String [] chain2 = {"v1","f1","q2"};
if (videoname.equals(chain1[0]) && (videoformat.equals(chain1[1])) && (videoquality.equals(chain1[2])) ){
request.setAttribute("chain",chain1);
}
}else if (videoname.equals(chain2[0]) && (videoformat.equals(chain2[1])) && (videoquality.equals(chain2[2])) ){
request.setAttribute("chain",chain2);}
RequestDispatcher dispatch = request.getRequestDispatcher("/Servlet2");
dispatch.forward(request, response);
And in Second Servlet , my code is :
String value = (String)request.getAttribute("chain");
System.out.println("Chain is" + value);
My problem is this is doesn`t work. I have 2 problems. 1) how to send attribiute 2) is that possible to see the result in servlet2 in the same mashin? becuse I just create another class wich name is Servlet2 on the same project and define the name and the path in web.xml. Is that right approch?
How to send attribute?
What you are doing to send the attribute (using request.setAttribute and then using dispatch.forward is correct.
Assuming you have just created one new servlet named Servlet2 within the same project and have configured it correctly in web.xml, you should be able to get the attribute in that servlet's GET or POST method.
I believe that you are running into issues because you are modifying the response, which should be done by Servlet2 and not Servlet1. Remove the following lines from your code
response.setContentType("text/html");
response.getWriter();
,since you are not handling the response in Servlet1. This should work, if not, modify your question and include the complete stack trace of the error that you get when you try to compile/run this.
Servlets are created to handle requests sent by clients. I assume that your servlet2 class does a such service. If you declare a public static variable in a servlet, it is accessible by any class. Therefore you don't need to send your data to client from servlet1 and get the client sent them back to servlet2. If you have common variables to all servlets in a web server, you can use static variable. If the sole purpose of servlet2 is printing your data, it shouldn't be a servlet, just a java class would be fine.
Remember that only 1 servlet instance will be created for all requests. Therefore don't use instance variables to store client specific data. Try to use sessions.
This should help you.
We have a portlet based application that retrieves a certain cookie for validation and then sends off an action request afterwards.
However, we're seeing an issue where the HttpServletRequest is returning a null list of cookies - even though I can 100% confirm there are cookies. In fact, sometimes the code DOES work and shows the cookies (although this is pretty rare).
We've noticed that IE appears to work more frequently than FF and Chrome, but again, there's no consistency or pattern really to determine what causes it to function.
The Request is always obtained - there's never an issue here of a null pointer. The only issue at this moment is that the cookie list is empty.
Method in static class that returns HttpServletRequest
FacesContext context = FacesContext.getCurrentInstance();
Map<String, Object> requests = context.getExternalContext().getRequestMap();
for (String requestName : requests.keySet()) {
if (requests.get(requestName) instanceof HttpServletRequest) {
return ((HttpServletRequest) requests.get(requestName));
}
}
return null;
Call from the other class to the static method above:
Cookie[] cookies = StaticClass.getHttpRequest().getCookies();
System.out.println("Cookies = " + cookies);
The HttpServletRequest method getCookies() should return an array of cookies the client sent in on the request. If the array returned is null, it means that the request the client sent in contains no cookies. Did you call addCookie(yourCookie) method within the same domain or subdomain (I ask as you cannot access cookies across different domains)?
ie:
Cookie yourCookie = new Cookie(name, value);
response.addCookie(yourCookie);
If the cookie was not added to a previous response, it will not be on the request.
Some other clues:
Check your Cookie's max age. Cookie may be expired.
Check the domain of the cookie and the domain of the request URL. If you are not sure, post them here for help.
In general if you can capture the http request message and post it here it will also be helpful.
Update: in firefox you can right click a page, and select 'view page info', then select the 'security' tab, click the 'view cookies' button to view all the cookies. You can also change the domain name in the popup window to see the cookies under other domain.
I've created a Java web service using the #WebService annotation and deployed the service to a Glassfish server that lives behind a proxy server.
The problem is when someone accesses our WSDL and looks at the service endpoint address location they see
http://app server url/service...
instead of
http://proxy server url/service...
I'd like to have the proxy server URL returned in the service endpoint address location of the WSDL instead of the app server url.
What I'm wondering is, can I write a Filter or a Listener to listen for requests to the WSDL, then modify the WSDL service endpoint address with the proxy server URL? What might be the recommended way to do this - I was thinking a Filter is the best choice, but wasn't 100% sure?
BTW - I thought there might be a simple setting in Glassfish to do this, but I haven't been able to locate one that works.
I took the filter approach and here's what I came up with. It seems to work.
I've included the code for my Filter's doFilter method. I also wrote a custom HttpServletResponseWrapper, but that implementation was pretty straightforward.
the Apache reverse-proxy adds the x-forwarded-host value to the HTTP header (and is the name I use to replace the app servers name). Another alternative I thought of was to place the proxy server's address as a property on the app server and grab that. Ultimately, I thought this was a cleaner way to go.
/*
* Replace the server URL with the proxy server URL when called from a proxy server
*/
#Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain filterChain) throws IOException, ServletException
{
WsdlResponseWrapper myResponse = new WsdlResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(request, myResponse);
boolean isResponseOutputStream = myResponse.getOutputStreamContent().length > 0;
/*
* The servlet response sent into this method only allows access to
* getOutputStream or getWriter, not both. It will throw an
* exception if an attempt is made to to access both.
*
* If this reason, I'm checking the output stream first and writing
* that content if it exists, then printing to the writer only if
* the output stream is empty.
*/
StringBuffer responseBuffer;
if (isResponseOutputStream) {
responseBuffer = new StringBuffer(new String(myResponse.getOutputStreamContent()));
} else {
responseBuffer = new StringBuffer(myResponse.getWriterContent());
}
// Change the URL when called from a proxy server
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String requestedHostname = httpServletRequest.getHeader("x-forwarded-host");
if ((null != requestedHostname) && !requestedHostname.isEmpty()) {
String myHostname = httpServletRequest.getHeader("host");
int myPort = httpServletRequest.getLocalPort();
// change the hostname
int index = responseBuffer.indexOf(myHostname);
int length = myHostname.length();
while (index > -1) {
responseBuffer.replace(index, index+length, requestedHostname);
index = responseBuffer.indexOf(myHostname);
}
// remove the port
String portString = ":" + myPort;
length = portString.length();
index = responseBuffer.indexOf(portString);
while (index > -1) {
responseBuffer.replace(index, index+length, "");
index = responseBuffer.indexOf(portString);
}
}
}
// forward the response
if (isResponseOutputStream) {
response.getOutputStream().write(responseBuffer.toString().getBytes());
} else {
response.getWriter().print(responseBuffer);
}
}
From Javaboutique article on servlet-filters
public final class TimerFilter implements Filter
{
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
long startTime = System.currentTimeMillis();
chain.doFilter(request, response);
long stopTime = System.currentTimeMillis();
System.out.println("Time to execute request: " + (stopTime - startTime) +
" milliseconds");
}
...
the call to chain.doFilter will call the normal servlet in your case (I'm assuming the #WebService is provided through a servlet API), and you can then read the result from the original web service, modify it, and pass it back to your own client.
Did you consider using a web service registry for that?
The glassfish doc about web service registry says:
If you are using a load balancer,
enter the Load Balancer host name,
port number, and the SSL port number.
If you are publishing the web service
to an external registry, where the
WSDL can be found over the internet,
these options will replace the
hostname and port name specified in
the WSDL to the one of the load
balancer.
So that should work for your proxy as well.
Here are two resources that might be interesting: the glassfish ws management page, an article aobut how to set up the registry.
I never used the registry myself, and agree that it's a bit heavy-weighted for what you want to achieve, but it seems to be a possible way to publish web service endpoint information for consumers.
If Apache is your proxy, you can try doing what I did, which is really simple. Apache causes the problem (sort-of), so use Apache to fix it:
https://stackoverflow.com/a/18136594/2666055