Introductie
Wanneer een juridische afdeling meerdere contract‑PDF’s ontvangt, voegt elke beoordelaar vaak zijn eigen wachtwoord toe om vertrouwelijke clausules te beschermen. Het consolideren van deze bestanden tot één map wordt een nachtmerrie omdat de wachtwoorden verschillen en de bestanden niet direct kunnen worden samengevoegd. Handmatig ontcijferen kost veel tijd en is foutgevoelig, vooral wanneer er tientallen PDF’s zijn.
Password‑merge is een GroupDocs.Merger‑workflow voor Java die heterogene PDF’s ontgrendelt en het samengevoegde resultaat opnieuw beveiligt met één enkele inloggegevens. Deze tutorial loopt door het detecteren van beveiligde PDF’s, het ontgrendelen, het samenvoegen van de inhoud en optioneel het roteren van het uniforme wachtwoord.
Je leert hoe je de Merger‑API configureert, byte‑streams verwerkt en een beveiligde gecombineerde PDF genereert in minder dan 30 regels Java‑code.
Wanneer moet ik wachtwoord‑beveiligde PDF’s samenvoegen?
Het samenvoegen van wachtwoord‑beveiligde PDF’s heeft zin wanneer je één doorzoekbaar archief nodig hebt dat voldoet aan beveiligingsbeleid, terwijl je de overhead van het omgaan met meerdere wachtwoorden elimineert. Typische scenario’s zijn kwartaal‑financiële rapportbundels, contractmappen voor audits en juridische dossiers waarbij elke bijdrager een ander wachtwoord heeft toegepast. Door elk bestand programmatisch te ontgrendelen en een uniform wachtwoord toe te passen, houd je het archief veilig en vereenvoudig je de downstream beoordelingsprocessen. De volledige bewerking kan geautomatiseerd worden in een CI‑pipeline, waardoor uren handmatig werk worden bespaard.
Voorvereisten
- Java 11 of hoger
- GroupDocs.Merger for Java 24.6+ (temporary license)
- Een set PDF‑bestanden, elk eventueel gekoppeld aan een wachtwoord
Installeer de bibliotheek via Maven:
mvn dependency:copy -Dartifact=com.groupdocs:groupdocs-merger:24.6
Stap 1 – Detecteer of een PDF wachtwoord‑beveiligd is
Voordat je probeert een bestand te ontgrendelen, controleer je of het daadwerkelijk een wachtwoord bevat. Dit voorkomt onnodige verwerking en laat je loggen welke bestanden inloggegevens nodig hebben.
// Returns true if the PDF at `path` has an owner or user password
public boolean isDocumentProtected(String path, String password) {
Merger merger;
if (password == null || password.isEmpty()) {
merger = new Merger(path);
} else {
merger = new Merger(path, new LoadOptions(password));
}
try {
return merger.isPasswordSet();
} finally {
merger.dispose();
}
}
Belangrijke punten:
LoadOptionsdraagt een bekend wachtwoord; als er geen wordt opgegeven, wordt het bestand normaal geopend.isPasswordSet()geeft true terug voor zowel eigenaar‑ als gebruikerswachtwoorden.- Ruim de
Merger‑instance altijd op om native resources vrij te geven.
Stap 2 – Ontgrendel elke PDF en verzamel ruwe bytes
Itereer over een map waarbij de sleutel het bestandspad is en de waarde het wachtwoord (null indien geen). De methode retourneert een lijst van byte‑arrays die de ontgrendelde PDF’s vertegenwoordigen.
public List<byte[]> unlockAll(Map<String, String> sources) throws IOException {
List<byte[]> unlocked = new ArrayList<>();
for (Map.Entry<String, String> e : sources.entrySet()) {
String path = e.getKey();
String password = e.getValue();
System.out.println("Unlocking (credentials=" +
(password != null ? "yes" : "no") + "): " + path);
if (password == null || password.isEmpty()) {
unlocked.add(Files.readAllBytes(Paths.get(path)));
} else {
LoadOptions opts = new LoadOptions(password);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
Merger m = new Merger(path, opts);
try {
m.removePassword();
m.save(buf);
} finally {
m.dispose();
}
unlocked.add(buf.toByteArray());
}
}
return unlocked;
}
Belangrijke punten:
removePassword()verwijdert de bestaande bescherming.- De gedecrypteerde inhoud wordt geschreven naar een
ByteArrayOutputStreamvoor in‑memory verwerking. - Bestanden zonder wachtwoord worden direct gelezen om de stroom eenvoudig te houden.
Stap 3 – Voeg de ontgrendelde PDF’s samen en pas een uniform wachtwoord toe
Maak een Merger aan vanuit de eerste PDF‑stream en voeg vervolgens de overige streams toe. Bescherm ten slotte het gecombineerde document met AddPasswordOptions.
public void mergeAndProtect(List<byte[]> unlockedPdfs,
String unifiedPassword,
String outputPath) {
InputStream first = new ByteArrayInputStream(unlockedPdfs.get(0));
Merger merger = new Merger(first);
try {
for (int i = 1; i < unlockedPdfs.size(); i++) {
merger.join(new ByteArrayInputStream(unlockedPdfs.get(i)));
}
merger.addPassword(new AddPasswordOptions(unifiedPassword));
merger.save(outputPath);
} finally {
merger.dispose();
}
System.out.println("Merged output: " + new File(outputPath).getAbsolutePath());
System.out.println("Unified password: " + unifiedPassword);
}
Belangrijke punten:
addPasswordversleutelt de uiteindelijke PDF met de opgegeven inloggegevens.- Alle bewerkingen gebeuren in het geheugen; alleen het eindbestand wordt naar schijf geschreven.
- Ruim de
Mergerop om native handles vrij te geven.
Stap 4 – Roteer het wachtwoord op een al beveiligde PDF (optioneel)
Als jouw organisatie periodieke wachtwoordrotatie afdwingt, kun je de inloggegevens bijwerken zonder de bronbestanden opnieuw te combineren.
public void rotateUnifiedPassword(String path,
String oldPassword,
String newPassword,
String outputPath) {
Merger merger = new Merger(path, new LoadOptions(oldPassword));
try {
merger.updatePassword(new UpdatePasswordOptions(newPassword));
merger.save(outputPath);
} finally {
merger.dispose();
}
System.out.println("Rotated output: " + new File(outputPath).getAbsolutePath());
System.out.println("New password: " + newPassword);
}
Belangrijke punten:
- Laad de beveiligde PDF met het huidige wachtwoord.
updatePasswordvervangt dit door de nieuwe inloggegevens.- Deze bewerking is snel omdat de PDF‑inhoud niet opnieuw wordt verwerkt.
Praktijkvoorbeeld
Ik kwam dit tegen bij het consolideren van vijf investeerderscontracten die elk een ander beoordelaar‑wachtwoord hadden. Met de bovenstaande stappen ontgrendelde ik alle bestanden, voegde ze samen tot één map en paste een enkel wachtwoord toe dat overeenkwam met ons bedrijfsbeleid. Het volledige proces duurde minder dan twee minuten op een standaard laptop.
Best Practices
- Valideer wachtwoorden vroeg: Gebruik
isDocumentProtectedom bestanden te markeren die handmatige aandacht nodig hebben. - Beperk geheugenverbruik: Voor grote PDF’s kun je ze naar schijf streamen in plaats van alle byte‑arrays in het geheugen te houden.
- Ruim objecten direct op: De Merger‑klasse bevat native resources; roep altijd
dispose()aan in eenfinally‑blok. - Gebruik een tijdelijke licentie alleen voor ontwikkeling; verkrijg een productie‑licentie vóór release.
Conclusie
GroupDocs.Merger for Java biedt een nette API voor het ontgrendelen, samenvoegen en opnieuw beveiligen van PDF‑collecties. Door de vier stappen te volgen — bescherming detecteren, ontgrendelen, samenvoegen met een uniform wachtwoord en eventueel dat wachtwoord roteren — kun je veilige PDF‑mappen automatiseren zonder handmatige tussenkomst.
Volgende stappen:
- Verken extra opties zoals het instellen van PDF‑metadata na het samenvoegen (documentation).
- Leer hoe je PDF’s kunt samenvoegen terwijl je bladwijzers behoudt (API reference).
- Bekijk het volledige voorbeeldproject op GitHub voor een kant‑en‑klaar implementatie.