【问题标题】:Download PDF in angular generated from Spring Boot Server下载从 Spring Boot Server 生成的角度 PDF
【发布时间】:2021-07-03 13:25:27
【问题描述】:

我正在努力从 Spring boot 生成的用户界面 (Angular) 下载 pdf 文件。 我可以使用相同的 API 从浏览器下载 pdf 文件。

我们将不胜感激快速帮助。

在邮递员中,它会给出这样的响应-

当从 UI 尝试然后得到以下错误-

SyntaxError: 在 XMLHttpRequest.onLoad 的 JSON.parse () 位置 0 处的 JSON 中出现意外的标记 % 消息:“位置 0 处 JSON 中的意外令牌 %” 堆栈:“语法错误:在 XMLHttpRequest.onLoad (http://localhost:4200/vendor.js:19662:51) 处 JSON.parse ()↵ 位置 0↵ 处的 JSON 中的意外令牌%↵

API 代码

控制器代码-

@RequestMapping(value = "/downloadPDF/", method = RequestMethod.GET, produces = "application/pdf")
    public ResponseEntity<Resource> downloadServicePack(@RequestHeader("Authorization") String token,
            HttpServletRequest request) throws WorkflowException, Exception {

        String fileName = "TWEVL_ServiceDesignPack.pdf";

        // String fileName ="ServiceDesignPdf.pdf";
        Resource resource = fileStorageService.loadFileAsResource(fileName);

        // Try to determine file's content type
        String contentType = null;
        try {
            contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
        } catch (IOException ex) {
            // logger.info("Could not determine file type.");
        }

        // Fallback to the default content type if type could not be determined
        if (contentType == null) {
            contentType = "application/octet-stream";
        }

        return ResponseEntity.ok().contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                .body(resource);

    }

服务代码-

@Service
public class FileStorageService {

    private final Path fileStorageLocation;

    @Autowired
    public FileStorageService(FileStorageProperties fileStorageProperties) throws Exception {
        this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
                .toAbsolutePath().normalize();

        try {
            Files.createDirectories(this.fileStorageLocation);
        } catch (Exception ex) {
            throw new Exception("Could not create the directory where the uploaded files will be stored.", ex);
        }
    }

    
    public Resource loadFileAsResource(String fileName) throws Exception {
        try {
            Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());
            if(resource.exists()) {
                return resource;
            } else {
                throw new Exception("File not found " + fileName);
            }
        } catch (Exception ex) {
            throw new Exception("File not found " + fileName, ex);
        }
    }
}

Angular 代码-

JWT 拦截器传递令牌和其他标头-

 @Injectable()
    export class JwtInterceptor implements HttpInterceptor {
      constructor(private authenticationService: AuthenticationService) {}
    
      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        // add authorization header with jwt token if available
        const token = this.authenticationService.currentUserValue;
            request = request.clone({
              setHeaders: {
                Authorization: `Bearer ${token.token}`,
                Accept: `application/pdf`,
                responseType:'blob',
                'Content-Type':`application/pdf`
              }
            });
        return next.handle(request);
      }
    }

API 调用

  downloadServicePackPDF() {
    this.tcmtSrv
      .downloadServicePack()
      .subscribe(
        (blob: Blob)  => {
          console.log('report is downloaded');
       
        },
        (error) => {
          console.log(error);
         }
      );
  }

服务代码-

   downloadServicePack() {
   //header is being passed from interceptor
    return this.apiSrv.get(DOWNLOAD_SERVICE_PACK,'');
  }

请求标头-

【问题讨论】:

  • @R.Richards 我已经在标头中传递了 Accept 和 responseType。它给出了同样的错误。刚刚使用请求标头参数更新了帖子
  • 我发现使用文件保护程序包对此很有帮助。查看此帖子stackoverflow.com/questions/53246489/…
  • responseType 的做法不正确。那不是标题。仔细查看我发布的链接。
  • 谢谢@R.Richards,你是对的。我没有按照您建议的方式传递 responseType。我试图通过它,但它不起作用。后来我检查了拦截器是否覆盖了在服务级别给出的这些标头和其他参数。所以我禁用了拦截器并且它工作但我无法禁用/删除拦截器。关于如何停止拦截器在特定 API 上运行的任何想法?如何停止覆盖拦截器在服务层传递的标头?

标签: javascript angular spring-boot pdf


【解决方案1】:

我没有在拦截器中传递 responseType。我试图将它传递给服务 ts,但拦截器覆盖了这些标头和在服务级别给出的其他参数。

在拦截器中传递了如下所示的标题并且它起作用了 -

const newRequest = request.clone({ setHeaders: { Authorization: Bearer ${token.token}, "Content-Type": "text/plain", Accept: "text/plain" },responseType: "text", });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    • 2020-06-10
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多