2022Fall NJUT
1.Servlet生命周期
加载,实例化,初始化,服务,销毁
其中加载和实例化只有一次,调用init()
Servlet运行过程
- Tomcat主线程对转发来的用户请求做出响应,并创建两个内置对象:HttpServletRequest类的实例request和 HttpServletResponse类的实例response。
- 根据请求中的URL找到正确的Servlet(第一次创建线程,第二次分配线程)同时把创建的两个内置对象传递给该线程。
- Tomcat调用Servlet的service()方法,根据请求类型的不同调用doGet()或者doPost()方法或者其他方法。
- 执行相关do方法,生成静态资源,并把信息组合到响应对象里。
- Servlet线程运行结束,Tomcat将响应对象转换为HTTP响应返回给用户,同时删除请求和响应对象。
2.内置对象技术
-
request对象
将客户端的请求包装在ruquest对象中,作用是 在当次请求中进行数据传递。
作用域:当前请求过程。
-
getParameter()和getAttribute()使用场景有何不同?
两个都是返回指定参数的值;getParameter(String key)获取客户端提交的信息,key和前端表单中元素的name属性一致,即后端接受前端的数据;
getParameterValues() 获得指定参数的组成信息,通常在表单的复选框中使用,
public String[] getParameterValues(String str);
-
getAttribute() 用于前端接受数据
后端用dispatcher方法
RequestDispatcher dispatcher =null;//用于页面迁移 if(!LoginManagement.login(account,sercert)){ request.setAttribute("log","error"); } dispatcher=getServletcContext().getRequestDispatcher("/login.jsp"); dispatcher.forward(request,response);
RequestDispatcher.forward() 方法 运行在服务端 浏览器url地址不变化 一次请求 “/”表示应用程序(项目)的路径。
HttpServletResponse.sendRedirect()方法 运行在客户端 浏览器url地址变化 两次请求 "/"表示根目录的路径。
-
-
response对象
用于封装客户端的请求报文信息,处理服务器对客户端的一些响应。
只存放一个用户的共享数据。每个访问者服务器都设立一个独立的session对象。
生命周期:在第一个JSP页面或Servlet被装载时由服务器自动创建,并在用户退出应用程序时由服务器销毁,完成会话管理。
生命周期结束的情况:客户端关闭浏览器,session过期,调用invalidate方法使session失效。
PrintWriter类的实例
用于在一个Servlet对象初始化时 JSP引擎向他传递信息。
用于异常处理。
page对象指向当前 JSP页面本身,类似this指针。
pageContext对象提供了JSP对页面内所有对象及名字空间的访问,可以访问本页面所在的session, application。
3.JSON
数据在键值对中;
数据由逗号分隔;
花括号保存对象;
方括号保存数组。
形式为{key:value}
- JS环境下的JSON技术
//增加修改
var stu={};
stu.name=David;
stu["id"]="123456";
//取值
var name=stu.name;
var name=stu["name"];
//遍历
for(var value in stu){}
//删除
delete(stu["name"]);
- Java环境下的JSON技术
- JOSN字符串(浏览器到服务器)与Java对象的相互转换功能,即反序列化。
- Java对象转换成 JSON字符串,也就是序列化。发送至前端后,由 JS反序列化为 JS环境下的 JSON对象。
- JS对象数组序列化为JSON字符串,发送至前端后,由JS反序列化。
-
常用的JSON处理工具包
jackson, fastonjson, gjson, JSONLIB
4.异步通信
指发送方发出数据后,不等接收方发回相应,接着发送下一个数据包。
web异步请求的过程:用户通过web异步请求技术发送到客户端后,服务器根据需求将数据传送回客户端,客户端实时生成部分HTML并渲染展示。
同步通信 渲染是在服务器,异步通信是在客户端。
5.Ajax技术
(Asynchronous JavaScript and XML)
由以下几种技术组合而成:
- CSS和XHTML展示页面内容
- DOM模型实现交互和动态显示
- XMLHttpRequest和服务器异步通信
- JavaScript实现绑定和调用
onSUbmit:function(){
var self =this; //回调函数中无法获得this
axios({url:"LoginAJax", method:"post",
data:{name:this.usrname,pass:this.passWord}})
.then(function(response){}) //成功时调用
.catch(function(error){}); //异常时调用
}
- axio()参数
url:值时后台的Servlet
method:post/get(default)
data:值是后台发送的JSON字符串
param:一般用于get,请求的参数自动拼接到url中
-
后端Servlet接收参数
不能用以前常用的request.getParameter(name)方法,因为axios向后台传输的只是HTTP请求/响应报文,并不是键值对。
BufferedReader rd= request.getReader(); String strJSON="",temp; while((temp=rd.readline())!=null){ strJSON=strJSON+temp; } //将JSON字符串转换成JSONObject对象或者JAVA对象 JSONObject obj=JSON.parseObject(strJSON);//转换成JSONObject对象 String name =obj.getString("name");//从JSONObject对象对象中取值 User user=JSON.parseObject(strJSON,User.class);//转换成JAVA对象 ....
-
axio()方法的简化方式
-
axios.get(url,[其他可选项]) —> axios(url,[其他可选项])
-
带一个数据可以放在url中,多个数据get请求用params,post用data
axios.get('/user?ID="12345").then(){}.catch(){} axios.get('/user',{param:{name:"123",pass:"123"}})... axios.post('/user',{data:{name:"123",pass:"123"}})...
-
6.过滤器Filter
用处如下:
- 在HttpServletRequest到达Servlet之前对其进行拦截
- 根据需要检查HttpServletRequest,可修改HttpServletRequest头和数据
- 在HttpServletResponse到达客户端之前对其进行拦截
- 根据需要检查HttpServletResponse,可修改HttpServletResponse头和数据
接口需要实现的方法:
init();
doFilter();
destory();
实例
if(xxx){
chain.doFilter(req,res);
}
用注解进行配置
@WebFilter(filterName="",value="")
生命周期:
- 启动服务器时加载过滤器的实例,并调用init()方法初始化实例
- 每一次请求时都只调用doFilter()进行处理
- 停止服务器时调用destory()销毁实例
7.监听器Listener
监听ServletContext, HttpServlet, ServletRequest 等对象的创建与销毁事件以及这些对象中属性发生改变的事件。
8.Spring
-
POJO(plain Ordinary Java Object)
指的是一个普通的Java类
Spring两个核心功能 :依赖注入(DI)和控制反转(IOC)。
-
Spring IOC
调用者不负责被调用者的实例创建工作,而是由IOC来完成。
<bean id="helloWOrld1" class="Spring.HelloWorld">// id:bean标识 class是bean对象的全类名 <property name="message" value="123456"/> //所代表的类的数据成员或属性 </bean>
AppicationContext context=new ClassPathXmlApplicationContext("springBeans.xml"); HelloWorld obj1=(HelloWorld) context.getbean("helloWorld1"); obj1.setMessage("666");
依赖注入concept
依赖注入(Dependency Injection,简称 DI)是一种软件设计模式,旨在解耦组件之间的依赖关系,使得组件之间更加灵活、可维护、可测试和可重用。
在依赖注入中,一个对象(被依赖对象)不再自己创建或管理所依赖的对象,而是通过构造函数、工厂方法、属性或接口等方式,由另一个对象(注入对象)注入所依赖的对象。这样一来,被依赖对象只需要关心自己的功能实现,而不需要关心它所依赖的对象如何创建和管理。
依赖注入可以带来多个好处,包括:
可测试性:依赖注入能够将所依赖的对象与被依赖的对象解耦,使得测试时能够更加方便地模拟或替换所依赖的对象,从而提高了代码的可测试性。
可维护性:依赖注入能够减少代码之间的耦合度,使得代码更加易于维护和修改,尤其是当需要修改所依赖的对象时,只需要修改注入对象而不需要修改被依赖对象。
可重用性:依赖注入能够使得代码更加通用和可重用,因为被依赖对象不再与特定的实现细节相关联,而是通过接口或抽象类来定义和实现功能
-
XML注入:有set和get方法,没有构造器。
-
构造方法注入:没有set和get,有构造器。
<constructor-arg ref="user">//表明构造器的参数
-
基于注解的依赖注入:配置中增加context:annotation-config
@Autowired:自动组装,在xml中不必说明对象的相互引用关系。
public class UserService{ 1.//注解字段 @AutoWired private UserDao userDao; @Autowired private User user; 2.//注解构造器 @Autowired public UserService(UserDao userdao,User user){ this.userDao=userDao; this.user=user; } 3.//注解get、set @Autowired public void set UserDao(UserDao userdao){this.userDao=userDao;} @Autowired public void set User(User user){this.user=user;} }
其他注解:
@Component:组件
@Controller
@Service
@Repository
9.面向切面编程AOP
是对OOP的补充和完善。
横切代码:分散在各处且与核心功能无关的代码
AOP:将封装好的对象切开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为切面(aspect)
10.SpringMVC框架
- 模型封装了应用程序的数据,通常由POJO组成。
- 视图负责呈现模型数据,并且通常生成客户端浏览器可以解释的HTML输出。
- 控制器负责处理用户请求并构建适当的模型,将其传递给视图呈现出来。
流程:
- HTTP请求
- DispatcherServlet->HandlerMapping寻找处理器
- 调用处理器
- 调用模型处理业务
- 得到处理结果
- 处理视图映射
- 将模型数据传给视图显示
- HTTP响应
注解:
@Controller
用于标记一个类,受IOC容器管理。
<context:conpoent-scan base-package="com.controller">
@RequestMapping
用于定义URL请求和Controller方法之间的映射。即请求和处理请求的控制器方法关联起来。
@RequestParam
作用于控制器方法的参数。
@RequestBody
作用于控制器方法的参数,但接受的是JSON格式的数据。
@ResponseBody
直接通过HttpServletResponse对象获得输出流,像前端页面写回数据,不通过总控制器。作用域控制器类或类中的方法。
@Resource
@Autowired
11.Maven
是一个包含了项目对象模型(POM)的软件项目管理工具,可以通过配置描述信息来管理项目的构建,报告和文档。
12.JDBC
使得Java程序能方便地与数据库交互并处理查询结果。
步骤:
- 注册加载一个数据库驱动程序
- 创建数据库连接
- 创建SQL语句
- 数据库执行SQL语句
- 用户程序处理执行SQL语句的结果
- 关闭连接等资源
应用实例:
public class firstJDBC{
String driver="com.mysql.jdbc.Driver";
String user="root";
String pass="123456";
String url="jdbc:mysql://xxx &characterEncoding=utf-8";
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
try{
Class.forName(driver);
con=DriverManager.getConnection(url,user,pass);
stmt=con.createStatment();
String sql="select * from stu";
rs=stmt.executeQuery(sql);
String name,password,tel;
while(rs.next()){
name=rs.getString(1);
password=rs.getString(2);
tel=rs.getString("tel");
System.out.println(name+" "+ password+" "+ tel);
}
}catch(ClassNotFoundException e){}
catch(SQLException e1){}
finally{}
rs.close();
stmt.close();
con.close();
}
13.Mybatis
def:
是持久层框架,支持自定义SQL,存储过程,高级映射,免除了几乎所有的 JDBC代码 以及设置参数和获取结果集的工作。它可以通过简单的XML或注解将原始类型、接口和 Java POJO配置和映射为数据库中的记录。
ad:
- 简单易学
- 灵活
- 解除了SQL语句与程序代码的耦合
- 提供了Java对象与关系数据库表的映射标签
流程:
- 读取Mybatis的配置文件
- 加载映射文件
- 构建会话工厂
- 创建会话对象
- 启动Exector
- 创建MappedStatement对象
- 输入参数映射
- 输出结果映射
基于SpringBoot的Mybatis的DAO层设计
@Mapper
public interface DAOBookTable{
//采用注解方法,实际上把DAO层与相应的mapper.xml合成了。
@Select("select * from tb_bool where bookID= #{id}")
public Book getBookID(String id);
@Delete("delete from tb_book where bookID= #{id}")
public boolean delBookByBookID(String id);
...
}
14.分页技术
-
将查询结果缓存在HttpSession中或有状态的 Javabean中,翻页时,从缓存中取出一页数据进行显示。
ad:翻页响应快(从内存中读数据)。
dis:用户可能看到过期数据;数据量过大时,第一次遍历耗时长,缓存占用大量内存,效率下降。
con:适用于数据规模不大,并发量不大的项目。
-
每次翻页都查询一次数据库,从结果集中只取出一页数据。
ad:不占用大量内存。
dis:速度慢。
-
每次翻页,只从数据里检索出页面大小的数据块。
ad:速度快。
-
通过数据库的存储技术实现,把分页过程的业务逻辑放在具体数据库中实现
ad:速度最快。
dis:可移植性差,可重用性差。
15.Springboot
控制器前加上注解
@RestController:相当于@Controller + @ResponseBody
Springboot中axios URL最后不需要加后缀名.do
SpringMVC:axios("user/userNameCheck.do?name="+this.UserName)...
Springboot:axios("user/userNameCheck?name="+this.UserName)...
-
默认使用的日志处理工具包中把日志分为哪些等级?
从高至低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL
书本:分为四个等级,从高到低分别是error warn info debug
error:表示发生异常,但程序能正常运行
warn:用来记录警告类信息,表示会出现潜在的错误
info:表示不属于异常但需要记录的内容
debug:一般用于开发阶段,记录程序上下文关键变量的变化
16.开发DAO和MVC四层模式
DAO+Model,View,Controller
MVC(模型、视图、控制器)架构的控制流程为:所有的终端用户请求被发送到控制器,控制器依赖请求去选择加载哪个模型,并把模型附加到对应的视图,附加了模型数据的最终视图作为响应发送给终端用户。
ad:
- 分离了关注点。后台代码被移到单独的类文件,可以最大限度地重复利用代码。
- 自动化UI测试成为可能,因为后台代码移到了.NET类,这让我们更容易进行单元测试和自动化测试。
采用Dao层可以对数据库访问进行封装,避免进行重复性的数据库访问开发操作。同时也降低了维护的成本。