Java Servlet Example

Caution

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

[Software Security Weakness Diagnosis Guide]

1. Servlet Configuration

Note

In Servlet 3.0 and above, you can use the @WebServlet annotation instead.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         id="WebApp_ID" version="3.1">
  <display-name>synapeditor</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>ImportServlet</servlet-name>
    <servlet-class>com.synap.synapeditor.ImportServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ImportServlet</servlet-name>
    <url-pattern>/importDoc</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>com.synap.synapeditor.UploadServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/uploadFile</url-pattern>
  </servlet-mapping>
</web-app>

2. Image and 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 com.google.gson.GsonBuilder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import java.io.*;
import java.util.*;

public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID    = 1L;
    private static final String UPLOAD_DIR_REL_PATH = "uploads";

    private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3;
    private static final int MAX_FILE_SIZE    = 1024 * 1024 * 40;
    private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (!ServletFileUpload.isMultipartContent(request)) return;

        DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setSizeThreshold(MEMORY_THRESHOLD);
        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("UTF-8");
        upload.setFileSizeMax(MAX_FILE_SIZE);
        upload.setSizeMax(MAX_REQUEST_SIZE);

        String ROOT_ABS_PATH       = request.getSession().getServletContext().getRealPath("");
        String UPLOAD_DIR_ABS_PATH = ROOT_ABS_PATH + File.separator + UPLOAD_DIR_REL_PATH;
        makeDirectory(UPLOAD_DIR_ABS_PATH);

        String storeFileName = "";
        try {
            List<FileItem> items = upload.parseRequest(request);
            if (items != null) {
                for (FileItem item : items) {
                    if (item.isFormField()) continue;
                    String ext = item.getName().substring(item.getName().lastIndexOf('.'));
                    storeFileName = UUID.randomUUID().toString() + ext;
                    item.write(new File(UPLOAD_DIR_ABS_PATH + File.separator + storeFileName));
                }
            }
        } catch (Exception ex) { ex.printStackTrace(); }

        Map<String, Object> map = new HashMap<>();
        map.put("uploadPath", "uploads/" + storeFileName);

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.print(new GsonBuilder().create().toJson(map));
        out.flush();
    }

    private static void makeDirectory(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists()) dir.mkdir();
    }
}

3. 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 com.google.gson.GsonBuilder;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import java.io.*;
import java.util.*;
import java.util.zip.InflaterInputStream;

public class ImportServlet extends HttpServlet {
    private static final long serialVersionUID    = 1L;
    private static final String UPLOAD_DIR_REL_PATH = "import";

    private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3;
    private static final int MAX_FILE_SIZE    = 1024 * 1024 * 40;
    private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (!ServletFileUpload.isMultipartContent(request)) return;

        DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setSizeThreshold(MEMORY_THRESHOLD);
        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("UTF-8");
        upload.setFileSizeMax(MAX_FILE_SIZE);
        upload.setSizeMax(MAX_REQUEST_SIZE);

        String ROOT_ABS_PATH       = request.getSession().getServletContext().getRealPath("");
        String UPLOAD_DIR_ABS_PATH = ROOT_ABS_PATH + File.separator + UPLOAD_DIR_REL_PATH;
        makeDirectory(UPLOAD_DIR_ABS_PATH);

        String storeFileAbsPath = "";
        try {
            List<FileItem> items = upload.parseRequest(request);
            for (FileItem item : items) {
                if (item.isFormField()) continue;
                String fileName    = item.getName();
                String contentType = item.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";

                String storeFileName = UUID.randomUUID().toString() + ext;
                storeFileAbsPath     = UPLOAD_DIR_ABS_PATH + File.separator + storeFileName;
                item.write(new File(storeFileAbsPath));
            }
        } catch (Exception ex) { ex.printStackTrace(); }

        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 outputDirAbsPath = UPLOAD_DIR_ABS_PATH + File.separator + yearMonth + File.separator + uuid;
        makeDirectory(outputDirAbsPath);

        executeConverter(storeFileAbsPath, outputDirAbsPath);
        deleteFile(storeFileAbsPath);

        String pbAbsPath = outputDirAbsPath + File.separator + "document.pb";
        Integer[] serializedData = serializePbData(pbAbsPath);
        deleteFile(pbAbsPath);

        Map<String, Object> map = new HashMap<>();
        map.put("serializedData", serializedData);
        map.put("importPath", UPLOAD_DIR_REL_PATH + "/" + yearMonth + "/" + uuid);

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.print(new GsonBuilder().create().toJson(map));
        out.flush();
    }

    protected static int executeConverter(String inputFilePath, String outputPath) {
        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, outputPath, TEMP_DIR_ABS_PATH };
        try {
            Timer t = new Timer();
            ProcessBuilder pb = new ProcessBuilder(cmd);
            pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
            pb.redirectError(ProcessBuilder.Redirect.INHERIT);
            Process proc = pb.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; }
    }

    protected 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 n;
                while ((n = ifis.read(buffer)) != -1) {
                    for (int i = 0; i < n; i++) serialized.add(buffer[i] & 0xFF);
                }
            }
        }
        return serialized.toArray(new Integer[0]);
    }

    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(); }
    }
}

Related Information