Crear su propio Rest Plugin (extender la API REST)
Puede crear su propio REST Plugin.
Condiciones:
- La nueva clase REST debe implementar la interfaz “RestPlugin”.
- La nueva clase REST debe declararse bajo el paquete “com.openkm.plugin.rest”.
- La nueva clase REST debe estar anotada con “@PluginImplementation”.
- La nueva clase REST debe extender “BasePlugin”.
Interfaz REST:
package com.openkm.plugin.rest;
import net.xeoh.plugins.base.Plugin;
import java.io.InputStream;import java.util.Map;
/** * RestPlugin */public interface RestPlugin extends Plugin {
Object executePlugin(Map<String, String> parameters, InputStream is) throws Exception;
}La nueva clase debe ubicarse en el paquete com.openkm.plugin.rest porque el sistema de plugins de la aplicación intentará cargarla desde ahí.
Descripción del método
Sección titulada «Descripción del método»| Método | Tipo | Descripción |
|---|---|---|
| executePlugin | Object | El método ejecuta un plugin REST y devuelve un objeto. |
Ejemplo de implementación de un plugin REST
Sección titulada «Ejemplo de implementación de un plugin REST»package com.openkm.plugin.rest;
import com.openkm.plugin.BasePlugin;import net.xeoh.plugins.base.annotations.PluginImplementation;import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import java.io.InputStream;import java.util.Map;
/** * Sample rest plugin */@PluginImplementationpublic class TestRestPlugin extends BasePlugin implements RestPlugin {
private static Logger log = LoggerFactory.getLogger(TestRestPlugin.class);
@Override public Object executePlugin(Map<String, String> parameters, InputStream is) throws Exception { log.debug("executePlugin({})", parameters); StringBuilder sb = new StringBuilder(); sb.append("{"); sb.append("className=").append(this.getClass().getCanonicalName()); for (String key : parameters.keySet()) { sb.append(", " + key + "=").append(parameters.get(key)); } return sb.toString(); }}Ejemplo de implementación de un plugin REST que devuelve un fichero
Sección titulada «Ejemplo de implementación de un plugin REST que devuelve un fichero»package com.openkm.plugin.rest;
import com.openkm.bean.Document;import com.openkm.module.db.DbDocumentModule;import com.openkm.plugin.BasePlugin;import com.openkm.util.PathUtils;import net.xeoh.plugins.base.annotations.PluginImplementation;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.io.InputStreamResource;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;
import java.io.InputStream;import java.util.Map;
/** * Sample rest plugin */@PluginImplementationpublic class TestGetDocumentRestPlugin extends BasePlugin implements RestPlugin {
private static Logger log = LoggerFactory.getLogger(TestGetDocumentRestPlugin.class);
@Autowired private DbDocumentModule dbDocumentModule;
@Autowired private PathUtils pathUtils;
@Override public Object executePlugin(Map<String, String> parameters, InputStream is) throws Exception { log.debug("executePlugin({})", parameters); String docId = parameters.get("docId"); boolean inline = parameters.containsKey("inline"); Document doc = dbDocumentModule.getProperties(null, docId); String mimeType = doc.getMimeType(); String fileName = pathUtils.getName(doc.getPath()); InputStream isContent = dbDocumentModule.getContent(null, docId, false);
HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Content-Type", mimeType);
// inline true when you want to embedded the content into if (inline) { responseHeaders.add("Content-disposition", "inline; filename=\"" + fileName + "\""); } else { responseHeaders.add("Content-Disposition", "attachment; filename=\"" + fileName + "\""); }
responseHeaders.setContentLength(doc.getActualVersion().getSize()); InputStreamResource inputStreamResource = new InputStreamResource(isContent); log.debug("TestGetDocumentRestPlugin: [BINARY]"); return new ResponseEntity<>(inputStreamResource, responseHeaders, HttpStatus.OK); }}Declaración de objetos
Sección titulada «Declaración de objetos»El método executionPlugin devuelve un Object. Este objeto será procesado -serializado- por OpenKM. Los tipos básicos como String, Integer, etc. pueden usarse directamente, pero para objetos complejos necesita usar anotaciones en las clases.
Estrategias de serialización y deserialización:
- El resultado del método ejecutado es siempre un String. Internamente, el método convierte los objetos complejos a JSON.
- El resultado del método ejecutado es un objeto complejo.
Escenario String
Sección titulada «Escenario String»Desde el lado del plugin -lado servidor- debe convertir el objeto a JSON:
return new Gson().toJson(someObject)Desde el lado del cliente debe convertir la cadena JSON a un objeto:
// value contains the returned String value by the REST callSomeObject someObject = new Gson().fromJson(value, SomeObject.class);Escenario de objeto complejo
Sección titulada «Escenario de objeto complejo»Puede usar clases existentes de OpenKM como Document, Folder, Record, Mail entre otras, porque estas clases ya tienen las anotaciones.
Ejemplo de clases complejas:
Sección titulada «Ejemplo de clases complejas:»Devolver una lista de Activities:
package com.openkm.ws.rest.util;
import com.openkm.db.bean.Activity;
import java.util.ArrayList;import java.util.List;
public class ActivityList {
List<Activity> activities = new ArrayList<>();
private int totalElements;
public List<Activity> getActivities() { return activities; }
public void setActivities(List<Activity> activities) { this.activities = activities; }
public int getTotalElements() { return totalElements; }
public void setTotalElements(int totalElements) { this.totalElements = totalElements; }}Objeto complejo:
package com.openkm.bean;
public class Record extends Parent {
private static final long serialVersionUID = 1L; public static final String TYPE = "okm:record"; public static final String NAME = "okm:name";
private boolean locked; private LockInfo lockInfo; private String title; private boolean hasLinks;
public boolean isLocked() { return locked; }
public void setLocked(boolean locked) { this.locked = locked; }
public LockInfo getLockInfo() { return lockInfo; }
public void setLockInfo(LockInfo lockInfo) { this.lockInfo = lockInfo; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public boolean hasLinks() { return hasLinks; }
public void setHasLinks(boolean hasLinks) { this.hasLinks = hasLinks; }
@Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{"); sb.append("uuid=").append(uuid); sb.append(", parent=").append(parent); sb.append(", path=").append(path); sb.append(", permissions=").append(permissions); sb.append(", created=").append(created == null ? null : created.getTime()); sb.append(", subscribed=").append(subscribed); sb.append(", subscriptors=").append(subscriptors); sb.append(", keywords=").append(keywords); sb.append(", categories=").append(categories); sb.append(", notes=").append(notes); sb.append(", locked=").append(locked); sb.append(", lockInfo=").append(lockInfo); sb.append(", title=").append(title); sb.append(", nodeClass=").append(getNodeClass()); sb.append(", nodeClassChildren=").append(getNodeClassChildren()); sb.append(", dispositionCurrentStage=").append(getDispositionCurrentStage()); sb.append("}"); return sb.toString(); }}Ejemplo avanzado de REST
Sección titulada «Ejemplo avanzado de REST»El siguiente ejemplo es un proyecto que usa una implementación de API de bajo nivel para subidas rápidas y establecer metadatos al mismo tiempo. El ejemplo incluye una implementación del plugin y una prueba de plugin cliente.
Si tiene un proceso de subida masiva y busca un mejor rendimiento, este es un buen enfoque.
- Descargue el proyecto de ejemplo sample-rest.zip.