SUPPORT-8664: fix file downloading

This commit is contained in:
gulnaz 2024-11-02 13:52:09 +03:00
parent a2e611ad10
commit fe27cfa51d
5 changed files with 61 additions and 70 deletions

View file

@ -1,11 +1,16 @@
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Root application context
@ -30,10 +35,15 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableWebMvc
@EnableScheduling
public class AppConfig {
public class AppConfig implements WebMvcConfigurer {
@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new ResourceHttpMessageConverter());
}
}

View file

@ -1,26 +1,30 @@
package ru.micord.ervu.service.rpc;
package ru.micord.ervu.controller;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import com.google.protobuf.InvalidProtocolBufferException;
import org.apache.kafka.common.utils.Bytes;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import ru.micord.ervu.dto.FileData;
import ru.micord.ervu.dto.ExtractRequestDto;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import rtl.pgs.ervu.proto.ExtractRegistry;
import rtl.pgs.ervu.proto.ResponseData;
import ru.micord.ervu.dto.ExtractRequestDto;
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
import ru.cg.webbpm.modules.standard_annotations.validation.NotNull;
import ru.cg.webbpm.modules.webkit.annotations.RpcCall;
import ru.cg.webbpm.modules.webkit.annotations.RpcService;
import ru.cg.webbpm.modules.webkit.beans.Behavior;
/**
* @author gulnaz
*/
@RpcService
public class ExtractRpcService extends Behavior {
@RestController
public class ExtractController {
private final JwtTokenService jwtTokenService;
private final ReplyingKafkaService<Object, Bytes> replyingKafkaService;
@ -30,20 +34,15 @@ public class ExtractRpcService extends Behavior {
@Value("${ervu.kafka.registry.extract.reply.topic}")
private String registryExtractReplyTopic;
@NotNull()
public String formatExtractRegistry;
public ExtractRpcService(
JwtTokenService jwtTokenService,
@Qualifier("recruit") ReplyingKafkaService<Object, Bytes> replyingKafkaService) {
public ExtractController(JwtTokenService jwtTokenService,
ReplyingKafkaService<Object, Bytes> replyingKafkaService) {
this.jwtTokenService = jwtTokenService;
this.replyingKafkaService = replyingKafkaService;
}
@RpcCall
public FileData getExtract() {
ExtractRequestDto request = new ExtractRequestDto(jwtTokenService.getErvuId(),
formatExtractRegistry);
@GetMapping(value = "/get-extract/{formatRegistry}")
public ResponseEntity<Resource> getExtract(@PathVariable String formatRegistry) {
ExtractRequestDto request = new ExtractRequestDto(jwtTokenService.getErvuId(), formatRegistry);
byte[] reply = replyingKafkaService.sendMessageAndGetReply(registryExtractRequestTopic,
registryExtractReplyTopic, request).get();
@ -51,8 +50,12 @@ public class ExtractRpcService extends Behavior {
ResponseData responseData = ResponseData.parseFrom(reply);
ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
.getExtractRegistry();
return new FileData(extractRegistry.getFileName(), extractRegistry.getFileType(),
extractRegistry.getFile().toByteArray());
String encodedFilename = URLEncoder.encode(extractRegistry.getFileName(), StandardCharsets.UTF_8);
InputStreamResource resource = new InputStreamResource(extractRegistry.getFile().newInput());
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFilename)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
}
catch (InvalidProtocolBufferException e) {
throw new RuntimeException("Failed to parse data", e);

View file

@ -1,7 +0,0 @@
package ru.micord.ervu.dto;
/**
* @author gulnaz
*/
public record FileData(String fileName, String fileType, byte[] file) {
}

View file

@ -3,9 +3,10 @@ import {
AnalyticalScope,
Behavior,
Event,
NotNull,
Visible
} from "@webbpm/base-package";
import {ExtractRpcService} from "../../../generated/ru/micord/ervu/service/rpc/ExtractRpcService";
import {HttpClient} from "@angular/common/http";
@AnalyticalScope(AbstractButton)
export class ExtractLoadService extends Behavior {
@ -14,34 +15,34 @@ export class ExtractLoadService extends Behavior {
public successEvent: Event<boolean> = new Event<boolean>();
@Visible("false")
public errorEvent: Event<boolean> = new Event<boolean>();
@NotNull()
public formatRegistry: string;
private button: AbstractButton;
private rpc: ExtractRpcService;
private httpClient: HttpClient;
private onClickFunction: Function;
initialize() {
super.initialize();
this.button = this.getScript(AbstractButton);
this.rpc = this.getScript(ExtractRpcService);
this.httpClient = this.injector.get(HttpClient);
this.onClickFunction = () => {
this.rpc.getExtract()
.then(fileData => {
const newBlob = new Blob([fileData['file']],
{ type: fileData['fileType'] });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(newBlob);
}
else {
const data = window.URL.createObjectURL(newBlob);
const link = document.createElement("a");
link.href = data;
link.download = fileData['fileName'];
link.click();
URL.revokeObjectURL(data);
link.remove();
this.successEvent.trigger();
}
this.httpClient.get('get-extract/' + this.formatRegistry, {
responseType: 'blob',
observe: 'response'
}).toPromise()
.then((response) => {
const data = window.URL.createObjectURL(response.body);
const link = document.createElement("a");
link.href = data;
const contentDisposition = response.headers.get('Content-Disposition');
const fileNameMatch = contentDisposition.match(/filename\*=?UTF-8''(.+)/i);
link.download = decodeURIComponent(fileNameMatch[1].replace(/\+/g, '%20'));
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(data);
link.remove();
this.successEvent.trigger();
})
.catch(() => {
this.errorEvent.trigger();

View file

@ -1797,17 +1797,9 @@
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
</scripts>
<scripts id="3380990f-3be0-442d-af4e-d31c8da7d39e">
<classRef type="JAVA">
<className>ExtractRpcService</className>
<packageName>ru.micord.ervu.service.rpc</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
<properties>
<entry>
<key>formatExtractRegistry</key>
<key>formatRegistry</key>
<value>
<simple>"1"</simple>
</value>
@ -4942,17 +4934,9 @@
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
</scripts>
<scripts id="b821375f-f5a9-4a85-8b0a-2fff5e2da2a5">
<classRef type="JAVA">
<className>ExtractRpcService</className>
<packageName>ru.micord.ervu.service.rpc</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
<properties>
<entry>
<key>formatExtractRegistry</key>
<key>formatRegistry</key>
<value>
<simple>"2"</simple>
</value>