Hola,
En esta publicación de blog para principiantes, veremos cómo podemos usar objetos grandes (LOB) en el modelo de programación de aplicaciones tranquilas ABAP.
En esta publicación de blog, veremos cómo cargar un archivo en el modelo de programación de aplicaciones ABAP Restful.
La anotación utilizada para trabajar con objetos grandes es @Semantics.largeObject
En esta aplicación de demostración vamos a cubrir los siguientes requisitos:
La carga de archivos en cualquier aplicación comercial es un requisito muy común, que no estaba disponible a través del marco ABAP RAP hasta el lanzamiento de SAP BTP ABAP 2208.
Según nuestro escenario, vamos a crear un registro de estudiante y cargaremos varios documentos para el estudiante creado.
Cree una tabla persistente para Student como se muestra a continuación.
@EndUserText.label : 'Student Table Header'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zstudent_hdr_tab {
key client : abap.clnt not null;
key id : sysuuid_x16 not null;
firstname : abap.char(100);
lastname : abap.char(100);
age : abap.numc(4);
course : abap.char(50);
courseduration : abap.numc(4);
status : abap_boolean;
gender : abap.char(1);
dob : abap.dats;
lastchangedat : timestampl;
locallastchangedat : timestampl;
}
Crear tabla persistente para archivos adjuntos para estudiantes
@EndUserText.label : 'Attachment Table'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zstudent_att_tab {
key client : abap.clnt not null;
key attach_id : char32 not null;
id : sysuuid_x16 not null;
comments : char30;
attachment : zattachment1;
mimetype : char128;
filename : char128;
}
Estamos viendo un campo con un nombre adjunto de tipo zatachment1. El tipo de datos adjuntos es muy importante y dado que vamos a guardar un archivo o datos binarios o datos sin procesar en este campo, el tipo de campo debe ser CUERDA PRIMA con longitud 0.
La longitud 0 no es obligatoria, pero si la longitud no es 0, habrá restricciones en el tamaño del archivo que se puede cargar. 0 longitud significa que se pueden cargar archivos grandes sin restricción de tamaño de archivo.
Cree vistas de interfaz para la tabla de estudiantes y archivos adjuntos.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface View Entity for Student'
define root view entity zstudent_hdr_tab_I as select from zstudent_hdr_tab
composition[1..*] of zstudent_att_tab_i as _Attachments
{
@EndUserText.label: 'Student ID'
key zstudent_hdr_tab.id as Id,
@EndUserText.label: 'First Name'
zstudent_hdr_tab.firstname as Firstname,
@EndUserText.label: 'Last Name'
zstudent_hdr_tab.lastname as Lastname,
@EndUserText.label: 'Age'
zstudent_hdr_tab.age as Age,
@EndUserText.label: 'Course'
zstudent_hdr_tab.course as Course,
@EndUserText.label: 'Course Duration'
zstudent_hdr_tab.courseduration as Courseduration,
@EndUserText.label: 'Status'
zstudent_hdr_tab.status as Status,
@EndUserText.label: 'Gender'
zstudent_hdr_tab.gender as Gender,
@EndUserText.label: 'DOB'
zstudent_hdr_tab.dob as Dob,
zstudent_hdr_tab.lastchangedat as Lastchangedat,
zstudent_hdr_tab.locallastchangedat as Locallastchangedat,
_Attachments // Make association public
}
@semantics.LatgeObject se usa para agregar la opción de carga de archivos en la vista de interfaz del encabezado del estudiante.
contentDispositionpreference : Este valor de propiedad decidirá si el archivo debe descargarse o debe abrirse en la pestaña del navegador cuando el usuario haga clic en el nombre del archivo una vez cargado.
#INLINE: el archivo se abrirá en la pestaña del navegador
#ADJUNTO: El archivo se descargará en la máquina local de los usuarios
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'View for Attachment'
define view entity zstudent_att_tab_i as select from zstudent_att_tab
association to parent zstudent_hdr_tab_I as _Student
on $projection.Id = _Student.Id {
key zstudent_att_tab.attach_id as AttachId,
zstudent_att_tab.id as Id,
@EndUserText.label: 'Comments'
zstudent_att_tab.comments as Comments,
@EndUserText.label: 'Attachments'
@Semantics.largeObject:{
mimeType: 'Mimetype',
fileName: 'Filename',
contentDispositionPreference: #INLINE
}
zstudent_att_tab.attachment as Attachment,
@EndUserText.label: 'File Type'
zstudent_att_tab.mimetype as Mimetype,
@EndUserText.label: 'File Name'
zstudent_att_tab.filename as Filename,
_Student.Lastchangedat as LastChangedat,
_Student // Make association public
}
Cree una vista de proyección y agregue anotaciones de interfaz de usuario para la aplicación Fiori.
@EndUserText.label: 'Projection view for Header table'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define root view entity zstudent_att_tab_p
provider contract transactional_query
as projection on zstudent_hdr_tab_I
{
@UI.facet: [{
id: 'StudentData',
purpose: #STANDARD,
label: 'Student Data',
type: #IDENTIFICATION_REFERENCE,
position: 10
},{
id: 'Upload',
purpose: #STANDARD,
label: 'Upload Attachments',
type: #LINEITEM_REFERENCE,
position: 20,
targetElement: '_Attachments'
}]
@UI: {
selectionField: [{ position: 10 }],
lineItem: [{ position: 10 }],
identification: [{ position: 10 }]
}
key Id,
@UI: {
lineItem: [{position: 20 }],
identification: [{position: 20 }]
}
Firstname,
@UI: {
lineItem: [{position: 30 }],
identification: [{position: 30 }]
}
Lastname,
@UI: {
lineItem: [{position: 40 }],
identification: [{position: 40 }]
}
Age,
@UI: {
lineItem: [{position: 50 }],
identification: [{position: 50 }]
}
Course,
@UI: {
lineItem: [{position: 60 }],
identification: [{position: 60 }]
}
Courseduration,
@UI: {
lineItem: [{position: 70 }],
identification: [{position: 70 }]
}
Status,
@UI: {
lineItem: [{position: 80 }],
identification: [{position: 80 }]
}
Gender,
@UI: {
lineItem: [{position: 90 }],
identification: [{position: 90 }]
}
Dob,
Lastchangedat,
Locallastchangedat,
/* Associations */
_Attachments : redirected to composition child zstudent_att_tabl_p
}
@EndUserText.label: 'Projection for Attachment'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view entity zstudent_att_tabl_p
as projection on zstudent_att_tab_i
{
@UI.facet: [{
id: 'StudentData',
purpose: #STANDARD,
label: 'Attachment Information',
type: #IDENTIFICATION_REFERENCE,
position: 10
}]
@UI: {
lineItem: [{ position: 10 }],
identification: [{ position: 10 }]
}
key AttachId,
@UI: {
lineItem: [{ position: 20 }],
identification: [{ position: 20 }]
}
Id,
@UI: {
lineItem: [{ position: 30 }],
identification: [{ position: 30 }]
}
Comments,
@UI: {
lineItem: [{ position: 40 }],
identification: [{ position: 40 }]
}
Attachment,
Mimetype,
Filename,
LastChangedat,
/* Associations */
_Student : redirected to parent zstudent_att_tab_p
}
Una vez que las Vistas de proyección estén listas, ahora vamos a crear la Definición de comportamiento. Para agregar diferentes acciones a Object.
Haga clic con el botón derecho en Vista de interfaz de encabezado de estudiante y cree Definición de comportamiento. consulte la imagen de abajo.
En la definición de comportamiento estamos usando la capacidad de borrador. Actualice la definición de comportamiento para el estudiante y los archivos adjuntos según el código a continuación.
managed implementation in class zbp_student_hdr_tab_i unique;
strict ( 1 ); with draft;
define behavior for zstudent_hdr_tab_I alias Student
persistent table zstudent_hdr_tab
draft table zstudent_h_d_tab
lock master
total etag Locallastchangedat
authorization master ( global )
etag master Lastchangedat
{
create;
update;
delete;
association _Attachments { create; with draft; }
field ( numbering : managed, readonly ) Id;
draft action Edit;
draft action Activate;
draft action Discard;
draft action Resume;
draft determine action Prepare;
mapping for zstudent_hdr_tab
{
Id = id;
Firstname = firstname;
Lastname = lastname;
Age = age;
Course = course;
Courseduration = courseduration;
Dob = dob;
Gender = gender;
Lastchangedat = lastchangedat;
Locallastchangedat = locallastchangedat;
Status = status;
}
}
define behavior for zstudent_att_tab_i alias Attachments
persistent table zstudent_att_tab
draft table zstudent_a_d_tab
lock dependent by _Student
authorization dependent by _Student
etag master LastChangedat
{
update;
delete;
field ( readonly ) Id;
association _Student { with draft; }
mapping for zstudent_att_tab{
AttachId = attach_id;
Attachment = attachment;
Comments = comments;
Filename = filename;
Id = id;
Mimetype = mimetype;
}
}
Guardar y activar comportamiento Definición
La clase de implementación de comportamiento está lista. Dado que no estamos realizando ninguna operación personalizada, no se necesitan cambios en este momento.
Cree también una definición de comportamiento para la vista de proyección del encabezado del estudiante. No se necesitan cambios una vez creado, simplemente Activar.
proyección Comportamiento de la vista Se creará una definición.
projection;
strict ( 1 );
use draft;
define behavior for zstudent_att_tab_p //alias <alias_name>
{
use create;
use update;
use delete;
use action Edit;
use action Activate;
use action Discard;
use action Resume;
use action Prepare;
use association _Attachments { create; with draft; }
}
define behavior for zstudent_att_tabl_p //alias <alias_name>
{
use update;
use delete;
use association _Student { with draft; }
}
Guardar y activar comportamiento Definición
Seleccione Vista de proyección de datos adjuntos y cree una nueva definición de servicio
@EndUserText.label: 'Service Defination'
define service ZSTUDENT_ATT_SD {
expose zstudent_att_tabl_p;
expose zstudent_att_tab_p;
}
Guardar y activar comportamiento Definición
Para crear una nueva vinculación de servicio, haga clic con el botón derecho en Definición de servicio y seleccione Nuevas vinculaciones de servicio
Debe seleccionar el Tipo de enlace como OData V4 – UI, ya que queremos tener disponibles las operaciones Crear, EDITAR y Eliminar junto con la Carga de archivos adjuntos.
Agregue a Transporte y haga clic en el botón Finalizar.
Haga clic en Activar enlace de servicio y, una vez activado, debemos publicar el nuevo enlace de servicio creado. Una vez publicado, solo la URL del servicio estará disponible para usarse para crear la aplicación Fiori.
Una vez creados los enlaces de servicio y publicados, debería verse como a continuación
La estructura final de la aplicación se ve a continuación:
La pantalla inicial de la aplicación se verá como se muestra a continuación. con botones de acción para crear y eliminar registros
Haga clic en el botón Crear para agregar un nuevo registro de estudiante, se mostrará la siguiente pantalla. Actualice toda la información requerida del estudiante y haga clic en el botón Crear en la faceta Cargar archivo adjunto para cargar el archivo de currículum.
Dado que el campo Id del archivo adjunto no es un campo generado automáticamente y no es nulo, en este caso, RAP Framework mostrará una ventana emergente que solicita un número único para la identificación del archivo adjunto.
Proporcione comentarios para el archivo adjunto y use el botón Cargar para seleccionar el archivo para cargar, una vez que haya terminado, haga clic en el botón Aplicar que guardará el archivo temporalmente
Una vez hecho esto, haga clic en el botón Guardar y el archivo se cargará y guardará para el registro de estudiante creado
Sube otro archivo. Múltiples archivos se cargan con éxito
Gracias-
Abhishek
Calle Eloy Gonzalo, 27
Madrid, Madrid.
Código Postal 28010
Paseo de la Reforma 26
Colonia Juárez, Cuauhtémoc
Ciudad de México 06600
Real Cariari
Autopista General Cañas,
San José, SJ 40104
Av. Jorge Basadre 349
San Isidro
Lima, LIM 15073