Springboot JSP项目如何以war、jar方式运行

文章目录

  • 一,序
  • 二,样例代码
    • 1,代码结构
    • 2,完整代码备份
  • 三,准备工作
    • 1. pom.xml 引入组件
    • 2. application.yml 指定jsp配置
  • 四,war方式运行
    • 1. 修改pom.xml文件
    • 2. mvn执行打包
  • 五,jar方式运行
    • 1. 修改pom-jsp-jar.xml文件
    • 2. 修改 spring-boot-maven-plugin添加版本号
    • 3. 添加资源文件配置(`Jar运行必须`)
    • 4. mvn执行打包
  • 六,war、jar方式运行配置文件区别

一,序

Spring Boot 官方不推荐使用JSP来作为视图,但是仍有部分项目使用了JSP视图,Springboot JSP项目运行方式有war、Jar两种方式。

二,样例代码

1,代码结构

在这里插入图片描述

2,完整代码备份

如何使用下面的备份文件恢复成原始的项目代码,请移步查阅:神奇代码恢复工具

//goto Dockerfile
#基础镜像
FROM openjdk:8-jre-alpineRUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone#把你的项目war包引入到容器的root目录下
COPY target/*.war /app.warCMD ["--server.port=8080"]#项目的启动方式
#ENTRYPOINT ["java","-Xmx400m","-Xms400m","-Xmn150m","-Xss1024k","-jar","/app.war", "--spring.profiles.active=prod"]
ENTRYPOINT ["java","-jar","/app.war"]
//goto pom-jsp-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fly</groupId><artifactId>docker-demo</artifactId><version>0.0.1</version><packaging>jar</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.4.RELEASE</version><relativePath /></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.build.timestamp.format>yyyyMMdd-HH</maven.build.timestamp.format><docker.hub>registry.cn-shanghai.aliyuncs.com</docker.hub><java.version>1.8</java.version><skipTests>true</skipTests></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><scope>compile</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>20.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!-- JSTL for JSP --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId></dependency><!-- For JSP compilation --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency></dependencies><build><finalName>${project.artifactId}-${project.version}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>1.4.2.RELEASE</version></plugin><!-- 添加docker-maven插件 --><plugin><groupId>io.fabric8</groupId><artifactId>docker-maven-plugin</artifactId><version>0.41.0</version><executions><execution><phase>package</phase><goals><goal>build</goal><goal>push</goal><goal>remove</goal></goals></execution></executions><configuration><!-- 连接到带docker环境的linux服务器编译image --><!-- <dockerHost>http://192.168.182.10:2375</dockerHost> --><!-- Docker 推送镜像仓库地址 --><pushRegistry>${docker.hub}</pushRegistry><images><image><!--推送到私有镜像仓库,镜像名需要添加仓库地址 --><name>${docker.hub}/00fly/${project.artifactId}:${project.version}-UTC-${maven.build.timestamp}</name><!--定义镜像构建行为 --><build><dockerFileDir>${project.basedir}</dockerFileDir></build></image><image><name>${docker.hub}/00fly/${project.artifactId}:${project.version}</name><build><dockerFileDir>${project.basedir}</dockerFileDir></build></image></images></configuration></plugin></plugins><resources><resource><directory>src/main/java</directory><excludes><exclude>**/*.java</exclude></excludes></resource><resource><directory>src/main/resources</directory><includes><include>**/**</include></includes></resource><resource><directory>src/main/webapp</directory><includes><include>**/**</include></includes><targetPath>META-INF/resources</targetPath></resource></resources></build>
</project>
//goto pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fly</groupId><artifactId>docker-demo</artifactId><version>0.0.1</version><packaging>war</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.4.RELEASE</version><relativePath /></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.build.timestamp.format>yyyyMMdd-HH</maven.build.timestamp.format><docker.hub>registry.cn-shanghai.aliyuncs.com</docker.hub><java.version>1.8</java.version><skipTests>true</skipTests></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><scope>compile</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>20.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!-- JSTL for JSP --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId></dependency><!-- For JSP compilation --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency></dependencies><build><finalName>${project.artifactId}-${project.version}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!-- 添加docker-maven插件 --><plugin><groupId>io.fabric8</groupId><artifactId>docker-maven-plugin</artifactId><version>0.41.0</version><executions><execution><phase>package</phase><goals><goal>build</goal><goal>push</goal><goal>remove</goal></goals></execution></executions><configuration><!-- 连接到带docker环境的linux服务器编译image --><!-- <dockerHost>http://192.168.182.10:2375</dockerHost> --><!-- Docker 推送镜像仓库地址 --><pushRegistry>${docker.hub}</pushRegistry><images><image><!--推送到私有镜像仓库,镜像名需要添加仓库地址 --><name>${docker.hub}/00fly/${project.artifactId}:${project.version}-UTC-${maven.build.timestamp}</name><!--定义镜像构建行为 --><build><dockerFileDir>${project.basedir}</dockerFileDir></build></image><image><name>${docker.hub}/00fly/${project.artifactId}:${project.version}</name><build><dockerFileDir>${project.basedir}</dockerFileDir></build></image></images></configuration></plugin></plugins><resources><resource><directory>src/main/java</directory><excludes><exclude>**/*.java</exclude></excludes></resource><resource><directory>src/main/resources</directory><includes><include>**/**</include></includes></resource><resource><directory>src/main/webapp</directory><includes><include>**/**</include></includes><targetPath>META-INF/resources</targetPath></resource></resources></build>
</project>
//goto shell\docker\1-n\docker-compose.yml
version: '3'
services:demo-dk:image: demo-dk:1.0build:context: .dockerfile: Dockerfilecontainer_name: demo_dkdeploy:resources:limits:cpus: '0.50'memory: 300Mreservations:memory: 128Mports:- 8085:8085- 8086:8086- 8087:8087logging:driver: json-fileoptions:max-size: 5mmax-file: '1'
//goto shell\docker\1-n\Dockerfile
#基础镜像
FROM openjdk:8-jre-alpineRUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone#把你的项目war包引入到容器的root目录下
COPY *.war /app.warRUN echo \
"#!/bin/sh\n"\
"nohup java -jar /app.war --server.port=8085 &\n"\
"nohup java -jar /app.war --server.port=8086 &"\
>> /start.shRUN chmod +x /start.sh
CMD nohup sh -c "/start.sh && java -jar /app.war --server.port=8087"
//goto shell\docker\1-n\restart-docker.sh
#!/bin/bash
docker-compose down && docker system prune -f && docker-compose build && docker-compose up -d
//goto shell\docker\1-n\start.sh
#!/bin/bash# 命令后加入 & ,保持程序后台持续运行
nohup java -jar /app.war --server.port=8085 & 
nohup java -jar /app.war --server.port=8086 &# 死循环,保持docker前台运行
while [[ true ]]; dosleep 1
done//goto shell\docker\1-n\start2.sh
#!/bin/bash# 命令后加入 & ,保持程序后台持续运行
nohup java -jar /app.war --server.port=8085 & 
java -jar /app.war --server.port=8086
//goto shell\docker\scale\docker-compose.yml
version: '3.8'
services:nginx:image: nginx:alpinecontainer_name: nginxdeploy:resources:limits:cpus: '0.80'memory: 50Mreservations:memory: 30Mports:- 80:80restart: on-failurevolumes:- ./nginx/nginx.conf:/etc/nginx/nginx.conf- ./nginx/conf.d:/etc/nginx/conf.dlogging:driver: 'json-file'options:max-size: '5m'max-file: '1'  depends_on:- demodemo:hostname: demoimage: registry.cn-shanghai.aliyuncs.com/00fly/docker-demo:0.0.1deploy:resources:limits:cpus: '0.80'memory: 200Mreservations:memory: 100Menvironment:- JAVA_OPTS=-server -Xms128m -Xmx128m -Djava.security.egd=file:/dev/./urandomrestart: on-failurelogging:driver: 'json-file'options:max-size: '5m'max-file: '1'
//goto shell\docker\scale\restart.sh
#!/bin/bash
docker-compose --compatibility restart
//goto shell\docker\scale\scale.sh
#!/bin/bash
docker-compose --compatibility up -d --scale nginx=1 --scale demo=3 
//goto shell\docker\scale\stop.sh
#!/bin/bash
docker-compose down
//goto shell\docker\single\docker-compose.yml
version: '3'
services:docker-demo:image: registry.cn-shanghai.aliyuncs.com/00fly/docker-demo:0.0.1container_name: docker-demodeploy:resources:limits:cpus: '0.80'memory: 300Mreservations:cpus: '0.05'memory: 100Mports:- 80:8080restart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: '1'
//goto shell\docker\single\restart.sh
#!/bin/bash
docker-compose down && docker system prune -f && docker-compose up -d
//goto shell\docker\single\stop.sh
#!/bin/bash
docker-compose down
//goto shell\init.sh
#!/bin/bash
dos2unix *
dos2unix */*
dos2unix */*/*chmod +x *.sh
chmod +x */*.sh
//goto shell\reload-jar.sh
#!/bin/bash
# get pidpname="springboot-cache.jar"
echo  -e  "jar-name=$pname\r\n"get_pid(){pid=`ps -ef | grep $pname | grep -v grep | awk '{print $2}'`echo "$pid"
}ps -ef|grep $pnamePID=$(get_pid)
if [ -z "${PID}" ] 
thenecho -e "\r\nJava Application already stop!"
elseecho -e '\r\nkill -9  '${PID} '\r\n'kill -9 ${PID}echo -e "Java Application is stop!"
firm -rf info.logecho -e "\r\nJava Application will startup!\r\n"
jar_path=`find .. -name $pname`#echo "jarfile=$jar_path"nohup java -jar $jar_path --server.port=8181 >>./info.log 2>&1 &ps -ef|grep $pname
//goto shell\reload-war.sh
#!/bin/bash
# get pid
get_pid(){pname="docker-demo.war"pid=`ps -ef | grep $pname | grep -v grep | awk '{print $2}'`echo "$pid"
}ps -ef|grep docker-demo.warPID=$(get_pid)
if [ -z "${PID}" ] 
thenecho -e "\r\nJava Application already stop!"
elseecho -e '\r\nkill -9  '${PID}kill -9 ${PID}echo -e "Java Application is stop!"
firm -rf info.logecho -e "\r\nJava Application will startup!"
nohup java -jar /work/demo/web/docker-demo.war -Xms64m -Xmx64m --server.port=8181 >>./info.log 2>&1 &
#sleep 2s
#nohup java -jar /work/demo/web/docker-demo.war -Xms64m -Xmx64m --server.port=8182 >>./info.log 2>&1 &ps -ef|grep docker-demo.warecho -e "please visit: https://test.00fly.online/user/"#tail -f info.log
//goto shell\start-service.sh
#!/bin/bash 
java -jar docker-demo.war -Xms64m -Xmx64m --server.port=8083 &
//goto src\main\java\com\fly\common\AnnotationHelper.java
package com.fly.common;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import lombok.extern.slf4j.Slf4j;/*** * 注解处理工具类* * @author 00fly* @version [版本号, 2020-04-16]* @see [相关类/方法]* @since [产品/模块版本]*/
@Slf4j
public class AnnotationHelper
{private static List<String> cacheList = new ArrayList<>();private AnnotationHelper(){super();}/*** 得到类上面的注解信息* * @param scannerClass* @param allowInjectClass* @return*/private static Annotation getClassAnnotation(Class<?> scannerClass, Class<? extends Annotation> allowInjectClass){if (!scannerClass.isAnnotationPresent(allowInjectClass)){return null;}return scannerClass.getAnnotation(allowInjectClass);}/*** 使用Java反射得到注解的信息* * @param annotation* @param methodName* @return Exception*/private static Object getAnnotationInfo(Annotation annotation, String methodName)throws Exception{if (annotation == null){return null;}Method declaredMethod = annotation.getClass().getDeclaredMethod(methodName, null);return declaredMethod.invoke(annotation, null);}/*** 从上下文获取 Controller注解类的 RequestMapping注解url信息* * @param applicationContext* @return* @throws Exception* @see [类、类#方法、类#成员]*/public static List<String> getRequestMappingURL(ApplicationContext applicationContext)throws Exception{if (cacheList.isEmpty()){synchronized (AnnotationHelper.class){List<String> list = new ArrayList<>();Map<String, Object> map = applicationContext.getBeansWithAnnotation(Controller.class);for (String key : map.keySet()){Class<?> clazz = map.get(key).getClass();Annotation classAnnotation = getClassAnnotation(clazz, RequestMapping.class);Object object = getAnnotationInfo(classAnnotation, "value");if (object != null){String[] array = (String[])object;log.info("{} -> {}", clazz.getName(), object);for (String it : array){if (!it.contains("$")){list.add(it);}}}}cacheList = list;}}return cacheList;}
}
//goto src\main\java\com\fly\common\AuthorizationInterceptor.java
package com.fly.common;import java.net.InetAddress;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;/*** * AuthorizationInterceptor* * @author 00fly* @version [版本号, 2019年7月21日]* @see [相关类/方法]* @since [产品/模块版本]*/
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter
{@AutowiredApplicationContext applicationContext;@Value("${server.port}")String port;@AutowiredHttpSession session;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{if (session.getAttribute("urls") == null){session.setAttribute("urls", AnnotationHelper.getRequestMappingURL(applicationContext));session.setAttribute("port", port);session.setAttribute("ip", InetAddress.getLocalHost().getHostAddress());}return true;}
}
//goto src\main\java\com\fly\common\WebMvcConfig.java
package com.fly.common;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** * WebMvcConfig* * @author 00fly* @version [版本号, 2019年7月21日]* @see [相关类/方法]* @since [产品/模块版本]*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer
{@Autowiredprivate AuthorizationInterceptor authorizationInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(authorizationInterceptor).addPathPatterns("/user/**");}
}
//goto src\main\java\com\fly\demo\model\User.java
package com.fly.demo.model;import java.io.Serializable;import lombok.Data;
import org.hibernate.validator.constraints.Range;import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;@Data
public class User implements Serializable
{private static final long serialVersionUID = -4621975403168327735L;private Long userId;@NotBlank(message = "用户名不能为空")private String userName;@NotNull(message = "年龄不能为空")@Range(min = 10, max = 60, message = "年龄必须在{min}-{max}")private Integer age;private String desc;
}
//goto src\main\java\com\fly\demo\service\impl\UserServiceImpl.java
package com.fly.demo.service.impl;import java.util.List;import javax.annotation.PostConstruct;import org.apache.commons.lang3.RandomUtils;
import org.springframework.stereotype.Service;import com.fly.demo.model.User;
import com.fly.demo.service.UserService;
import com.google.common.collect.Lists;import lombok.extern.slf4j.Slf4j;@Slf4j
@Service
public class UserServiceImpl implements  UserService
{private List<User> users = Lists.newArrayList();private Long sequence = 1L;/*** 初始化* * @see [类、类#方法、类#成员]*/@PostConstructpublic void init(){log.info("PostConstruct users");for (int i = 0; i < 5; i++){User user = new User();user.setUserId(sequence);user.setUserName("user_" + sequence);user.setAge(RandomUtils.nextInt(10, 40));user.setDesc("This is a user " + sequence);users.add(user);sequence++;}}private void insert(User user){log.info("insert user : {}", user);user.setUserId(sequence + 1);users.add(user);sequence++;}private void update(User user){log.info("update user id = {}", user.getUserId());for (User it : users){if (it.getUserId().equals(user.getUserId())){it.setUserName(user.getUserName());it.setAge(user.getAge());it.setDesc(user.getDesc());return;}}}/*** 新增/根据id更新* * @param user* @see [类、类#方法、类#成员]*/@Overridepublic void saveOrUpdate(User user){if (user.getUserId() != null){update(user);return;}insert(user);}@Overridepublic void delete(Long userId){log.info("delete user id = {}", userId);for (User user : users){if (user.getUserId().equals(userId)){users.remove(user);return;}}}@Overridepublic User get(Long userId){log.info("get user id = {}", userId);for (User user : users){if (user.getUserId().equals(userId)){return user;}}return null;}@Overridepublic List<User> list(){log.info("list users");return users;}
}
//goto src\main\java\com\fly\demo\service\UserService.java
package com.fly.demo.service;import java.util.List;import com.fly.demo.model.User;public interface UserService
{void saveOrUpdate(User user);void delete(Long userId);User get(Long userId);List<User> list();}
//goto src\main\java\com\fly\demo\web\IndexController.java
package com.fly.demo.web;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;import com.fly.common.AnnotationHelper;/*** * IndexController* * @author 00fly* @version [版本号, 2020-04-16]* @see [相关类/方法]* @since [产品/模块版本]*/
@Controller
public class IndexController
{@AutowiredApplicationContext applicationContext;/*** 首页* * @param model* @return* @throws Exception* @see [类、类#方法、类#成员]*/@GetMapping("/")public String index(Model model)throws Exception{model.addAttribute("urls", AnnotationHelper.getRequestMappingURL(applicationContext));return "/index";}
}
//goto src\main\java\com\fly\demo\web\UserApi.java
package com.fly.demo.web;import javax.validation.Valid;import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;import com.fly.demo.model.User;
import com.fly.demo.service.UserService;import lombok.extern.slf4j.Slf4j;@Slf4j
@Controller
@RequestMapping("/user")
public class UserApi
{@Autowiredprivate UserService userService;/*** 测试添加缓存,后续读取从缓存中取* * @param userId* @return* @see [类、类#方法、类#成员]*/@GetMapping("get")public User get(Long userId){return userService.get(userId);}/*** 新增/更新数据* * @param user* @return* @see [类、类#方法、类#成员]*/@PostMapping("/add")public String add(@Valid @ModelAttribute("item") User user, Errors errors, Model model){if (errors.hasErrors()){StringBuilder errorMsg = new StringBuilder();for (ObjectError error : errors.getAllErrors()){errorMsg.append(error.getDefaultMessage()).append(" ");}if (errorMsg.length() > 0){log.info("errors message={}", errorMsg);}model.addAttribute("items", userService.list());return "/user/show";}userService.saveOrUpdate(user);return "redirect:/user/list";}/*** 测试删除缓存*/@GetMapping("/delete/{id}")public String delete(@PathVariable Long id){userService.delete(id);return "redirect:/user/list";}@GetMapping({"/", "/list"})public String list(Model model){User user = new User();if (RandomUtils.nextInt(1, 10) > 1){user.setUserName(RandomStringUtils.randomNumeric(5));user.setAge(RandomUtils.nextInt(10, 70));user.setDesc(RandomStringUtils.randomNumeric(5));}model.addAttribute("item", user);model.addAttribute("items", userService.list());return "/user/show";}/*** 编辑数据* * @param id* @param model* @return* @see [类、类#方法、类#成员]*/@GetMapping("/update/{id}")public String update(@PathVariable Long id, Model model){model.addAttribute("item", userService.get(id));model.addAttribute("items", userService.list());return "/user/show";}
}
//goto src\main\java\com\fly\DemoBootApplication.java
package com.fly;import java.net.InetAddress;import org.apache.commons.lang3.SystemUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;import lombok.extern.slf4j.Slf4j;@Slf4j
@SpringBootApplication
public class DemoBootApplication
{@Value("${server.port}")Integer port;public static void main(String[] args){SpringApplication.run(DemoBootApplication.class, args);}@Bean@ConditionalOnWebApplicationCommandLineRunner openBrowser(){return args -> {if (SystemUtils.IS_OS_WINDOWS && port > 0){log.info("★★★★★★★★  now open Browser ★★★★★★★★ ");String ip = InetAddress.getLocalHost().getHostAddress();String url = "http://" + ip + ":" + port;Runtime.getRuntime().exec("cmd /c start /min " + url);}};}
}
//goto src\main\resources\application.yml
server:port: 8080
spring:mvc:view:prefix: /WEB-INF/viewssuffix: .jsp
//goto src\main\webapp\WEB-INF\views\index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<table><tr><th colspan="${fn:length(urls)+1}">Navigate</th></tr><tr><c:forEach var="item" items="${urls}"><td><a href="${pageContext.request.contextPath}${item}/">${item}</a></td></c:forEach></tr>
</table>
//goto src\main\webapp\WEB-INF\views\user\show.jsp
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<meta charset="utf-8">
<html>
<head>
<title>00fly功能演示</title>
<style>
body {margin: 10;font-size: 62.5%;line-height: 1.5;
}.blue-button {background: #25A6E1;padding: 3px 20px;color: #fff;font-size: 12px;border-radius: 2px;-moz-border-radius: 2px;-webkit-border-radius: 4px;border: 1px solid #1A87B9
}table {width: 70%;
}th {background: SteelBlue;color: white;
}td, th {border: 1px solid gray;font-size: 12px;text-align: left;padding: 5px 10px;overflow:hidden; white-space:nowrap; text-overflow:ellipsis;max-width: 200px;
}
</style>
</head>
<script type="text/javascript">function formReset() {location.href="/user/list";}
</script>
<body><center><table><tr><th colspan="${fn:length(urls)+1}">Navigate</th></tr><tr><c:forEach var="item" items="${urls}"><td><a href="${pageContext.request.contextPath}${item}/">${item}</a></td></c:forEach></tr></table>    <form:form method="post" modelAttribute="item" action="${pageContext.request.contextPath}/user/add"><table><tr><th colspan="3">Add or Edit Item</th><form:hidden path="userId" /></tr><tr><td><form:label path="userName">userName:</form:label></td><td><form:input path="userName" size="30" maxlength="30"></form:input></td><td>String <form:errors path="userName" cssStyle="color:red" /></td></tr><tr><td><form:label path="age">age:</form:label></td><td><form:input path="age" size="30" maxlength="30"></form:input></td><td>Integer <form:errors path="age" cssStyle="color:red" /></td></tr><tr><td><form:label path="desc">desc:</form:label></td><td><form:input path="desc" size="30" maxlength="30"></form:input></td><td>String <form:errors path="desc" cssStyle="color:red" /></td></tr><tr><td colspan="3" style="text-align: center;"><input type="submit" class="blue-button" /> <input type="reset" class="blue-button" onclick="formReset()" /></td></tr></table></form:form><h3>Data List</h3><c:if test="${!empty items}"><table><tr><th width="5">序号</th><th width="5">Edit</th><th width="5">Delete</th><th width="100">userId</th><th width="150">userName</th><th width="150">age</th><th width="150">desc</th></tr><c:forEach items="${items}" var="it" varStatus="vs"><tr><td>${vs.count}</td><td><a href="<c:url value='/user/update/${it.userId}' />">Edit</a></td><td><a href="<c:url value='/user/delete/${it.userId}' />">Delete</a></td><td>${it.userId}</td><td>${it.userName}</td><td>${it.age}</td><td>${it.desc}</td></tr></c:forEach></table></c:if><h3>应用端口:<font color="red">${port}</font></h3><h3>Server IP<font color="red">${ip}</font></h3></center>
</body>
</html>

三,准备工作

1. pom.xml 引入组件

		<!-- JSTL 支持,按需引入 --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId></dependency><!-- JSP 编译支持,必须引入--><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope></dependency>

2. application.yml 指定jsp配置

application.yml

spring:mvc:view:prefix: /WEB-INF/viewssuffix: .jsp

四,war方式运行

1. 修改pom.xml文件

	<packaging>war</packaging>

2. mvn执行打包

mvn clean package

执行后会在target目录生成war包,拷贝出来后运行

java -jar docker-demo-0.0.1.war

浏览器访问: http://127.0.0.1:8080/user/ 界面如下:
在这里插入图片描述

五,jar方式运行

复制 pom.xml重命名为 pom-jsp-jar.xml

1. 修改pom-jsp-jar.xml文件

	<packaging>jar</packaging>

2. 修改 spring-boot-maven-plugin添加版本号

注意只能使用1.4.2.RELEASE,其他版本不行

			<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>1.4.2.RELEASE</version></plugin>

3. 添加资源文件配置(Jar运行必须

		<resources><resource><directory>src/main/java</directory><excludes><exclude>**/*.java</exclude></excludes></resource><resource><directory>src/main/resources</directory><includes><include>**/**</include></includes></resource><resource><directory>src/main/webapp</directory><includes><include>**/**</include></includes><targetPath>META-INF/resources</targetPath></resource></resources>

4. mvn执行打包

mvn clean package -f pom-jsp-jar.xml

执行后会在target目录生成 jar包,拷贝出来后运行

java -jar docker-demo-0.0.1.jar

六,war、jar方式运行配置文件区别

在这里插入图片描述
在这里插入图片描述


有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-

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

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

相关文章

PPT制作指南

诸神缄默不语-个人CSDN博文目录 文章目录 1. SOP2. PPT的目标3. PPT素材4. 内容框架5. 设计细节本文撰写过程中使用到的参考资料 1. SOP 分析目标→收集素材→明确框架→视觉呈现 2. PPT的目标 演讲型PPT&#xff1a;字少图多 阅读型PPT&#xff1a;需要文字解释 分析维度&…

【深度学习基础】Pytorch框架CV开发(2)实战篇

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

springboot常见网络相关错误及原因解析

在基于spring-boot开发过程尤其是上线后&#xff0c;经常出现网络相关的错误&#xff0c;令人难以琢磨和下手&#xff0c;所以就spring-boot使用过程中可能碰到的网络相关问题进行分析&#xff0c;结合网络转包、日志报错和前端输出&#xff0c;针对网络连接超时、连接被拒绝、…

默认路由配置

默认路由&#xff1a; 在末节路由器上使用。&#xff08;末节路由器是前往其他网络只有一条路可以走的路由器&#xff09; 默认路由被称为最后的关卡&#xff0c;也就是静态路由不可用并且动态路由也不可用&#xff0c;最后就会选择默认路由。有时在末节路由器上写静态路由时…

自动驾驶算法(五):Informed RRT*算法讲解与代码实现(基于采样的路径规划) 与比较

目录 1 RRT*与Informed RRT* 2 Informed RRT*代码解析 3 完整代码 4 算法比较 1 RRT*与Informed RRT* 上篇博客我们介绍了RRT*算法&#xff1a;我们在找到一个路径以后我们还会反复的搜索。 Informed RRT*算法提出的动机(motivation)是能否增加渐近最优的速度呢&#xff1f;…

【数据结构】树家族

目录 树的相关术语树家族二叉树霍夫曼树二叉查找树 BST平衡二叉树 AVL红黑树伸展树替罪羊树 B树B树B* 树 当谈到数据结构中的树时&#xff0c;我们通常指的是一种分层的数据结构&#xff0c;它由节点&#xff08;nodes&#xff09;组成&#xff0c;这些节点之间以边&#xff08…

基于级联延迟信号消除的锁相环(CDSC_PLL)技术MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 基于级联型延迟信号消除&#xff08;CDSC&#xff09;的锁相环技术&#xff08;CDSC-PLL&#xff09;&#xff0c;该锁相环克服了传统dq 锁相环在电网电压畸变或不对称时存在较大稳态误差的缺点。CDSC-PLL是在…

Ansible中的任务执行控制

循环 简单循环 {{item}} 迭代变量名称 loop: - value1 - value2 - ... //赋值列表{{item}} //迭代变量名称循环散列或字典列表 - name: create filehosts: host1tasks:- name: file moudleservice:name: "{{ item.name }}"state: "{{…

FRI及相关SNARKs的Fiat-Shamir安全

1. 引言 本文主要参考&#xff1a; Alexander R. Block 2023年论文 Fiat-Shamir Security of FRI and Related SNARKsAlbert Garreta 2023年9月在ZK Summit 10上分享 ZK10: Fiat-Shamir security of FRI and related SNARKs - Albert Garreta (Nethermind) 评估参数用的Sage…

Git客户端软件 Tower mac中文版特点说明

Tower mac是一款Mac OS X系统上的Git客户端软件&#xff0c;它提供了丰富的功能和工具&#xff0c;帮助用户更加方便地管理和使用Git版本控制系统。 Tower mac软件特点 1. 界面友好&#xff1a;Tower的界面友好&#xff0c;使用户能够轻松地掌握软件的使用方法。 2. 多种Git操…

edge浏览器的隐藏功能

1. edge://version 查看版本信息 2. edge://flags 特性界面 具体到某一特性&#xff1a;edge://flags/#overlay-scrollbars 3. edge://settings设置界面 详情可参考chrome: 4. edge://extensions 扩展程序页面 5. edge://net-internals 网络事件信息 6. edge://component…

excel制作透视表

场景描述&#xff1a; 有一张excel表&#xff0c;存在多条记录&#xff0c;现在需要把相同名称的商品的数量求和&#xff0c;放在一起展示 操作步骤&#xff1a; 删除最后一行数据 选中不显示分类汇总 以表格形式展示

STM32-HAL库08-TIM的输出比较模式(输出PWM的另一种方式)

STM32-HAL库08-TIM的输出比较模式&#xff08;输出PWM的另一种方式&#xff09; 一、所用材料&#xff1a; STM32F103C6T6最小系统板 STM32CUBEMX&#xff08;HAL库软件&#xff09; MDK5 示波器或者逻辑分析仪 二、所学内容&#xff1a; 通过定时器TIM的输出比较模式得到预…

第21期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练 Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

【计算机网络实验/wireshark】tcp建立和释放

wireshark开始捕获后&#xff0c;浏览器打开xg.swjtu.edu.cn&#xff0c;网页传输完成后&#xff0c;关闭浏览器&#xff0c;然后停止报文捕获。 若捕获不到dns报文&#xff0c;先运行ipconfig/flushdns命令清空dns缓存 DNS报文 设置了筛选条件&#xff1a;dns 查询报文目的…

BO(Business Object)是一种用于表示业务对象的设计模式

BO是 Business Object 的缩写&#xff0c;是一种用于表示业务对象的设计模式。在Java中&#xff0c;BO的主要作用是 封装业务逻辑&#xff0c;实现业务流程的可重用性和可维护性。 BO主要有以下几个作用&#xff1a; 实现业务逻辑的封装&#xff1a;将业务逻辑封装在BO对象中&a…

【完美世界】石昊拒绝云曦相认,爱而不得,云曦悲伤无助

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫资讯。 深度爆料《完美世界云曦篇》最新一集&#xff0c;为了云曦&#xff0c;石昊不远十万里&#xff0c;亲自送她回家&#xff0c;这份感情之真挚&#xff0c;绝对毋庸置疑。然而&#xff0c;令人感到不解的是&…

【KVM】软件虚拟化和硬件虚拟化

前言 大家好&#xff0c;我是秋意零。 今天介绍的内容是虚拟化技术以及软件虚拟化和硬件虚拟化。 &#x1f47f; 简介 &#x1f3e0; 个人主页&#xff1a; 秋意零&#x1f525; 账号&#xff1a;全平台同名&#xff0c; 秋意零 账号创作者、 云社区 创建者&#x1f9d1; 个…

HCIA数据通信——路由协议

数据通信——网络层&#xff08;OSPF基础特性&#xff09;_咕噜跳的博客-CSDN博客 数据通信——网络层&#xff08;RIP与BGP&#xff09;_咕噜跳的博客-CSDN博客 上述是之前写的理论知识部分&#xff0c;懒得在实验中再次提及了。这次做RIP协议以及OSPF协议。不过RIP协议不常用…

Mac连接linux的办法(自带终端和iterm2)

1. 使用Mac自带终端Terminal 1.1 点击右上角的聚焦搜索&#xff0c;再输入终端 1.2 查找linux系统的ip地址 在虚拟机里输入如下命令&#xff0c;找到蓝色区域的就是ip地址 ip addr 如果没有显示ip地址&#xff0c;可以重新安装一下虚拟机&#xff0c;之后确保以太网的连接是打…