2009-03-24 20 views
46

Estoy escribiendo una aplicación web Java usando Spring MVC. Tengo un proceso en segundo plano que pasa por la base de datos y encuentra notificaciones que deben enviarse por correo electrónico a mis usuarios. Estos mensajes de correo electrónico deben incluir hipervínculos a la aplicación. Esto parece un patrón bastante común para una aplicación web, pero estoy teniendo problemas.Encontrar la URL de su aplicación con solo un ServletContext

¿Cómo obtengo la URL completa de mi aplicación, con el nombre del servidor y la ruta de contexto? No tengo acceso a ninguno de los métodos en HttpServletRequest porque estoy ejecutando esto como un proceso en segundo plano, no en respuesta a una solicitud web. Lo mejor que puedo hacer es tener acceso a ServletContext.

Actualmente estoy colocando la URL base en un archivo de configuración y leyéndola al inicio, pero esta aplicación se licenciará e implementará en los servidores de aplicaciones de los clientes, y de ser posible me gustaría que no tengan que configurar esto de forma manual.

+0

¿Por qué no puedes usar una URL relativa? – Eddie

+7

¿En relación a qué? Esto se envía en un correo electrónico. –

+0

Ah, si se está enviando en un correo electrónico, entonces, por supuesto, necesita un camino completo.Pensé que tal vez esto era parte de Servlet, algo que comenzó una tarea en segundo plano. – Eddie

Respuesta

29

No se recomienda preparar dinámicamente la URL en tiempo de ejecución, especialmente en función de ServletRequest. Esto se debe principalmente a que no tiene idea de la URL que los usuarios usarían para acceder a la aplicación: el servidor de aplicaciones podría estar detrás de un servidor web, un firewall o un equilibrador de carga. Para mantenerlo corto, uno no puede predecir las topologías de red.

Su técnica actual de recuperar el URL del archivo de propiedad es lo suficientemente buena para resolver dicho problema. Tal vez debería considerar proporcionar una consola administrativa para administrar la URL que aparece en los correos, especialmente si hay una consola de administración implementada, o si hay opciones relacionadas que deberían ir en una.

Editar: Mi último punto se hace eco de lo que Tony ha hablado.

7

Por qué simplemente no tener una página web de configuración que aparece la primera vez que se ejecuta la aplicación si el archivo de configuración no existe (en la carpeta WEB-INF, por ejemplo.) Usando ServletContext, puede llamar a getRealPath y obtener la ruta real de un archivo y ver si existe(). Si lo hace, redirija a la página de inicio de la aplicación, si no lo hace, abra la página de administración).

Lo mejor que puede hacer con ServletContext es leer algunas configuraciones de web.xml, y obtener la ruta del contexto, solo HttpRequest puede darle la URL de FQ.

+5

Para todas las personas downvoting: El usuario está accediendo a www.acme.com que es un servidor de seguridad F5/proxy inverso, que se conecta a un equilibrador de carga interno en http://loadbalancer.internal.acme.com, y finalmente llega a su servidor web en http://appserver3.internal.acme.com. Lo último que desea hacer es (re) dirigir a un usuario a una página en http://appserver3.internal.acme.com. La respuesta dada es la respuesta correcta, no puedes hacer nada mejor. –

0

¿Ha comprobado con un depurador si su ServletContext no es una instancia de HttpServletContext? Si es así, ejecútelo y obtenga la información de allí.

+0

Mis documentos API no enumeran ninguna clase ... –

+1

Esto no es recomendable. El usuario está accediendo a www.acme.com, que es un servidor de seguridad/proxy inverso F5, que se conecta a un equilibrador de carga interno en http://loadbalancer.internal.acme.com, y finalmente accede a su servidor web en http: // appserver3. internal.acme.com. Lo último que desea hacer es (re) dirigir a un usuario a una página en http://appserver3.internal.acme.com. –

1

creo que se puede usar algo como:

String host = InetAddress.getLocalHost().getCanonicalHostName(); 
String appUrl = String.format("http://%s:%s%s", host, port, contextPath); 

con puerto y contextPath desde ServletContext.

Cuestiones relacionadas