基于上一篇的Autovue集成全过程,因为部署个tomcat还是不太好,于是,将Autovue的外部服务用springboot包装起来。
1.新建一个springboot项目,创建过程略,项目大概结构如下:
2.pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.6.6version>
<relativePath/>
parent>
<groupId>com.autovuegroupId>
<artifactId>autovueartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>autovuename>
<description>Autovue Plusdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.cimmetrygroupId>
<artifactId>avjnlpservletartifactId>
<version>1.0.0version>
<optional>trueoptional>
<scope>systemscope>
<systemPath>${project.basedir}/lib/avjnlpservlet.jarsystemPath>
dependency>
<dependency>
<groupId>com.cimmetrygroupId>
<artifactId>vuerdvservletartifactId>
<version>1.0.0version>
<optional>trueoptional>
<scope>systemscope>
<systemPath>${project.basedir}/lib/vuerdvservlet.jarsystemPath>
dependency>
<dependency>
<groupId>com.cimmetrygroupId>
<artifactId>vueservletartifactId>
<version>1.0.0version>
<optional>trueoptional>
<scope>systemscope>
<systemPath>${project.basedir}/lib/vueservlet.jarsystemPath>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<includeSystemScope>trueincludeSystemScope>
<fork>truefork>
configuration>
plugin>
plugins>
build>
project>
此处的 ${project.basedir}/lib/vueservlet.jar 是引入了本地jar包。
3.配置
application.yml
spring:
thymeleaf:
cache: false
encoding: utf-8
prefix: classpath:/templates/
suffix: .html
mode: HTML5
check-template-location: true
content-type: text/html
profiles:
active: dev
server:
port: 5098
servlet:
context-path: /Autovue
autovue:
baseUrl: http://127.0.0.1:5098/Autovue/
fileUrl: http://127.0.0.1:8400/document/download/download?fileId= # http://127.0.0.1:8400/document/download/download?fileId=13eb9067-f64b-4d6c-ac2e-1e2e26810d7e&storageType=minio
按照上图一个个的上代码(由于公司电脑限制,.java文件全是加密的,无法上传git)
ServletConfig.java
package com.autovue.config;
import com.autovue.servlet.MyVueJNLPServlet;
import com.cimmetry.servlet.VueKeyPairServlet;
import com.cimmetry.servlet.VueRDVServlet;
import com.cimmetry.servlet.VueServlet;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ServletConfig {
@Bean
public FilterRegistrationBean<SimpleCORSFilter> filterRegistration() {
FilterRegistrationBean<SimpleCORSFilter> registration = new FilterRegistrationBean<>(new SimpleCORSFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("Origin", "http://127.0.0.1:5098,http://172.16.5.97:5098");
registration.addInitParameter("Methods", "POST, GET, OPTIONS, DELETE");
registration.addInitParameter("Age", "3600");
registration.addInitParameter("Headers", "Content-type,x-requested-with,Authorization,x-ui-request,lang,Accept");
registration.addInitParameter("Credentials", "true");
return registration;
}
@Bean
public ServletRegistrationBean<MyVueJNLPServlet> VueJNLPServlet() {
ServletRegistrationBean<MyVueJNLPServlet> servletRegistrationBean = new ServletRegistrationBean<>(new MyVueJNLPServlet(), "/servlet/VueJNLPServlet");
servletRegistrationBean.addInitParameter("URL-Dir", "static/AutoVueClient");
servletRegistrationBean.addInitParameter("Cookies", "JSESSIONID;");
return servletRegistrationBean;
}
@Bean
public ServletRegistrationBean<VueRDVServlet> VueRDVServlet() {
ServletRegistrationBean<VueRDVServlet> servletRegistrationBean = new ServletRegistrationBean<>(new VueRDVServlet(), "/servlet/VueRDVServlet");
return servletRegistrationBean;
}
@Bean
public ServletRegistrationBean<VueKeyPairServlet> VueKeyPairServlet() {
ServletRegistrationBean<VueKeyPairServlet> servletRegistrationBean = new ServletRegistrationBean<>(new VueKeyPairServlet(), "/servlet/VueKeyPairServlet");
return servletRegistrationBean;
}
@Bean
public ServletRegistrationBean<VueServlet> VueServlet() {
ServletRegistrationBean<VueServlet> servletRegistrationBean = new ServletRegistrationBean<>(new VueServlet(), "/servlet/VueServlet");
servletRegistrationBean.addInitParameter("JVueServer", "127.0.0.1:5099;172.16.5.97:5099");
servletRegistrationBean.addInitParameter("Verbose", "false");
servletRegistrationBean.addInitParameter("EnableSSL", "false");
return servletRegistrationBean;
}
}
SimpleCORSFilter.java
package com.autovue.config;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class SimpleCORSFilter implements Filter {
private String origin;
private String methods;
private String age;
private String headers;
private String credentials;
public void init(FilterConfig filterConfig) throws ServletException {
origin = filterConfig.getInitParameter("Origin");
methods = filterConfig.getInitParameter("Methods");
age = filterConfig.getInitParameter("Age");
headers = filterConfig.getInitParameter("Headers");
credentials = filterConfig.getInitParameter("Credentials");
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String[] allowDomain = origin.split(",");
Set allowedOrigins = new HashSet(Arrays.asList(allowDomain));
String originHeader = request.getHeader("Origin");
if (allowedOrigins.contains(originHeader)) {
//跨域请求,*代表允许全部类型)
response.setHeader("Access-Control-Allow-Origin", originHeader);
//允许请求方式 "POST, GET, OPTIONS, DELETE"
response.setHeader("Access-Control-Allow-Methods", this.getMethods());
//用来指定本次预检请求的有效期,单位为秒,在此期间不用发出另一条预检请求 "3600"
response.setHeader("Access-Control-Max-Age", this.getAge());
//请求包含的字段内容,如有多个可用哪个逗号分隔如下 "Content-type,x-requested-with,Authorization,x-ui-request,lang,Accept"
response.setHeader("Access-Control-Allow-Headers", this.getHeaders());
//访问控制允许凭据,true为允许
response.setHeader("Access-Control-Allow-Credentials", this.getCredentials());
// 浏览器是会先发一次options请求,如果请求通过,则继续发送正式的post请求
// 配置options的请求返回
if (request.getMethod().equals("OPTIONS")) {
response.setStatus(200);
response.getWriter().write("OPTIONS returns OK");
return;
}
}
// 传递业务请求处理
chain.doFilter(servletRequest, servletResponse);
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getMethods() {
return methods;
}
public void setMethods(String methods) {
this.methods = methods;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getHeaders() {
return headers;
}
public void setHeaders(String headers) {
this.headers = headers;
}
public String getCredentials() {
return credentials;
}
public void setCredentials(String credentials) {
this.credentials = credentials;
}
}
AutovueController.java
package com.autovue.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
@Controller
public class AutovueController {
@Value("${autovue.baseUrl}")
public String baseUrl;
@Value("${autovue.fileUrl}")
public String fileUrl;
/**
*
* @param model
* @param request
* @return
*/
@GetMapping("/jnlp")
public String jnpl(Model model, HttpServletRequest request) {
String docfId = request.getParameter("docfId");
String isMark = request.getParameter("isMark");
String isReadOnly = request.getParameter("isReadOnly");
model.addAttribute("isMark", isMark);
model.addAttribute("isReadOnly", isReadOnly);
model.addAttribute("baseUrl", baseUrl);
model.addAttribute("fileUrl", fileUrl + docfId + "&storageType=minio");
return "jnlp";
}
}
MyVueJNLPServlet.java
package com.autovue.servlet;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyVueJNLPServlet extends HttpServlet {
private static final String CODEBASE_HOST_PLACEHOLDER = "__CODEBASE-HOST__";
private static final String AV_PARAMS_PLACEHOLDER = "";
private String m_URLDir;
private String m_codebaseHost = null;
protected TreeSet<String> m_Cookies;
public MyVueJNLPServlet() {
}
public void init() throws ServletException {
this.log("Initializing");
Enumeration var1 = this.getServletConfig().getInitParameterNames();
while (true) {
while (var1.hasMoreElements()) {
String var2 = (String) var1.nextElement();
String var3 = this.getServletConfig().getInitParameter(var2);
if (var2.equalsIgnoreCase("URL-Dir")) {
this.m_URLDir = var3;
} else if (var2.equalsIgnoreCase("Cookies") && !var3.equalsIgnoreCase("false")) {
this.m_Cookies = new TreeSet();
if (!var3.equalsIgnoreCase("true")) {
StringTokenizer var4 = new StringTokenizer(var3);
while (var4.hasMoreTokens()) {
this.m_Cookies.add(var4.nextToken(";"));
}
}
}
}
if (this.m_URLDir == null) {
throw new ServletException("Failed to intialize: The paramter URL_Dir missing in Web Config File");
}
this.log("Initialized");
return;
}
}
private void processRequest(HttpServletRequest var1, HttpServletResponse var2) throws ServletException, IOException {
TreeMap var3 = new TreeMap();
Enumeration var4 = var1.getParameterNames();
byte[] var5 = null;
String var6;
String var7;
while (var4.hasMoreElements()) {
var6 = (String) var4.nextElement();
var7 = var1.getParameter(var6);
if (var6.equalsIgnoreCase("EncryptionKey")) {
var5 = this.deserializeMsg(var7);
} else if (var6.equalsIgnoreCase("CodebaseHost")) {
this.m_codebaseHost = var7;
} else {
var3.put(var6, URLDecoder.decode(var7, "UTF-8"));
}
}
var6 = this.getCookies(var1, var5);
if (var6 != null) {
var3.put("COOKIES", var6);
}
var7 = this.m_URLDir + "/autovue.jnlp";
ClassPathResource classPathResource = new ClassPathResource(var7);
InputStream var8 = classPathResource.getInputStream();
// InputStream var8 = this.getServletConfig().getServletContext().getResourceAsStream(var7);
if (var8 == null) {
String var9 = "Failed to generate JNLP file as there is no template to read from specified location " + var7;
this.log("ERROR: " + var9);
var2.setContentType("text/plain");
var2.getWriter().println("Error. Reason: " + var9);
} else {
var2.setContentType("application/x-java-jnlp-file");
this.generateJNLPFile(var3, var8, var2.getWriter());
}
}
protected void doGet(HttpServletRequest var1, HttpServletResponse var2) throws ServletException, IOException {
this.processRequest(var1, var2);
}
protected void doPost(HttpServletRequest var1, HttpServletResponse var2) throws ServletException, IOException {
this.processRequest(var1, var2);
}
public String getServletInfo() {
return "Java Servlet in charge of generating the JNLP file required to launch AutoVue through Java Web Start";
}
protected String getCookies(HttpServletRequest var1, byte[] var2) throws IOException {
String var3 = this.collectCookies(var1);
if (var3 == null) {
return null;
} else if (var2 == null) {
return this.escapeXML(var3);
} else if (var2.length == 0) {
this.log("Encryption requested but no encryption key. Cookies not forwarded");
return null;
} else {
return this.encrypt(var3.getBytes("UTF-8"), var2);
}
}
protected String collectCookies(HttpServletRequest var1) {
String var2 = null;
if (this.m_Cookies != null && var1.getCookies() != null) {
Cookie[] var3 = var1.getCookies();
int var4 = var3.length;
for (int var5 = 0; var5 < var4; ++var5) {
Cookie var6 = var3[var5];
if (this.m_Cookies.isEmpty() || this.m_Cookies.contains(var6.getName())) {
if (var2 == null) {
var2 = "";
} else {
var2 = var2 + ";";
}
var2 = var2 + var6.getName() + '=' + var6.getValue();
}
}
}
return var2;
}
private String encrypt(byte[] var1, byte[] var2) {
try {
KeyGenerator var3 = KeyGenerator.getInstance("AES");
var3.init(128);
SecretKey var4 = var3.generateKey();
Cipher var5 = Cipher.getInstance("AES");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
X509EncodedKeySpec var7 = new X509EncodedKeySpec(var2);
KeyFactory var8 = KeyFactory.getInstance("RSA");
PublicKey var9 = var8.generatePublic(var7);
var5 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
var5.init(1, var9);
byte[] var10 = var5.doFinal(var4.getEncoded());
return this.serializeMsg(var6) + '-' + this.serializeMsg(var10);
} catch (Exception var11) {
this.log("Failed to encrypt message", var11);
return null;
}
}
private void generateJNLPFile(TreeMap<String, String> var1, InputStream var2, PrintWriter var3) {
Scanner var4 = new Scanner(var2);
Throwable var5 = null;
try {
while (var4.hasNextLine()) {
String var6 = var4.nextLine();
if (var6.contains("")) {
this.insertAutoVueParameters(var1, var3);
} else if (var6.contains("__CODEBASE-HOST__")) {
if (this.m_codebaseHost != null) {
var3.println(var6.replace("__CODEBASE-HOST__", this.m_codebaseHost));
} else {
this.log("Code base not defined, will not be able to start AutoVue");
var3.println(var6);
}
} else {
var3.println(var6);
}
}
} catch (Throwable var14) {
var5 = var14;
throw var14;
} finally {
if (var4 != null) {
if (var5 != null) {
try {
var4.close();
} catch (Throwable var13) {
var5.addSuppressed(var13);
}
} else {
var4.close();
}
}
}
}
private void insertAutoVueParameters(TreeMap<String, String> var1, PrintWriter var2) {
Iterator var3 = var1.keySet().iterator();
while (var3.hasNext()) {
String var4 = (String) var3.next();
var2.print("\t\t-param" );
var2.print(var4 + "=" + (String) var1.get(var4));
var2.println("");
}
}
private byte[] deserializeMsg(String var1) {
try {
if (var1 != null && var1.length() > 0 && var1.length() % 2 == 0) {
byte[] var2 = new byte[var1.length() / 2];
for (int var3 = 0; var3 < var2.length; ++var3) {
var2[var3] = (byte) (Integer.parseInt(var1.substring(2 * var3, 2 * var3 + 2), 16) & 255);
}
return var2;
}
this.log("Invalid key string : null, empty, or length not even = >" + var1 + "<");
} catch (NumberFormatException var4) {
this.log("Failed to parse HEX serialized string", var4);
}
return new byte[0];
}
private String serializeMsg(byte[] var1) {
if (var1 != null && var1.length != 0) {
String var2 = "";
for (int var3 = 0; var3 < var1.length; ++var3) {
String var4 = Integer.toHexString(var1[var3] & 255);
if (var4.length() == 1) {
var4 = "0" + var4;
}
var2 = var2 + var4;
}
return var2;
} else {
return null;
}
}
private String escapeXML(String var1) {
return var1 == null ? null : " + var1 + "]]>";
}
}
jnlp.html
Oracle AutoVue - JNLP
Oracle AutoVue
以上 ,大概有用的就这么多了,剩下其他的文件都是一些上篇文章提到的,都是autovue中能找到的。
如果找不到,或者也是做跟我类似这种预览的,私聊或评论~互帮互助,共同进步!