Build a Java SpringBoot Electronic Signature & Seal System: Full Source Code & Deployment Guide

This article walks through the design and implementation of a Java SpringBoot‑based electronic signature and seal system, covering the underlying concepts of digital signatures, the complete project structure, key controller and service code, utility classes, deployment steps, and a step‑by‑step functional demo with screenshots.

Java High-Performance Architecture
Java High-Performance Architecture
Java High-Performance Architecture
Build a Java SpringBoot Electronic Signature & Seal System: Full Source Code & Deployment Guide

Introduction

The article explains the need for a document signing and stamping feature, describing digital signatures as cryptographic methods that ensure authenticity, integrity, and non‑repudiation. It introduces an open‑source demo that simulates the flow of Office documents in an OA system, supporting both PC and mobile platforms via PageOffice and MobOffice.

Source Code and Deployment

Project Structure and Framework

The system is built with SpringBoot and Thymeleaf, and Maven manages the dependencies.

Controller Layer

@Controller<br/>@RequestMapping("/mobile")<br/>public class MobileOfficeController {<br/>    @Value("${docpath}")<br/>    private String docPath;<br/>    @Value("${moblicpath}")<br/>    private String moblicpath;<br/>    @Autowired<br/>    DocService m_docService;<br/>    /** Add MobOffice server‑side authorization servlet (required) */<br/>    @RequestMapping("/opendoc")<br/>    public void opendoc(HttpServletRequest request, HttpServletResponse response, HttpSession session, String type, String userName) throws Exception {<br/>        String fileName = "";<br/>        userName = URLDecoder.decode(userName, "utf-8");<br/>        Doc doc = m_docService.getDocById(1);<br/>        if (type.equals("word")) {<br/>            fileName = doc.getDocName();<br/>        } else {<br/>            fileName = doc.getPdfName();<br/>        }<br/>        OpenModeType openModeType = OpenModeType.docNormalEdit;<br/>        if (fileName.endsWith(".doc")) {<br/>            openModeType = OpenModeType.docNormalEdit;<br/>        } else if (fileName.endsWith(".pdf")) {<br/>            String mode = request.getParameter("mode");<br/>            if (mode.equals("normal")) {<br/>                openModeType = OpenModeType.pdfNormal;<br/>            } else {<br/>                openModeType = OpenModeType.pdfReadOnly;<br/>            }<br/>        }<br/>        MobOfficeCtrl mobCtrl = new MobOfficeCtrl(request, response);<br/>        mobCtrl.setSysPath(moblicpath);<br/>        mobCtrl.setServerPage("/mobserver.zz");<br/>        mobCtrl.setSaveFilePage("/mobile/savedoc?testid=" + Math.random());<br/>        mobCtrl.webOpen("file://" + docPath + fileName, openModeType, userName);<br/>    }<br/>    @RequestMapping("/savedoc")<br/>    public void savedoc(HttpServletRequest request, HttpServletResponse response) {<br/>        FileSaver fs = new FileSaver(request, response);<br/>        fs.saveToFile(docPath + fs.getFileName());<br/>        fs.close();<br/>    }<br/>}<br/>

Service Layer

@Service<br/>public class DocServiceImpl implements DocService {<br/>    @Autowired<br/>    DocMapper docMapper;<br/>    @Override<br/>    public Doc getDocById(int id) throws Exception {<br/>        Doc doc = docMapper.getDocById(id);<br/>        if (doc == null) {<br/>            doc = new Doc();<br/>        }<br/>        return doc;<br/>    }<br/>    @Override<br/>    public Integer addDoc(Doc doc) throws Exception {<br/>        int id = docMapper.addDoc(doc);<br/>        return id;<br/>    }<br/>    @Override<br/>    public Integer updateStatusForDocById(Doc doc) throws Exception {<br/>        int id = docMapper.updateStatusForDocById(doc);<br/>        return id;<br/>    }<br/>    @Override<br/>    public Integer updateDocNameForDocById(Doc doc) throws Exception {<br/>        int id = docMapper.updateDocNameForDocById(doc);<br/>        return id;<br/>    }<br/>    @Override<br/>    public Integer updatePdfNameForDocById(Doc doc) throws Exception {<br/>        int id = docMapper.updatePdfNameForDocById(doc);<br/>        return id;<br/>    }<br/>}<br/>

Copy File Utility

public class CopyFileUtil {<br/>    // Copy file<br/>    public static boolean copyFile(String oldPath, String newPath) throws Exception {<br/>        boolean copyStatus = false;<br/>        int bytesum = 0;<br/>        int byteread = 0;<br/>        File oldfile = new File(oldPath);<br/>        if (oldfile.exists()) { // file exists<br/>            InputStream inStream = new FileInputStream(oldPath); // read original file<br/>            FileOutputStream fs = new FileOutputStream(newPath);<br/>            byte[] buffer = new byte[1444];<br/>            int length;<br/>            while ((byteread = inStream.read(buffer)) != -1) {<br/>                bytesum += byteread; // total bytes<br/>                fs.write(buffer, 0, byteread);<br/>            }<br/>            fs.close();<br/>            inStream.close();<br/>            copyStatus = true;<br/>        } else {<br/>            copyStatus = false;<br/>        }<br/>        return copyStatus;<br/>    }<br/>}<br/>

QR Code Utility

public class QRCodeUtil {<br/>    private String codeText; // QR content<br/>    private BarcodeFormat barcodeFormat;<br/>    private int width;<br/>    private int height;<br/>    private String imageformat;<br/>    private int backColorRGB;<br/>    private int codeColorRGB;<br/>    private ErrorCorrectionLevel errorCorrectionLevel;<br/>    private String encodeType;<br/><br/>    public QRCodeUtil() {<br/>        codeText = "www.zhuozhengsoft.com";<br/>        barcodeFormat = BarcodeFormat.PDF_417;<br/>        width = 400;<br/>        height = 400;<br/>        imageformat = "png";<br/>        backColorRGB = 0xFFFFFFFF;<br/>        codeColorRGB = 0xFF000000;<br/>        errorCorrectionLevel = ErrorCorrectionLevel.H;<br/>        encodeType = "UTF-8";<br/>    }<br/>    public QRCodeUtil(String text) {<br/>        codeText = text;<br/>        barcodeFormat = BarcodeFormat.PDF_417;<br/>        width = 400;<br/>        height = 400;<br/>        imageformat = "png";<br/>        backColorRGB = 0xFFFFFFFF;<br/>        codeColorRGB = 0xFF000000;<br/>        errorCorrectionLevel = ErrorCorrectionLevel.H;<br/>        encodeType = "UTF-8";<br/>    }<br/>    // Getters and setters omitted for brevity<br/>    private BufferedImage toBufferedImage(BitMatrix bitMatrix) {<br/>        int w = bitMatrix.getWidth();<br/>        int h = bitMatrix.getHeight();<br/>        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);<br/>        for (int x = 0; x < w; x++) {<br/>            for (int y = 0; y < h; y++) {<br/>                image.setRGB(x, y, bitMatrix.get(x, y) ? codeColorRGB : backColorRGB);<br/>            }<br/>        }<br/>        return image;<br/>    }<br/>    private byte[] writeToBytes(BitMatrix bitMatrix) throws IOException {<br/>        BufferedImage bufferedimage = toBufferedImage(bitMatrix);<br/>        File file = java.io.File.createTempFile("~pic", "." + imageformat);<br/>        ImageIO.write(bufferedimage, imageformat, file);<br/>        FileInputStream fis = new FileInputStream(file);<br/>        int fileSize = fis.available();<br/>        byte[] imageBytes = new byte[fileSize];<br/>        fis.read(imageBytes);<br/>        fis.close();<br/>        if (file.exists()) { file.delete(); }<br/>        return imageBytes;<br/>    }<br/>    public byte[] getQRCodeBytes() throws IOException {<br/>        try {<br/>            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();<br/>            Map hints = new HashMap();<br/>            if (errorCorrectionLevel != null) { hints.put(EncodeHintType.ERROR_CORRECTION, errorCorrectionLevel); }<br/>            if (encodeType != null && encodeType.trim().length() > 0) { hints.put(EncodeHintType.CHARACTER_SET, encodeType); }<br/>            BitMatrix bitMatrix = multiFormatWriter.encode(codeText, BarcodeFormat.QR_CODE, width, height, hints);<br/>            return writeToBytes(bitMatrix);<br/>        } catch (Exception e) { e.printStackTrace(); return null; }<br/>    }<br/>}<br/>

Project Download and Deployment

Contact the author on WeChat (ID: fenggejava) and reply with “盖章系统” to receive the source code.

After downloading, import the slndemo project into IDEA and run it.

Copy the slndemodata.zip package under slndemo to the root of drive D: and unzip it.

Click to start the project.

Feature Demonstration

Login to Home Page

URL: http://localhost:8888/pc/login

Account: 张三, Password: 123456

System Home Page Overview

The demo simulates the main flow of a Word document in an OA system, showing drafting, approval, sealing, and final publishing. PageOffice provides online editing, saving, dynamic filling, merging, stamping, and many other features, but does not handle workflow control.

Draft Document

Click “Draft Document” and submit.

When editing, PageOffice prompts installation; after installing, restart the browser to edit.

Register the PageOffice enterprise version (Trial) with serial number 35N8V-2YUC-LY77-W14XL.

After registration, you can edit and publish files or announcements.

Click Save after editing.

Click Approve.

Approval Process

Login as 李总 for approval, then log out and log in again.

Click Review and proceed to the next step.

Login as 赵六 to review the draft.

Sealing and Signing

Login as 王五 (Account: 王五, Password: 123456) to apply the personal seal and sign.

After successful signing, the document is sealed and ready for publishing.

Final signed and sealed document is displayed.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSpringBootWebDevelopmentDocumentWorkflowPageOfficeElectronicSignature
Java High-Performance Architecture
Written by

Java High-Performance Architecture

Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.