spring and UEditor Combination

Keywords: Java Spring JSON JSP Maven

Preface

The Spring Festival is boring, go to get rich text editor, then Baidu, many say Baidu's UEditor is good, and then go to the official website to take a look at the document, it is very simple and easy to use. Then I want to combine this with my own spring project. It's still GG when uploading pictures. Baidu Google once uploaded pictures. Now it can only upload pictures when the front and back are together. If there is a message from the UEditor of jsp that the pictures can be uploaded across the domain, here's a summary of the problems encountered in the past few days.

PS: It seems that the rich text editor in Blog Garden is OK...

brief introduction

UEditor is an open source html rich text editor developed by Baidu. The interface is really good, and the documentation is complete. Although cross-domain uploading leaves a pit for us to use our imagination (), in order to prevent UEditor from having pits, we need to change the source code of UEditor. Here we suggest downloading the source code of UEditor into our own project. Simply, it's easy to see the problem by tracking Debug.

The spring project demonstrated here integrates spring security and Thymeleaf, which is built with maven, and the background controller of UEditor is changed to controller of spring mvc. Originally, I wanted to use Servlet to find a lot of information. It seems that I did not see that spring MVC project can integrate source Servlet, but spring boot can register Servlet through @Servlet ComponentScan and integrate UEditor with spring boot. Most convenient, basically no pit, smooth way, which I have tried. Here's how spring project integrates the UEditor background.

text

The UEditor downloads and installs nothing, just above.

Front-end file directory:

  

Put the source code of UEditor back-end in your project:

  

Adding UEditor background dependencies:

  

     <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160810</version>
        </dependency>

Because we use spring mvc, the controller.jsp of UEditor should be changed to the form of Controller, basically copy the controller code of UEditor.

 1 @Controller
 2 public class UEditorController {
 3     @RequestMapping("/ued/config")
 4     public void service(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
 5 
 6         request.setCharacterEncoding("utf-8");
 7         response.setHeader("Content-Type" , "text/html");
 8         String rootPath = request.getSession()
 9                 .getServletContext().getRealPath("/");
10 
11         try {
12             String exec = new ActionEnter(request, rootPath).exec();
13             PrintWriter writer = response.getWriter();
14             writer.write(exec);
15             writer.flush();
16             writer.close();
17         } catch (IOException e) {
18             e.printStackTrace();
19         }
20     }
21 
22 }
Controller

Then we change the background interface of UEditor to our Controller.

  

At this point, if we try to use UEditor, we will not find the background configuration error. This is because the default controller.jsp and config.json are the same directory. The background code of UEditor can not find config.json. Here we find the ConfigManager in the background source code of UEditor, and change the getConfigPath() method. Here I put config.json in the same directory. maven src/main/resources, that is, under the classpath path path path path path, if there are differences, then change accordingly.

  

In this way, UEditor finds config.json, but uploading pictures is still not good. This is mainly because spring mvc has a conflict between the request object injected by controller and the commons-fileupload used by UEditor, which results in commons-fileload not being able to get the file byte stream in the request through debug (so we need to download the source code), and then we just need com.baidu.uedi. Change the upload file method of the tor. upload. BinaryUploader class.

Here I mainly changed the key FileItemIterator iterator = upload.getItemIterator(request); try to keep the source code as it is.

public static final State save(HttpServletRequest request,
            Map<String, Object> conf) {
        boolean isAjaxUpload = request.getHeader( "X_Requested_With" ) != null;

        if (!ServletFileUpload.isMultipartContent(request)) {
            return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT);
        }

        ServletFileUpload upload = new ServletFileUpload(
                new DiskFileItemFactory());

        if ( isAjaxUpload ) {
            upload.setHeaderEncoding( "UTF-8" );
        }

        try {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile multipartFile = multipartRequest.getFile(conf.get("fieldName").toString());
//            FileItemIterator iterator = upload.getItemIterator(request);
//
//            while (iterator.hasNext()) {
//                fileStream = iterator.next();
//
//                if (!fileStream.isFormField())
//                    break;
//                fileStream = null;
//            }

            if (multipartFile == null) {
                return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
            }

            String savePath = (String) conf.get("savePath");
            String originFileName = multipartFile.getOriginalFilename();
            String suffix = FileType.getSuffixByFilename(originFileName);

            originFileName = originFileName.substring(0,
                    originFileName.length() - suffix.length());
            savePath = savePath + suffix;

            long maxSize = ((Long) conf.get("maxSize")).longValue();

            if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
                return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
            }

            savePath = PathFormat.parse(savePath, originFileName);

            String physicalPath = (String) conf.get("rootPath") + savePath;

            InputStream is = multipartFile.getInputStream();
            State storageState = StorageManager.saveFileByInputStream(is,
                    physicalPath, maxSize);
            is.close();

            if (storageState.isSuccess()) {
                storageState.putInfo("url", PathFormat.format(savePath));
                storageState.putInfo("type", suffix);
                storageState.putInfo("original", originFileName + suffix);
            }

            return storageState;
        } catch (IOException e) {
        }
        return new BaseState(false, AppInfo.IO_ERROR);
    }

    private static boolean validType(String type, String[] allowTypes) {
        List<String> list = Arrays.asList(allowTypes);

        return list.contains(type);
    }

At this point, UEditor can upload files, there may be a small pit is that the path of file storage and return to the front-end path does not match, debug, in config.json, you can modify the file upload and save path and return to the url prefix configuration, source code in hand, any mistakes can be changed by themselves. In addition, because my project has spring security, the X-Frame-Options of the response header defaults to DENY, so that the pit dad iframe uploaded by UEditor will not show the picture. Here I tried setHeader in Controller, and the front end said that X-Frame-Options had two values. It was a real day dog. So just turn off spring security, you know how to change the header value in controller to let me know.

http.headers().frameOptions().disable()

Posted by didgydont on Thu, 28 Mar 2019 16:24:28 -0700