SpringBoot项目——springboot配置Tomcat两个端口,https和http的方式 jar的打包和运行

news2024/11/23 8:07:08

目录

  • 引出
  • springboot配置Tomcat两个端口,https和http的方式
    • 1.生成SSL证书
    • 2.配置client.p12和https端口
    • 3.配置http的8080端口WebServerFactoryCustomizer接口
    • 4.启动项目
  • 项目应用:在某项目中有一个功能需要https协议
    • Tomcat启动https和http两个端口
    • 根据http或者https确定拦截后到哪个页面
    • 后端共享值,前端form表单获取
  • 问题:在https协议下,发送axios请求没反应
    • 解决方案一:用form表单
  • 项目的打包部署
    • 1.template might not exist or might not be accessible by any of the configured Template Resolvers

引出


1.springboot配置Tomcat两个端口,https和http的方式;
2.在https协议下,发送axios请求没反应,暂时用form表单解决;
3.运行jar包template might not exist报错及解决;

springboot配置Tomcat两个端口,https和http的方式

1.生成SSL证书

严格来说https不是一个独立协议,只是在http协议基础上增加了SSL/TLS加密层。所以我们需要先生成SSL证书,这里使用keytool生成jks。

keytool -genkey -alias client -keypass 12345678 -keyalg RSA -keysize 2048 -validity 365 -storetype PKCS12 -keystore ./client.p12 -storepass 12345678

在这里插入图片描述

在这里插入图片描述

2.配置client.p12和https端口

server:
  ssl:
    key-store: classpath:client.p12
    key-store-password: 12345678
    key-store-type: PKCS12
    key-alias: client
  # https的访问端口
  port: 8443

3.配置http的8080端口WebServerFactoryCustomizer接口

WebServerFactory接口的几个重要实现:

  • TomcatServletWebServerFactory:对应于tomcat

  • JettyServletWebServerFactory:对应jetty

  • UndertowServletWebServerFactory:对应undertow

  • NettyReactiveWebServerFactory:对应netty

Spring Boot默认使用http/1.1协议。所以我们增加额外的自定义https连接器。

package com.shanxi.gis.config;

import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class TomcatServerCustomer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        final Connector httpConn = new Connector("HTTP/1.1");
        httpConn.setPort(8080);
        factory.addAdditionalTomcatConnectors(httpConn);
    }
}

4.启动项目

运行项目后可以看到启动了https的8843和http的8080两个端口

在这里插入图片描述

项目应用:在某项目中有一个功能需要https协议

Tomcat启动https和http两个端口

在这里插入图片描述

在这里插入图片描述

TomcatServerCustomer.java文件

package com.shanxi.gis.config;

import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class TomcatServerCustomer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Value("${ServerHttpPort}")
    Integer httpHost;

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        final Connector httpConn = new Connector("HTTP/1.1");
        httpConn.setPort(httpHost);
        factory.addAdditionalTomcatConnectors(httpConn);
    }
}

application.yml配置文件

server:
  ssl:
    key-store: classpath:client.p12
    key-store-password: 12345678
    key-store-type: PKCS12
    key-alias: client
  # https的访问端口
  port: 8443

# 部署服务器的配置
ServerHttpsUrl: https://localhost:8443 # https的url
ServerHttpUrl: http://localhost:8080 # http的url
ServerHttpPort: 8080 # http的端口号
LoginPassword: Admin@1a2 # 登陆的密码


spring:
  mvc:
    static-path-pattern: /**
  resources:
    static-locations: classpath:/static/
  thymeleaf:
    prefix: classpath:/templates/
    check-template-location: true
    cache: false
    suffix: .html #模板后缀
    encoding: UTF-8 #编码
    mode: HTML #模板
    servlet:
      content-type: text/html

根据http或者https确定拦截后到哪个页面

LoginAuthorInterceptor.java文件

request.getScheme(); // for example, http, https, or ftp.

package com.shanxi.gis.interceptor;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * spring的拦截器,
 * 1.在容器中,@Component
 * 2.是spring的拦截器 implements HandlerInterceptor
 */
@Component
public class LoginAuthorInterceptor implements HandlerInterceptor {

    @Value("${ServerHttpsUrl}")
    String httpsUrl;

    @Value("${ServerHttpUrl}")
    String httpUrl;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果没有登陆,就去登陆页面,如果登陆了就放行
        HttpSession session = request.getSession();
        Object user = session.getAttribute("user");
        System.out.println(user);
        if ("admin".equals(user)){
            return true;
        }else {
            // 没有登陆,就去登陆页面
            String scheme = request.getScheme(); // for example, http, https, or ftp.
            // 如果是http就去,http的端口
            if ("http".equals(scheme)){
                response.sendRedirect(httpUrl+"/user/loginPage");
            }
            // 否则就去https的端口
            response.sendRedirect(httpsUrl+"/user/loginPage");
            return false;
        }
    }
}

后端共享值,前端form表单获取

login.html页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登陆页面</title>
    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
    <script src="/js/jquery-3.5.1.js"></script>
    <script src="/bootstrap/js/bootstrap.js"></script>
    <script src="/js/axios.min.js"></script>
    <script src="/js/vue.min-v2.5.16.js"></script>
    <link rel="stylesheet" href="/css/login.css">
</head>

<body>
    <div class="login-container" id="app">
        <h2>欢迎登录</h2>
<!--        "https://localhost:8443/user/login"-->
        <form :action=url method="post">
            <label for="username">用户名:</label>
            <input type="text" id="username" v-model="username" placeholder="请输入用户名" required name="username">
            <label for="password">密码:</label>
            <input type="password" id="password" v-model="password" placeholder="请输入密码" required name="password">
            <input type="submit" value="登录" @click="loginBtn" class="btn btn-primary btn-block">
        </form>
    </div>

<script>
    let app = new Vue({
        el:"#app",
        data:{
            username:"",
            password:"",
            url:"[[${httpsUrl}]]",
        },
        methods:{
        },
        created(){},
    })
</script>
</body>
</html>

后端共享值+跳转loginController.java

    @Value("${ServerHttpsUrl}")
    String httpsUrl;

    // 1.先到登陆页面
    @RequestMapping("/loginPage") // /user/loginPage
    public ModelAndView loginPage(){
        ModelAndView mv = new ModelAndView("user/login");
        mv.addObject("httpsUrl", httpsUrl + "/user/login");
        return mv;
    }

配置文件设置url

server:
  ssl:
    key-store: classpath:client.p12
    key-store-password: 12345678
    key-store-type: PKCS12
    key-alias: client
  # https的访问端口
  port: 8443

# 部署服务器的配置
ServerHttpsUrl: https://localhost:8443 # https的url
ServerHttpUrl: http://localhost:8080 # http的url
ServerHttpPort: 8080 # http的端口号
LoginPassword: Admin@1a2 # 登陆的密码


spring:
  mvc:
    static-path-pattern: /**
  resources:
    static-locations: classpath:/static/
  thymeleaf:
    prefix: classpath:/templates/
    check-template-location: true
    cache: false
    suffix: .html #模板后缀
    encoding: UTF-8 #编码
    mode: HTML #模板
    servlet:
      content-type: text/html

问题:在https协议下,发送axios请求没反应

问题如下:

在这里插入图片描述

解决方案一:用form表单

后端,用户名和密码正确后,重定向到index.html页面

// form表单下重定向到indexPage页面
response.sendRedirect(httpsUrl+“/user/indexPage”);

package com.shanxi.gis.controller;

import com.shanxi.gis.entity.ResData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

@Controller
@RequestMapping("/user")
@CrossOrigin // 允许跨域
public class LoginController {
    @Value("${ServerHttpsUrl}")
    String httpsUrl;

    @Value("${LoginPassword}")
    String loginPassword;

    // 1.先到登陆页面
    @RequestMapping("/loginPage") // /user/loginPage
    public ModelAndView loginPage(){
        ModelAndView mv = new ModelAndView("user/login");
        mv.addObject("httpsUrl", httpsUrl + "/user/login");
        return mv;
    }

    // 2.处理前端的axios请求
    @Autowired
    HttpSession session; // TODO:保存用户名到session

    @RequestMapping("/login")
    @ResponseBody
    public ResData login(
            String username,
            String password, HttpServletResponse response
            ) throws IOException {
        System.out.println(username +"//"+ password);
        if (Objects.equals(username, "") || username==null ||
                Objects.equals(password, "") || password==null
        ){
            return new ResData(1001, "必填项为空", null);
        }

        if (!"admin".equals(username) || !loginPassword.equals(password)){
            return new ResData(1002, "用户名|密码错误", null);
        }
        session.setAttribute("user",username); // TODO:set进session
        // form表单下重定向到indexPage页面
        response.sendRedirect(httpsUrl+"/user/indexPage");

        return new ResData(200, "ok", null);
    }

    // 3.登陆成功到index页面
    @RequestMapping("/indexPage")
    public String loginIndex(){
        return "gis/index";
    }
}

前端发送form表单

<form :action=url method=“post”>

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登陆页面</title>
    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
    <script src="/js/jquery-3.5.1.js"></script>
    <script src="/bootstrap/js/bootstrap.js"></script>
    <script src="/js/axios.min.js"></script>
    <script src="/js/vue.min-v2.5.16.js"></script>
    <link rel="stylesheet" href="/css/login.css">
</head>

<body>
    <div class="login-container" id="app">
        <h2>欢迎登录</h2>
<!--        "https://localhost:8443/user/login"-->
        <form :action=url method="post">
            <label for="username">用户名:</label>
            <input type="text" id="username" v-model="username" placeholder="请输入用户名" required name="username">
            <label for="password">密码:</label>
            <input type="password" id="password" v-model="password" placeholder="请输入密码" required name="password">
            <input type="submit" value="登录" @click="loginBtn" class="btn btn-primary btn-block">
        </form>
    </div>

<script>
    let app = new Vue({
        el:"#app",
        data:{
            username:"",
            password:"",
            url:"[[${httpsUrl}]]",
        },
        methods:{
            loginBtn(){
                console.log("send----")
                let params = new URLSearchParams();
                params.append("username",this.username)
                params.append("password",this.password)
                // axios.post("/user/login",params)
                axios.post("/user/login",params)
                    .then(response=>{
                        console.log("axios")
                        if (response.data.code==200){
                            // alert("登陆成功")
                            location.href= "/user/indexPage"
                        }else {
                            alert(response.data.msg)
                        }
                    })
            }
        },
        created(){},
    })

</script>

</body>
</html>

项目的打包部署

1.template might not exist or might not be accessible by any of the configured Template Resolvers

错误描述:

在idea中进行测试,所有功能都可以实现,尝试打包成jar包后运行,进入首页后没有显示用户信息页面,报500异常,后台显示Error resolving template [/user/info], template might not exist or might not be accessible by any of the configured Template Resolvers

报错信息:

在这里插入图片描述

2023-07-08 10:16:11.298 ERROR 28396 — [p-nio-80-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/user/info], template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause

org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/user/info], template might not exist or might not be accessible by any of the configured Template Resolvers

在这里插入图片描述

解决方案一:

@RequestMapping("/infoPage")
public String infoPage(){
    return "/user/info";
}

跳转页面去掉第一个反斜杠,改为如下

    @RequestMapping("/infoPage")
    public String infoPage(){
        return "user/info";
    }

在这里插入图片描述

thymeleaf + Spring Boot 在开发环境正常,但用jar运行时报错 Error resolving template template might not exist or might not be accessible;

就可以了

解决方案二:

spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

改成

spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates
spring.thymeleaf.suffix=.html
## spring相关的配置
spring:
  # 连接数据库
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/javaweb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: root
    password: 123
  ## 设置上传文件大小
  servlet:
    multipart:
      max-file-size: 10MB # 设置单个文件最大大小为10MB

  # 另一种解决方案
  thymeleaf:
    cache: false
    prefix: classpath:/templates
    suffix: .html

此时所有跳页面的都要加反斜杠

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/784485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习中标量,向量,矩阵和张量

1.标量(Scalar) 只有大小没有方向&#xff0c;可用实数表示的一个量 2.向量(Vector) 可以表示大小和方向的量 3.矩阵(Matrix) m行n列,矩阵中的元素可以是数字也可以是符号&#xff0c;在深度学习中一般是二维数组 4.张量(Tensor) 用来表示一些向量、标量和其他张量之间的…

Vue3使用Pinia-store选项式api和组合式api两种使用方式-快速入门demo

Pinia官方文档 选项式api /** Author: Jackie* Date: 2023-06-25 09:58:10* LastEditTime: 2023-07-24 17:32:25* LastEditors: Jackie* Description: pinia* FilePath: /vue3-demo-pinia/src/store/counter.js* version:*/ import { defineStore, storeToRefs } from pinia;…

el-table 表头设置渐变色

<el-table :data"tableData" stripe><el-table-column prop"name" label"测试" align"left"></el-table-column><el-table-column prop"code" label"测试1" align"left"></…

【《Go编程进阶实战:开发命令行应用、HTTP应用和gRPC应用》——指导你使用Go语言构建健壮的、生产级别的应用程序】

谷歌在2009年发布了Go编程语言&#xff0c;并于2012年发布了1.0版。Go语言具有强大的兼容性&#xff0c;一直用于编写可扩展的重量级程序(命令行应用程序、关键基础设施工具乃至大规模分布式系统)。凭借简单性、丰富的标准库和蓬勃发展的第三方软件包生态系统&#xff0c;Go语言…

渗透D1---基础知识回顾

端口&#xff1a; http 80 https 443 ftp 20 21 telnet 23 ssh 22 DNS 53 DHCP 67 68 mail smtp 25 pop3 110 ladp 389 域控制器 3306 mysql 关系型 sqlserver 1433 c# oracle 1521 3389 windows 远程连接端口 redis nosql 6379 编码介绍&#xff1a; 主要有两…

Git实现同一个项目多个版本

需求&#xff1a; 最近项目有这样一个需求&#xff0c;就是同一个项目要求给不同的两个客户&#xff0c;这两个客户需要的功能和界面不一样但基础功能一样&#xff0c;然后修改基础功能时这两个项目的基础功能要同时修改。避免同样的代码在两个项目上各自再开发一遍。 解决办…

前端JS识别二维码内容

原文&#xff1a;https://www.cnblogs.com/houxianzhou/p/15030351.html <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>图片二维码识别</title><script src"https://cdn.bootcss.com/jquery/3.4.1/jque…

如何在3ds max中创建可用于真人场景的巨型机器人:第 5 部分

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. After Effects 中的项目设置 步骤 1 打开“后效”。 打开后效果 步骤 2 我有真人版 我在After Effects中导入的素材。这是将 用作与机器人动画合成的背景素材。 实景镜头 步骤 3 有背景 选定的素材…

halcon微积分原理生成卡尺,异形产品宽度测量

1.普通测量项目中&#xff0c;我们可以利用halcon的测量模型&#xff0c;例如add_metrology_object_line_measure。很方便的测量直线&#xff0c;圆&#xff0c;椭圆&#xff0c;矩形等。这些工具都有一个缺点是&#xff0c;需要提前绘制测量位置&#xff0c;然后利用仿射变换跟…

力扣1116.打印零与奇偶数--------题解

题目描述 现有函数 printNumber 可以用一个整数参数调用&#xff0c;并输出该整数到控制台。 例如&#xff0c;调用 printNumber(7) 将会输出 7 到控制台。 给你类 ZeroEvenOdd 的一个实例&#xff0c;该类中有三个函数&#xff1a;zero、even 和 odd 。ZeroEvenOdd 的相同实…

使用langchain与你自己的数据对话(二):向量存储与嵌入

之前我以前完成了“使用langchain与你自己的数据对话(一)&#xff1a;文档加载与切割”这篇博客&#xff0c;没有阅读的朋友可以先阅读一下&#xff0c;今天我们来继续讲解deepleaning.AI的在线课程“LangChain: Chat with Your Data”的第三门课&#xff1a;向量存储与嵌入。 …

java整合chatGPT

public void test_chatGPT() throws IOException {String pro "127.0.0.1";//本机地址int pro1 7890; //代理端口号//创建一个 HttpHost 实例&#xff0c;这样就设置了代理服务器的主机和端口。HttpHost httpHost new HttpHost(pro, pro1);//创建一个 RequestConf…

Appium+python自动化(二十)- Monkey(猴子)日志(超详解)

简介 日志是非常重要的&#xff0c;用于记录系统、软件操作事件的记录文件或文件集合&#xff0c;可分为事件日志和消息日志。具有处理历史数据、诊断问题的追踪以及理解系统、软件的活动等重要作用&#xff0c;在开发或者测试软系统过程中出现了问题&#xff0c;我们首先想到的…

macOS Monterey 12.6.8 (21G725) 正式版发布,ISO、IPSW、PKG 下载

macOS Monterey 12.6.8 (21G725) 正式版发布&#xff0c;ISO、IPSW、PKG 下载 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持…

Google 登录支付,Firebase 相关设置

登录sdk: https://developers.google.com/identity/sign-in/android/start?hlzh-cn 支付sdk: https://developers.google.com/pay/api/android/overview?hlzh-cn Firebase sdk: https://firebase.google.com/docs/android/setup?hlzh-cn 登录设置&#xff1a; 创建凭据&…

U盘做PE系统盘

下载微PE工具箱 网址&#xff1a;https://www.wepe.com.cn/ 下载好后可以看到一个.exe文件 安装PE系统 先插入U盘到电脑&#xff0c;然后打开微PE工具箱&#xff0c;选择安装到U盘 等待制作成功 这时候U盘会被分成两个分区&#xff0c;EFI分区是PE微系统所在的分区&a…

蓝桥杯专题-真题版含答案-【最大公共子串】【阿姆斯特朗数】【出售金鱼】【亲密数】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

Android开发核心技术还是Framework~

这几年&#xff0c;社会问题层出不穷&#xff0c;最头疼的就是民生就业问题&#xff0c;大厂裁员&#xff0c;小厂倒闭&#xff0c;每年大批量的应届毕业生也涌入就业市场。 近几日&#xff0c;统计局也发布了就业相关数据&#xff0c;全国失业青年达600多万&#xff0c;面对此…

Solr原理剖析

一、简介 Solr是一个高性能、基于Lucene的全文检索服务器。Solr对Lucene进行了扩展&#xff0c;提供了比Lucene更为丰富的查询语言&#xff0c;并实现了强大的全文检索功能、高亮显示、动态集群&#xff0c;具有高度的可扩展性。同时从Solr 4.0版本开始&#xff0c;支持SolrCl…

《Ansible自动化工具篇:ubuntu操作系统基于ansible工具一键远程离线部署之K8S1.24.12二进制版集群》

一、部署背景 由于业务系统的特殊性&#xff0c;我们需要针对不同的客户环境部署二进制版K8S集群&#xff0c;由于大都数用户都是专网环境&#xff0c;无法使用外网&#xff0c;为了更便捷&#xff0c;高效的部署&#xff0c;针对业务系统的特性&#xff0c;我这边编写了 基于a…