Supponiamo che io ho la seguente chiamata di servizio Web utilizzando @GET
metodo:Come funziona il caching in JAX-RS?
@GET
@Path(value = "/user/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserCache(@PathParam("id") String id, @Context HttpHeaders headers) throws Exception {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", id);
SqlSession session = ConnectionFactory.getSqlSessionFactory().openSession();
Cre8Mapper mapper = session.getMapper(Cre8Mapper.class);
// slow it down 5 seconds
Thread.sleep(5000);
// get data from database
User user = mapper.getUser(map);
if (user == null) {
return Response.ok().status(Status.NOT_FOUND).build();
} else {
CacheControl cc = new CacheControl();
// save data for 60 seconds
cc.setMaxAge(60);
cc.setPrivate(true);
return Response.ok(gson.toJson(user)).cacheControl(cc).status(Status.OK).build();
}
}
di sperimentare, ho rallentare il thread corrente 5 secondi prima di andare a prendere i dati dal mio database.
Quando chiamo il servizio Web utilizzando Firefox Poster, entro 60 secondi è sembrato molto più veloce nella seconda, terza chiamata e così via, fino a quando non ha superato i 60 secondi.
Tuttavia, quando si incolla l'URI su un browser (Chrome), sembra che rallenti ogni volta 5 secondi. E sono davvero confuso su come il caching sia effettivamente fatto con questa tecnica. Ecco le mie domande:
- Vuol POSTER effettivamente guardare l'intestazione
max-age
e decidere quando recuperare i dati? - Nel lato client (web, android ....), durante l'accesso al mio servizio web devo controllare l'intestazione e quindi eseguire la cache manualmente o il browser ha già memorizzato nella cache i dati stesso?
- C'è un modo per evitare di recuperare i dati dal database ogni volta? Immagino che dovrei memorizzare i miei dati in qualche modo, , ma potrebbe potenzialmente esaurire la memoria?
In questo tutorial JAX-RS caching tutorial: Come funziona effettivamente la cache? La prima riga recupera sempre i dati dal database:
Prenota myBook = getBookFromDB (id);
Quindi, come viene considerato memorizzato nella cache? A meno che il codice non venga eseguito nell'ordine in alto/in basso.
@Path("/book/{id}")
@GET
public Response getBook(@PathParam("id") long id, @Context Request request) {
Book myBook = getBookFromDB(id);
CacheControl cc = new CacheControl();
cc.setMaxAge(86400);
EntityTag etag = new EntityTag(Integer.toString(myBook.hashCode()));
ResponseBuilder builder = request.evaluatePreconditions(etag);
// cached resource did change -> serve updated content
if (builder == null){
builder = Response.ok(myBook);
builder.tag(etag);
}
builder.cacheControl(cc);
return builder.build();
}
Nota a margine, non rispondendo alla domanda: invece di '86400' puoi usare' TimeUnit.DAYS.toSeconds (1) '. Molto più facile per gli occhi e nessuno sforzo di decodifica necessario;) – fge
@fge: Grazie;) – Chan
Analogamente, puoi usare 'TimeUnit.SECONDS.sleep (5)', a proposito – fge