本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(3)

自定义404页面并打包docker部署项目

发布于2020-11-19 20:23     阅读(843)     评论(0)     点赞(8)     收藏(1)


前言
最近看了docker的用法,对于容器的理解感觉还行,当是自我感觉总是不靠谱的。所以现在就来使用docker容器实际部署一下项目,检验自己对于知识的掌握。

SpringBoot项目和docker的简单实战结合

自定义404页面

因为这篇博客只是简单演示docker的用法,所以就使用一个简单的SpringBoot应用即可。并且我最近阅读了一篇关于大厂自定义404页面的文章,感觉非常有趣,也很有特点。所以,就拿我自己自定义404页面的demo作为演示的例子了。

项目结构

在这里插入图片描述
注:因为功能很简单,所以只是导入了spring-boot-starter-web的依赖,其它的都不需要了。

NotFoundController类

说明:这里的控制器需要实现 ErrorController类,然后重写它的getErrorPath()方法。并且提供一个方法映射到 /error 路径,然后返回你希望返回的数据即可。这里我返回我自定义的图片数据流,纪念一下我今年养的小猫,可惜我出来实习不久后走丢了…

package com.test.poem.controller;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class NotFoundController implements ErrorController {

	private Logger log = LoggerFactory.getLogger(NotFoundController.class);
	
	private final String errorPath = "/error";
	private final String resourceLocation = "static/404.jpg";
	
	@Override
	public String getErrorPath() {
		return errorPath;
	}
	
	@GetMapping(errorPath)
	public void error(HttpServletRequest request, HttpServletResponse response) {
		try (OutputStream out = new BufferedOutputStream(response.getOutputStream())) {
			// 设置响应值的类型
			response.setHeader("Content-Type", "image/jpg");
			ClassPathResource resource = new ClassPathResource(resourceLocation);
			try (InputStream in = resource.getInputStream()) {
				byte[] data = FileCopyUtils.copyToByteArray(in);
				out.write(data);
				out.flush();
			}
			// 使用 try-with-resource 语句,关闭流的时候会自动调用flush方法
			// 但是,处于严谨的目的,还是再调用一次吧。因为并不是所有时候都需要关闭流刷新的,
			// 只是这里情况比较特殊。
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		log.info("未知访问链接:{}", request.getServletPath());
	}
}


PoemController类
这里就只有一个getPoem()方法,返回注入的Poem对象。

package com.test.poem.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.test.poem.entity.Poem;

@RestController
public class PoemController {
	
	@Autowired
	private Poem poem;
	
	@GetMapping("/poem")
	public Poem getPoem() {
		return poem;
	}
	
}

Poem实体类
我这里没有使用数据库,所以就只有一个设置好值的Poem类了。

package com.test.poem.entity;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Poem {
	// 可以去了解一波 # 和 $ 在这个注解中的区别!
	@Value("${title}")
	private String title;
	@Value("${author}")
	private String author;
	@Value("${content}")
	private String content;
	
	public Poem() {}
	
	public Poem(String title, String author, String content) {
		this.title = title;
		this.author = author;
		this.content = content;
	}
	
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
}

application.yml配置文件

# 修改服务端口
server:
  port: 8000

# 自定义数据,这里是为了使用 @Value 注解
title: 江城子.密州出猎
author: 苏轼
content: 老夫聊发少年狂,左牵黄,右擎苍,锦帽貂裘,千骑卷平冈。为报倾城随太守,亲射虎,看孙郎。酒酣胸胆尚开张,鬓微霜,又何妨?持节云中,何日遣冯唐?会挽雕弓如满月,西北望,射天狼。

启动类

package com.test.poem;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PoemApplication {

	public static void main(String[] args) {
		SpringApplication.run(PoemApplication.class, args);
	}
}

访问 /poem 路径

因为Chrome浏览器安装json格式化太麻烦了,所以使用Firefox浏览器来演示了,也推荐大家多使用Firefox,不能让Chrome一家独大!

注:这里的关注点应该是内容本身以及下方的HTTP状态码。

在这里插入图片描述

访问其它路径,这里其它路径都是404路径

在这里插入图片描述

在这里插入图片描述
注:所谓 404页面,不过是没有设置的页面而已。因为一个网站的正确url是有限的,当时错误的url是无限的。所以,给所有的错误的url一个特定的响应,即实现了404页面!

docker容器部署项目

前面的项目经过测试已经没有问题了,直接使用IDE打包即可或者使用Maven命令打包,打包命令:mvn clean package

在这里插入图片描述
注:打包的时候,关闭项目的运行,否则会出错。因为执行clean命令会删除某些文件,如果恰好你真正运行项目,会导致无法删除文件,即打包失败。

测试一下jar包是否可以正常运行

下面就是docker部署了,这里需要一个构建镜像的文件:dockerfile

FROM java:8     # 选择一个带有Java8的基础镜像
LABEL "author"="Alfred"  # 添加信息,MAINTAINER 被废弃了
ADD *.jar /app.jar  # 复制打包的jar包到镜像目录的某个位置,并重命名
EXPOSE 8000   # 暴露出8000端口
ENTRYPOINT ["nohup", "java", "-jar", "app.jar", "&"]  # 启动jar包的命令

开始构建

构建过程很顺利,没出啥幺蛾子!速度也非常快,因为我使用了阿里云的docker镜像加速服务。
在这里插入图片描述

查看已经存在的镜像

在这里插入图片描述

运行自己构建的docker镜像

命令解释:
-d docker镜像在后台启动
-P docker镜像随机映射到主机(虚拟机)的某个端口,但是最好显示指定它,不然会很麻烦。

注:因为端口是随机映射的,所以我也不知道映射到了哪里?这里使用命令
docker port xxx 查询即可,这个 xxx 表示的是前面启动镜像后的字符串的前面一部分,相当于身份证一样。

注:我这里加上 sudo,是因为我并没有将 docker 加入 docker 用户组里面。

在这里插入图片描述

docker服务是按照在虚拟机里面的,所以我这里在我本地远程访问虚拟机,或者你可以直接在虚拟机里面使用localhost访问,但是虚拟机比较卡,而且虚拟机访问成功了,也不意味着远程可以访问成功!
在这里插入图片描述
在这里插入图片描述
注:浏览器会默认发送一个http请求访问该url所指向的网站的图标,但是我这里并没有配置,所以也是404。

查看后台运行的docker容器

第一条即是刚才运行的docker镜像。
在这里插入图片描述

说明

好了,经过几天的努力(拖延),总算是完成了这篇博客。一开始写博客的时候确实是很兴奋,但是事情一旦拖延了以后,感觉就没有什么动力了!这就是古人所谓的:一鼓作气,再而衰,三而竭吗?这是一个很严重的问题,个人的执行力还是不太行!
现在,学习技术都尽量取亲自尝试一下,改变以为只是走马观花式的看看的形式了,感觉好多了,确实也学习到了知识。

对于使用Maven构建的项目,也可以将docker的构建过程集成进去,可以直接使用maven插件来完成这个功能。但是,它应该是需要本地安装docker的,我的电脑是windows家庭版、并且安装了VMWare虚拟机,基本是告别了安装docker了。不过,我可以在虚拟机里面安装Maven,这样也是可以的,有时间的话我就试一下(不过,可能没时间了,哈哈!)。


PS:参考资料

Dockerfile命令详解
docker run cmd entrypoint的区别
构建一个简单的jar包镜像l
菜鸟教程 docker
狂神说 docker

原文链接:https://blog.csdn.net/qq_40734247/article/details/109732964



所属网站分类: 技术文章 > 博客

作者:java战神

链接:http://www.javaheidong.com/blog/article/807/f525ed357b3605289950/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

8 0
收藏该文
已收藏

评论内容:(最多支持255个字符)