一、软件架构解释
今天开始大家要学习到服务器后端的知识了,但是在说后面的内容之前,先给大家说说两种经典的软件架构模式C/S 和B/S 。
- C/S 架构(QQ,wechat)
即: Client/Server,客户/服务器 . 要求客户端电脑安装一个客户端程序 , 服务器端电脑安装服务器端程序
- 特点
- 服务器负责管理数据库的访问
- 客户端负责与用户的交互,收集用户信息,通过网络向服务器发送请求。
- 客户程序(前台程序)在客户机上运行,数据库服务程序(后台程序)在应用服务器上运行
- 优点
- 用户体验好、效果炫酷
- 信息处理更加安全
- 客户端可以存储一部分资源,减少获取资源的时间和精力
- 缺点
- 占用本地磁盘空间
- 维护麻烦,经常要更新
- 安装也许依赖其他附加环境
- 常见应用 QQ | 微信客户端 | 迅雷 ...
- B/S架构(网页游戏)
即: Browser / Server 浏览器 /服务器 通过浏览器和服务器进行对接,不需要其他附带程序
- 特点
- 用户的一系列操作都是在浏览器上完成的,通过浏览器与服务器对接
- 客户程序过于简单,导致所有内容以及计算都放在服务器身上。
- 优点
- 维护升级简单、只需要关注浏览器即可
- 无需安装附带程序,只要有浏览器即可使用
- 缺点
- 效果受浏览器限制、也许不能像 C/S 那么炫酷
- 信息安全稍差,如: 网银需要使用U盾,对信息进行加密
- 服务器存负荷较重( 资源,以及绝大多数运算工作都是在服务器端)
- 常见应用 网银 | web qq | 网页游戏 ...
二、MVC架构解释
- 概念解释
上面解释的 B/S 或者 C/S 只是从大局观来划分 客户和 服务器两个端而已。 这里的MVC 开始就侧重于说明服务器端了。 在服务器端的架构设计演变过程中, MVC 是一个很经典的设计。 几乎大部分的B/S 架构程序都采用MVC 来设计它们的程序。 MVC 其实就是 M( Model ) 、 V( View ) 、C(Control) , 三个层级
- M
指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性
- V
指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操纵的方式
- C
控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。
- MVC 架构的具体实现
上面的MVC 是早期提倡出来的一种设计模式,一种理论基础。实际编码时,服务器端代码会根据逻辑进行分层,常见的分层为三层,称之为: 三层体系结构 。 分别是: 表示层、业务逻辑层、数据访问层
- 具体层级的实现框架
三、Spring 基本使用
-
Spring Boot介绍
上面分析过了,我们的每一个层级的解决方案有不同的框架,由于每一个框架有自己的配置,所以Spring Boot 的出发点就是整合三个层级这些臃肿的配置。它是Spring 社区较新的一个项目。该项目的目的是帮助开发者更容易的创建基于 Spring 的应用程序和服务,让更多人的人更快的对 Spring 进行入门体验,为 Spring 生态系统提供了一种固定的、约定优于配置风格的框架 复制代码
-
Spring Boot 环境搭建
-
build.gradle 添加依赖
dependencies { compile("org.springframework.boot:spring-boot-starter-web:1.5.10.RELEASE") }
-
定义SpringBoot 启动类
@SpringBootApplication public class SampleController {
public static void main(String[] args) throws Exception { SpringApplication.run(SampleController.class, args); } 复制代码
}
-
第一个Controller
//表示这是一个控制器,用于处理客户端的请求 @RestController public class DemoController { private static final String TAG = "DemoController";
//映射地址路径 访问地址 :localhost:8080/demo @RequestMapping("/demo") public String save(){ System.out.println("DemoController save~!~~!"); //返回结果 return "执行成功"; } 复制代码
}
四、服务器软件介绍
- 什么是服务器
服务器其实就是比PC高级一点的电脑,硬件更高级,性能更好、运算能力更强。
- 什么是服务器软件
服务器软件其实也是软件,这类软件,可以让我们写的代码托管我们写好的网站项目、这样就可以访问了。
- 常见的服务器软件
Apache: Apache 趋向于静态资源处理
Tomcat : Apache 提供的一个免费小型服务器软件 , 支持JSP/Servlet 规范
WebLogic : Bea公司提供的收费大型服务器软件 , 支持EE的所有规范
WebSphere : IBM公司收费大型服务器软件 , 支持EE的所有规范
JBoss : 一个基于J2EE开放源码的服务器软件 核心不支持 JSP/Servlet ,一般与tomcat 或者 jetty配合使用
五、PostMan 使用(网络调试工具)
-
PostMan 介绍
用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求,用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具。今天给大家介绍的这款网页调试工具不仅可以调试简单的css、html、脚本等简单的网页基本信息,它还可以发送几乎所有类型的HTTP请求!**Postman**在发送网络HTTP请求方面可以说是Chrome插件类产品中的代表产品之一。 复制代码
早期它一Chrome插件形式存在,如今官方已经推出了一个独立的安装桌面版,并不一定要通过插件形式安装于Chrome浏览器上。
-
PostMan 安装
-
到官方网站下载
-
直接安装使用即可
-
PostMan 使用
六、Controller CRUD演练
服务器端的任何知识都是涉及到增删查改, 一句话概括,做服务器端,其实就是不停的做CRUD
- 获取页面提交数据
- a. 接收零散参数
直接在方法的参数中指定同名参数即可获取请求传递过来的数据
@RequestMapping("login")
public String login(String username , String password){
}
复制代码
- b. 接收对象数据
有时候需要接收的数据较多,如果都以零散的参数来接收,就会很麻烦。其实可以使用对象来接收数据。
public class User{
private String username;
private String password;
//get & set xxx
}
@RequestMapping("login")
public String login(User user){
}
复制代码
- 增加 | 保存操作
此处随意以一个保存工作来演示即可, 可以是保存学生信息、 保存商品信息..不限
- 接收参数
假设我们要演示一个学生管理系统的保存工作,那么务必要从浏览器接收学生信息(至少包含基本的名字、年龄、地址、电话 ...), 通常这些操作应该是通过页面来操作,此处并不涉及到页面,可以结合PostMan来演示
@RequestMapping("/user_save")
public String save(String name , int age , String address ){
System.out.println("name=" + name + "==age=" + age + "===addres=" + address);
return "保存成功";
}
复制代码
postman 演示
- 完成保存
可以先保存数据,多增加几条,然后即可引出ID了。主要是为了以后修改数据起来比较方便, 注意要追加写入
private static int ID = 1 ;
@RequestMapping("/user_save")
public String save(String name , int age , String address ){
try {
//在每一行的后面跟上回车换行
String content = ID +"#"+ name+"#"+age+"#"+address+"\r\n";
//要记得追加写入,否则会替换掉以前内容
FileWriter fw = new FileWriter("stu.txt" ,true);
fw.write(content);
fw.close();
//id自增
ID++;
System.out.println("写入文件成功");
} catch (IOException e) {
e.printStackTrace();
}
return "保存成功";
}
复制代码
- 删除操作
由于我们现在操作的是文本,文本内容是不支持直接删除操作的。我们需要把内容读取出来,然后删除对应的内容,然后拼接再写入文本里面去。
@RequestMapping("/user_delete")
public String delete(String id ){
try {
FileReader fr = new FileReader("stu.txt");
//构建BufferedReader
BufferedReader br = new BufferedReader(fr);
StringBuffer buffer = new StringBuffer();
//读取每一行
String line = null;
while((line = br.readLine()) != null){
//1#zhangsan#18#北京2
String [] contents = line.split("#");
//比较id
if(!id.equals(contents[0])){
//组拼剩下的内容
buffer.append(line).append("\r\n");
}
}
//组拼完毕,再写回去。
FileWriter fw = new FileWriter("stu.txt");
fw.write(buffer.toString());
fw.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return "删除成功";
}
复制代码
- 更新操作
更新操作需要指定更新哪一条数据,并且还要指定更新什么数据。 这些操作在生活中很常见,比如大家更换自己的微信头像、 聊天背景图 、录入数据录入错误,也需要提供更新的操作。咱们操作的还是文件,所以仍然需要读取出来,然后组拼内容,再写回去。
@RequestMapping("/user_update")
public String update(String id , String address ){
try {
FileReader fr = new FileReader("stu.txt");
BufferedReader br = new BufferedReader(fr);
String line = null;
StringBuilder stringBuilder = new StringBuilder();
while((line = br.readLine()) != null){
String [] contents = line.split("#");
//根据id找学生
if(id.equals(contents[0])){
//修改数据
line = line.replace(contents[contents.length-1],address);
}
//修改好了之后,记得拼接以便一会写入文件中。
stringBuilder.append(line + "\r\n");
}
//写回文件
FileWriter fw = new FileWriter("stu.txt");
fw.write(stringBuilder.toString());
fw.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return "更新成功";
}
复制代码
-
查询所有
@RequestMapping("/user_findAll") public String findAll(){ try { File file = new File("stu.txt"); FileReader fr = new FileReader(file); BufferedReader br = new BufferedReader(fr);
String line; while(( line = br.readLine()) !=null){ System.out.println(line); } br.close(); } catch (Exception e) { e.printStackTrace(); } return "查询成功"; 复制代码
}
七、打包部署
- 打jar包
在build.gradle 里面添加这段构建打包配置,即可打出来一个可执行的jar包。
//构建打包的配置
jar {
//遍历依赖,追加到someStirng上
String someString = ''
configurations.runtime.each {someString = someString + " lib//"+it.name}
//指定项目清单
manifest {
attributes 'Main-Class': 'com.itheima.MainApp' //指定启动类
attributes 'Class-Path': someString //指定依赖
}
}
//指定编码类型
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
//拷贝jar ,把依赖都放到build/libs/lib中
task copyJar(type:Copy){
from configurations.runtime
into ('build/libs/lib')
}
//构建一个自定义任务release , dependsOn 表示它依赖两个子任务 build 和 copyJar
task release(dependsOn: [build,copyJar]){
}
复制代码
-
部署云服务器
-
上传jar包到 服务器
-
使用java -jar 运行即可 ,具体可以参照下面的命令
Linux 运行jar包命令如下:
方式一:
java -jar shareniu.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出
那如何让窗口不锁定?
方式二
java -jar shareniu.jar & &代表在后台运行。
特定:当前ssh窗口不被锁定,但是当窗口关闭时,程序中止运行。
继续改进,如何让窗口关闭时,程序仍然运行?
方式三
nohup java -jar shareniu.jar &
nohup 意思是不挂断运行命令,当账户退出或终端关闭时,程序仍然运行
当用 nohup 命令执行作业时,缺省情况下该作业的所有输出被重定向到nohup.out的文件中,除非另外指定了输出文件。
方式四
nohup java -jar shareniu.jar >temp.txt & 解释下 >temp.txt
command >out.file
command >out.file是将command的输出重定向到out.file文件,即输出内容不打印到屏幕上,而是输出到out.file文件中。
可通过jobs命令查看后台运行任务
jobs 那么就会列出所有后台执行的作业,并且每个作业前面都有个编号。 如果想将某个作业调回前台控制,只需要 fg + 编号即可。
fg 23 查看某端口占用的线程的pid
netstat -nlp |grep :9181