Creación de su propio plugin REST (extensión de la API REST)
Puede crear su propio validador de formularios.
Condiciones:
- La nueva clase REST debe implementar la interfaz “RestPlugin”.
- La nueva clase REST debe declararse en 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 allí.
Descripción del método
Sección titulada «Descripción del método»| Método | Tipo | Descripción |
|---|---|---|
| executePlugin | String | 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 executePlugin devuelve un Object. Este objeto será procesado (serializado) por OpenKM. Los tipos básicos como String, Integer, etc. pueden utilizarse directamente, pero para los objetos complejos es necesario utilizar 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 con String
Sección titulada «Escenario con String»Desde el lado del plugin (lado del servidor) debe convertir el Object 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 con objeto complejo
Sección titulada «Escenario con objeto complejo»Puede utilizar clases existentes de OpenKM como Document, Folder, Record, Mail, entre otras, porque estas clases ya tienen la anotación.
Ejemplo de clases complejas:
Sección titulada «Ejemplo de clases complejas:»Devolver una lista de actividades:
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 utiliza una implementación de API de bajo nivel para subir rápidamente ficheros y establecer metadatos al mismo tiempo. El ejemplo incluye la implementación de un plugin y una prueba de plugin cliente.
Si tiene un proceso de subida de gran volumen y busca un mejor rendimiento, este es un buen enfoque.
- Descargue el proyecto de ejemplo sample-rest.zip.