Java Spring Framework Example

Caution

For server security, please refer to the link below when handling this work.

[Software Security Weakness Diagnosis Guide]

Per-environment Integration Guides

  • Java Spring Framework example
  • Java Servlet example
  • ASP.NET (C#) example
  • ASP (Classic) example
  • PHP example
  • PHP4 example
  • Django example
  • Ruby on Rails example
  • WordPress plugin example

1. Image / Video / File Upload

Caution

The file-upload portion of the sample code below is intentionally minimal and lacks proper security handling.

For the file-upload portion, use what is already in place inside your project, and refer to the code below for the integration portion only.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

@Controller
public class UploadController {
    static String IMAGE_UPLOAD_DIR_REL_PATH = "uploads";

    @RequestMapping(value = "/uploadFile.do", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> uploadFile(HttpServletRequest request,
                                          @RequestParam("file") MultipartFile file) throws IOException {
        String ROOT_ABS_PATH       = request.getSession().getServletContext().getRealPath("");
        String UPLOAD_DIR_ABS_PATH = ROOT_ABS_PATH + File.separator + IMAGE_UPLOAD_DIR_REL_PATH;
        makeDirectory(UPLOAD_DIR_ABS_PATH);

        String fileName    = file.getOriginalFilename();
        String contentType = file.getContentType();
        String ext = "";
        if (contentType != null) {
            ext = "." + contentType.substring(contentType.lastIndexOf('/') + 1);
        } else if (fileName.lastIndexOf('.') > 0) {
            ext = fileName.substring(fileName.lastIndexOf('.'));
        }
        if (ext.contains(".jpeg")) ext = ".jpg";   // normalize jpeg → jpg

        String saveFileName    = UUID.randomUUID().toString() + ext;
        String saveFileAbsPath = UPLOAD_DIR_ABS_PATH + File.separator + saveFileName;
        writeFile(saveFileAbsPath, file.getBytes());

        Map<String, Object> map = new HashMap<>();
        map.put("uploadPath", "uploads/" + saveFileName);   // browser-accessible path
        return map;
    }

    private static void writeFile(String path, byte[] bytes) throws IOException {
        try (OutputStream os = new FileOutputStream(path)) { os.write(bytes); }
    }
    private static void makeDirectory(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists()) dir.mkdir();
    }
}

2. HWP / Word / Excel Document Import

Caution

The file-upload portion of the sample code below is intentionally minimal and lacks proper security handling.

For the file-upload portion, use what is already in place inside your project, and refer to the code below for the integration portion only.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;
import java.util.zip.InflaterInputStream;

@Controller
public class ImportController {
    static String DOC_UPLOAD_DIR_REL_PATH = "uploads" + File.separator + "docs";
    static String OUTPUT_DIR_REL_PATH     = "uploads" + File.separator + "output";

    @RequestMapping(value = "/importDoc.do", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> importDoc(HttpServletRequest request,
                                         @RequestParam("file") MultipartFile importFile) throws IOException {
        String ROOT_ABS_PATH       = request.getSession().getServletContext().getRealPath("");
        String UPLOAD_DIR_ABS_PATH = ROOT_ABS_PATH + File.separator + DOC_UPLOAD_DIR_REL_PATH;
        makeDirectory(UPLOAD_DIR_ABS_PATH);

        String fileName         = importFile.getOriginalFilename();
        String inputFileAbsPath = UPLOAD_DIR_ABS_PATH + File.separator + fileName;
        writeFile(inputFileAbsPath, importFile.getBytes());

        // Per-file conversion output directory
        Calendar cal = Calendar.getInstance();
        String yearMonth = String.format("%04d%02d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1);
        String uuid             = UUID.randomUUID().toString();
        String worksDirAbsPath  = ROOT_ABS_PATH + File.separator + OUTPUT_DIR_REL_PATH
                                + File.separator + yearMonth + File.separator + uuid;
        makeDirectory(worksDirAbsPath);

        // Convert
        executeConverter(inputFileAbsPath, worksDirAbsPath);
        deleteFile(inputFileAbsPath);

        // Read and serialize the .pb output
        // From v2.3.0 the filename is "document.pb" (was "document.word.pb").
        String pbAbsPath = worksDirAbsPath + File.separator + "document.pb";
        Integer[] serializedData = serializePbData(pbAbsPath);
        deleteFile(pbAbsPath);

        Map<String, Object> map = new HashMap<>();
        map.put("serializedData", serializedData);
        map.put("importPath", "uploads/output/" + yearMonth + "/" + uuid);   // browser-accessible
        return map;
    }

    /** Invoke the sedocConverter process. */
    public static int executeConverter(String inputFilePath, String outputFilePath) {
        String SEDOC_CONVERTER_DIR_ABS_PATH = "absolute/path/to/converter/dir";
        String FONT_DIR_ABS_PATH            = SEDOC_CONVERTER_DIR_ABS_PATH + File.separator + "fonts";
        String TEMP_DIR_ABS_PATH            = SEDOC_CONVERTER_DIR_ABS_PATH + File.separator + "temp";
        String SEDOC_CONVERTER_ABS_PATH     = SEDOC_CONVERTER_DIR_ABS_PATH + File.separator + "sedocConverter_exe";
        // Windows: "sedocConverter.exe"

        makeDirectory(TEMP_DIR_ABS_PATH);
        makeDirectory(FONT_DIR_ABS_PATH);

        String[] cmd = { SEDOC_CONVERTER_ABS_PATH, "-f", FONT_DIR_ABS_PATH,
                         inputFilePath, outputFilePath, TEMP_DIR_ABS_PATH };
        try {
            Timer t = new Timer();
            ProcessBuilder builder = new ProcessBuilder(cmd);
            builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
            builder.redirectError(ProcessBuilder.Redirect.INHERIT);
            Process proc = builder.start();

            TimerTask killer = new TimeoutProcessKiller(proc);
            t.schedule(killer, 20000);   // 20 s timeout
            int exitValue = proc.waitFor();
            killer.cancel();
            return exitValue;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    /** Inflate the .pb file and serialize to int[]. */
    public static Integer[] serializePbData(String pbFilePath) throws IOException {
        List<Integer> serialized = new ArrayList<>();
        try (FileInputStream fis = new FileInputStream(pbFilePath)) {
            fis.skip(16);
            try (InflaterInputStream ifis = new InflaterInputStream(fis)) {
                byte[] buffer = new byte[1024];
                int len;
                while ((len = ifis.read(buffer)) != -1) {
                    for (int i = 0; i < len; i++) serialized.add(buffer[i] & 0xFF);
                }
            }
        }
        return serialized.toArray(new Integer[0]);
    }

    private static void writeFile(String path, byte[] bytes) throws IOException {
        try (OutputStream os = new FileOutputStream(path)) { os.write(bytes); }
    }
    private static void deleteFile(String path) {
        File f = new File(path);
        if (f.exists()) f.delete();
    }
    private static void makeDirectory(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists()) dir.mkdir();
    }

    private static class TimeoutProcessKiller extends TimerTask {
        private final Process p;
        public TimeoutProcessKiller(Process p) { this.p = p; }
        @Override public void run() { p.destroy(); }
    }
}

3. WMF to PNG Conversion

Release 3.0.2409 and above, Release 2.18.2409 and above.

When pasting content from HWP or MS Word, any WMF files included are converted to PNG.

Caution

The file-upload portion of the sample code below is intentionally minimal and lacks proper security handling.

For the file-upload portion, use what is already in place inside your project, and refer to the code below for the integration portion only.

import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

@Controller
public class WmfToPngController {
    static String IMAGE_UPLOAD_DIR_REL_PATH = "uploads" + File.separator + "image";
    static String OUTPUT_DIR_REL_PATH       = "uploads" + File.separator + "output";

    @PostMapping(value = "/wmfToPng", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public ResponseEntity<Map<String, String>> convertWmfToPng(HttpServletRequest request,
                                                              @RequestParam("file") MultipartFile wmfImageFile) throws IOException {
        String ROOT_ABS_PATH       = request.getSession().getServletContext().getRealPath("");
        String UPLOAD_DIR_ABS_PATH = ROOT_ABS_PATH + File.separator + IMAGE_UPLOAD_DIR_REL_PATH;
        makeDirectory(UPLOAD_DIR_ABS_PATH);

        String fileName         = wmfImageFile.getOriginalFilename();
        String inputFileAbsPath = UPLOAD_DIR_ABS_PATH + File.separator + fileName;
        writeFile(inputFileAbsPath, wmfImageFile.getBytes());

        Calendar cal = Calendar.getInstance();
        String yearMonth = String.format("%04d%02d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1);
        String uuid           = UUID.randomUUID().toString();
        String worksDirAbsPath = ROOT_ABS_PATH + OUTPUT_DIR_REL_PATH
                              + File.separator + yearMonth + File.separator + uuid;
        makeDirectory(worksDirAbsPath);

        executeConverter(inputFileAbsPath, worksDirAbsPath + File.separator + "output.png");
        deleteFile(inputFileAbsPath);

        String downloadUrl = request.getScheme() + "://" + request.getServerName() + ":"
                          + request.getServerPort() + "/download?fileName=" + uuid + "/output.png";

        Map<String, String> response = new HashMap<>();
        response.put("uploadPath", downloadUrl);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return ResponseEntity.status(HttpStatus.OK).headers(headers).body(response);
    }

    @GetMapping("/download")
    public void downloadFile(@RequestParam("fileName") String fileName,
                             HttpServletRequest request, HttpServletResponse response) throws IOException {
        String ROOT_ABS_PATH    = request.getSession().getServletContext().getRealPath("");
        Calendar cal = Calendar.getInstance();
        String yearMonth = String.format("%04d%02d", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1);
        String downloadDirPath  = ROOT_ABS_PATH + OUTPUT_DIR_REL_PATH + File.separator + yearMonth + File.separator;

        File file = new File(downloadDirPath + File.separator + fileName);
        if (!file.exists()) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); return; }

        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
        response.setContentLengthLong(file.length());

        try (InputStream is = new FileInputStream(file);
             OutputStream os = response.getOutputStream()) {
            byte[] buffer = new byte[8192];
            int n;
            while ((n = is.read(buffer)) != -1) os.write(buffer, 0, n);
        }
    }

    public static int executeConverter(String inputFilePath, String outputFilePath) {
        String SEDOC_CONVERTER_DIR_ABS_PATH = "absolute/path/to/converter/dir";
        String TEMP_DIR_ABS_PATH            = SEDOC_CONVERTER_DIR_ABS_PATH + File.separator + "temp";
        String SEDOC_CONVERTER_ABS_PATH     = SEDOC_CONVERTER_DIR_ABS_PATH + File.separator + "sedocConverter_exe";
        makeDirectory(TEMP_DIR_ABS_PATH);
        String[] cmd = { SEDOC_CONVERTER_ABS_PATH, inputFilePath, outputFilePath, TEMP_DIR_ABS_PATH };
        try {
            Timer t = new Timer();
            ProcessBuilder builder = new ProcessBuilder(cmd);
            builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
            builder.redirectError(ProcessBuilder.Redirect.INHERIT);
            Process proc = builder.start();
            TimerTask killer = new TimeoutProcessKiller(proc);
            t.schedule(killer, 20000);
            int exitValue = proc.waitFor();
            killer.cancel();
            return exitValue;
        } catch (Exception e) { e.printStackTrace(); return -1; }
    }

    private static void writeFile(String path, byte[] bytes) throws IOException {
        try (OutputStream os = new FileOutputStream(path)) { os.write(bytes); }
    }
    private static void deleteFile(String path) {
        File file = new File(path);
        if (file.exists()) file.delete();
    }
    private static void makeDirectory(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists()) dir.mkdirs();
    }
    private static class TimeoutProcessKiller extends TimerTask {
        private final Process p;
        public TimeoutProcessKiller(Process p) { this.p = p; }
        @Override public void run() { p.destroy(); }
    }
}

Related Information