Fijar rutas relativas en HTML servidos por servlets Java (para HTML5 pushState)

votos
3

Estoy intentando modificar un servidor de embarcadero, que tiene un servlet (RootResource.java) que de alguna manera mágica recoge y utiliza:

@Singleton
@Path(/)
public class RootResource {
    @Context
    private ServletContext servletContext;

    @GET
    @Path(react-client/{path: .*\\..+$})
    public Response serveReactClientContent(@Context HttpServletRequest httpServletRequest) {
        // This doesn't work, a resolved relative resource is not relative
        // to the /react-client base. See description of problem.
        final String pathToResource = httpServletRequest.getRequestURI();
        return serveStaticContent(pathToResource);
    }

    @GET
    @Path(react-client/{path: .*$})
    public Response serveReactClientIndexPage(@Context HttpServletRequest httpServletRequest) {
        return serveStaticContent(/react-client/index.html);
    }

    private Response serveStaticContent(String pathToResource) {
        final String type = this.servletContext.getMimeType(pathToResource);
        final Response.ResponseBuilder response = Response.ok(servletContext.getResourceAsStream(pathToResource)).type(type);
        return response.build();
    }
}

La idea es tomar una solicitud GET a react-client/some/pathy devolver el contenido de react-client/index.html. Esencialmente haciendo embarcadero se comporta como un servidor de aplicación web que utiliza el enrutamiento lado del cliente.

El problema que estoy teniendo es que las rutas relativas en el index.html único trabajo si la ruta es un nivel de profundidad , por ejemplo react-client/products.

<script src=./webapp.js></script>

En ese caso se encuentra el archivo JavaScript anterior en index.html porque webapp.jses un archivo que existe en react-client/webapp.js.

Tan pronto como lo intento un ejemplo de enlace profundo react-client/products/97357361que falla como el servlet trata de encontrar webapp.jsen react-client/products/webapp.jsel cual no existe.

¿Cómo puedo hacer que solicitar el recurso siempre como si es de /react-client? Gracias

Publicado el 27/11/2018 a las 16:52
fuente por usuario
En otros idiomas...                            


2 respuestas

votos
0

Debido a que su index.htmlpodría conseguir el acceso de múltiples URLs tales como

  • / reaccionar-cliente / productos
  • / reaccionar-cliente / productos / 97357361
  • / Reaccionar-cliente / alguna
  • / Reaccionar-cliente / some / ruta

Podría ser conveniente añadir una <base>etiqueta en el encabezado de la página HTML.

<head>
    ...
    <base href="https://www.yourwebsite.com/react-content/" />
    <script src="./script.js"></script>
    ...
</head>

Esto indicará al navegador para resolver cualquier ruta relativa que se encuentra en la página como en relación con el https://www.yourwebsite.com/react-content/

Así, de acuerdo con el ejemplo anterior, <script src="./script.js"></script>se solicita al servidor que "https://www.yourwebsite.com/react-content/script.js"independientemente de la URL actual que ser útil para acceder a esta página.

A continuación, puede volver esos ajustes en el embarcadero y que sea sencillo.

Respondida el 07/12/2018 a las 11:17
fuente por usuario

votos
0

He intentado muchas cosas tales como filtros y reescribir los manipuladores , pero en ningún momento embarcadero siempre proporcionan la importación relación no resuelta original (por ejemplo ./webapp) así que nunca tuve la oportunidad de volver a escribir los recursos relativos.

Al final tuve que simplemente detectarlos con un corte en el conocimiento de que estaban casi todos solicitarse a un /static/subdirectorio (que tenía que agregar una excepción de duro codificado para favicon.icoy manifest.json.

@GET
@Path("react-client/{path: .*\\..+$}")
public Response serveReactClientContent(@Context HttpServletRequest httpServletRequest) {
    final String pathToResource = httpServletRequest.getRequestURI();

    Pattern p = Pattern.compile("/react-client/(.+?(?=static/|favicon.ico))", Pattern.CASE_INSENSITIVE);
    Matcher m = p.matcher(pathToResource);
    String resolveResourcePath = m.replaceAll("/react-client/");
    return serveStaticContent(resolveResourcePath);
}

No contento con él, pero funciona.

Respondida el 03/12/2018 a las 15:33
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more