Ir al contenido
Otras versiones

Cargando…

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í.

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
*/
@PluginImplementation
public 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
*/
@PluginImplementation
public 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);
}
}

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.

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 call
SomeObject someObject = new Gson().fromJson(value, SomeObject.class);

Puede utilizar clases existentes de OpenKM como Document, Folder, Record, Mail, entre otras, porque estas clases ya tienen la anotación.

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();
}
}

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.