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

一,序

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

二,样例代码

1,代码结构

在这里插入图片描述

2,完整代码备份

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

//goto Dockerfile
#基础镜像
FROM openjdk:8-jre-alpine

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone

#把你的项目war包引入到容器的root目录下
COPY target/*.war /app.war

CMD ["--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.0
    build:
      context: .
      dockerfile: Dockerfile
    container_name: demo_dk
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 300M
        reservations:
          memory: 128M
    ports:
    - 8085:8085
    - 8086:8086
    - 8087:8087
    logging:
      driver: json-file
      options:
        max-size: 5m
        max-file: '1'
//goto shell\docker\1-n\Dockerfile
#基础镜像
FROM openjdk:8-jre-alpine

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone

#把你的项目war包引入到容器的root目录下
COPY *.war /app.war

RUN echo \
"#!/bin/sh\n"\
"nohup java -jar /app.war --server.port=8085 &\n"\
"nohup java -jar /app.war --server.port=8086 &"\
>> /start.sh

RUN 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 ]]; do
    sleep 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:alpine
    container_name: nginx
    deploy:
      resources:
        limits:
          cpus: '0.80'
          memory: 50M
        reservations:
          memory: 30M
    ports:
      - 80:80
    restart: on-failure
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
    logging:
      driver: 'json-file'
      options:
        max-size: '5m'
        max-file: '1'  
    depends_on:
      - demo
     
  demo:
    hostname: demo
    image: registry.cn-shanghai.aliyuncs.com/00fly/docker-demo:0.0.1
    deploy:
      resources:
        limits:
          cpus: '0.80'
          memory: 200M
        reservations:
          memory: 100M
    environment:
      - JAVA_OPTS=-server -Xms128m -Xmx128m -Djava.security.egd=file:/dev/./urandom
    restart: on-failure
    logging:
      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.1
    container_name: docker-demo
    deploy:
      resources:
        limits:
          cpus: '0.80'
          memory: 300M
        reservations:
          cpus: '0.05'
          memory: 100M
    ports:
    - 80:8080
    restart: on-failure
    logging:
      driver: json-file
      options:
        max-size: 5m
        max-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 pid

pname="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 $pname

PID=$(get_pid)
if [ -z "${PID}" ] 
then
 echo -e "\r\nJava Application already stop!"
else
 echo -e '\r\nkill -9  '${PID} '\r\n'
 kill -9 ${PID}
 echo -e "Java Application is stop!"
fi

rm -rf info.log

echo -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.war

PID=$(get_pid)
if [ -z "${PID}" ] 
then
 echo -e "\r\nJava Application already stop!"
else
 echo -e '\r\nkill -9  '${PID}
 kill -9 ${PID}
 echo -e "Java Application is stop!"
fi

rm -rf info.log

echo -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.war

echo -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
{
    @Autowired
    ApplicationContext applicationContext;
    
    @Value("${server.port}")
    String port;
    
    @Autowired
    HttpSession session;
    
    @Override
    public 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
{
    @Autowired
    private AuthorizationInterceptor authorizationInterceptor;
    
    @Override
    public 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 [类、类#方法、类#成员]
     */
    @PostConstruct
    public 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 [类、类#方法、类#成员]
     */
    @Override
    public void saveOrUpdate(User user)
    {
        if (user.getUserId() != null)
        {
            update(user);
            return;
        }
        insert(user);
    }
    
    @Override
    public void delete(Long userId)
    {
        log.info("delete user id = {}", userId);
        for (User user : users)
        {
            if (user.getUserId().equals(userId))
            {
                users.remove(user);
                return;
            }
        }
    }
    
    @Override
    public User get(Long userId)
    {
        log.info("get user id = {}", userId);
        for (User user : users)
        {
            if (user.getUserId().equals(userId))
            {
                return user;
            }
        }
        return null;
    }
    
    @Override
    public 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
{
    @Autowired
    ApplicationContext 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
{
    @Autowired
    private 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
    @ConditionalOnWebApplication
    CommandLineRunner 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/views
      suffix: .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/views
      suffix: .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-

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值