Day11
1. JavaWeb
-
Web资源的分类
- 静态资源:html,css,js,txt,mp4视频,jpg图片
- 动态资源:jsp页面,Servlet程序
-
常用Web服务器
- Tomcat,Jboss,GlassFish,Resin,WebLogic
-
通过idea集成Tomcat(把idea工程部署到tomcat上)
2. Servlet
-
Servlet:是JavaEE规范之一,是运行在服务器上的一个java小程序,可以接收客户端发送的请求,并响应数据给客户端
-
工作内容
- 在一次前后端交互中,用于处理请求和响应
-
生命周期:
-
public class LoginServlet extends HttpServlet { //1、servlet构造方法 public LoginServlet(){ System.out.println("1、实例创建成功"); } //2、init()初始化 public void init(ServletConfig config) throws ServletException{ System.out.println("2、执行了init()初始化方法"); //获取servlet全局域对象 ServletContext servletContext=config.getServletContext(); System.out.println(servletContext); //获取当前资源别名 String servletName= config.getServletName(); System.out.println("当前servlet资源别名: "+servletName); //获取当前资源的初始化配置 System.out.println("username: "+config.getInitParameter("username")); System.out.println("password: "+config.getInitParameter("password")); Enumeration<String> initParameterNames=config.getInitParameterNames(); System.out.println("-------------------------------------"); while(initParameterNames.hasMoreElements()){ String key = initParameterNames.nextElement(); String value = config.getInitParameter(key); System.out.println(key+" "+value); } } /** * @param request 请求对象 请求客户端传递过来的数据 * @param response 响应对象 在处理完后端逻辑之后根据需求,响应数据给客户端 * @throws ServletException * @throws IOException */ //3、service()方法 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("3、执行service方法,浏览器成功访问到后端资源!"); String method =request.getMethod(); System.out.println("客户端提交的方式为"+method); if(method.equals("GET")){ doGet(request,response); }else if(method.equals("POST")){ doPost(request,response); } } //4、destroy()销毁方法 public void destroy(){ System.out.println("4、执行销毁方法"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("执行了doget方法"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("执行了dopost方法"); } }
-
执行Servlet构造器方法
- 当客户端发送请求时,tomcat容器会解析请求的地址,映射对应的工程路径和资源路径找到具体资源
- 在定位到具体的后端类后,tomcat会创建对应的后端类的实例(调用具体资源的构造方法)
-
执行init()初始化方法,该方法会去加载对应的配置信息
- 域对象:可以像map一样存储数据,以key:value的形式去存储数据,只有在规定作用域内,才能取到数据,比如:session,request,servletContext…都是域对象
- servletContext作用域:全局的,可以在当前工程下任何资源中都可以获取到该对象中的值(**面试题:**重写了init()后,可能会有空指针异常,此时可以在重写的init()里使用super来调用父类的config)
- request是请求对象,也是域对象,可以存数据、取数据,取值范围:一次请求之内
- 域对象:可以像map一样存储数据,以key:value的形式去存储数据,只有在规定作用域内,才能取到数据,比如:session,request,servletContext…都是域对象
-
执行service()方法,根据客户端提交的方式,来进行请求的分发处理
-
在正式开发时,不能把所有的请求响应和对应的业务逻辑放在一个service中,要做一个分发处理,不同的业务逻辑交给不同的方法,才符合八大原则之一
-
客户端提交的方式:
-
get、post
- 都有具体的请求行、请求头
- 前者没有请求体,后者有
- 前者提交数据,原理是将数据拼接在地址上面
- 后者提交数据,原理是将数据封装在请求体中
- 后者能提交的数据大小要大于前者能提交的
- 后者要比前者安全
-
常用响应码:(面试)
- 200:请求成功
- 302:请求重定向
- 404:请求服务器已收到,但是请求的数据不存在(请求地址错误)
- 500:表示服务器已收到请求,但是服务器内部错误(代码错误)
-
现阶段:
-
浏览器直接发起的都是get
-
通过前端html页面表单form将method属性设置为get,属于get
-
通过前端html页面表单form将method属性设置为post,属于post(如下图)
-
-
请求转发:会从一个资源跳转到另一个资源,但是地址不会发生变化(内部资源的跳转,例如下)
-
需求:张三去两个柜台办理业务,先去柜台1拿完章,才能去柜台2办理业务(代码如下)
@WebServlet("/Counter1") public class Counter1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("柜台1"); //getRequestDispatcher()获取请求转发对象,此处请求转发对象为柜台2 RequestDispatcher requestDispatcher= req.getRequestDispatcher("/Counter2"); req.setAttribute("message","章1"); requestDispatcher.forward(req,resp); } }
@WebServlet("/Counter2") public class Counter2 extends HttpServlet { protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ System.out.println("柜台2"); Object message =req.getAttribute("message"); if(message.equals("章1")){ System.out.println("办理成功"); }else{ System.out.println("办理失败"); } } } /* 柜台1 柜台2 办理成功 */
-
-
-
-
执行destroy()销毁方法,当tomcat服务器关闭的时候,对应的servlet就会销毁
-
-
-
HttpServlet常用方法:
-
搭建web工程具体流程:(详情见D:\ProgramFile\typora\搭建工程)
-
创建动态的web工程
-
集成tomcat服务器,将当前工程部署到服务器上面,配置工程路径
-
导入servlet资源(本项目和tomcat都要导入)
-
需要创建对应的servlet资源,然后在配置文件web.xml中注册后端资源(servlet资源)
- xml:用来保存数据,而且这些数据具有自我描述性;可以做为项目或者模块的配置文件;可以做为网络传输数据的格式
- xml:用来保存数据,而且这些数据具有自我描述性;可以做为项目或者模块的配置文件;可以做为网络传输数据的格式
-
通过浏览器访问后端资源:http://localhost:8080/工程路径/资源路径
-
2.1 往客户端回传数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
response.setContentType("text/html;charset=UTF-8"); //统一字符集
PrintWriter writer =response.getWriter();
writer.print("成功"); //写数据到客户端
}
/*
浏览器访问http://localhost:8080/web/HelloServlet1
*/
❤2.2 请求重定向与请求转发(面试)
-
请求转发
-
是服务器行为,即用户向服务器发送了一次http请求,该请求可能会经过多个信息资源处理以后返回给用户,各个信息资源使用请求转发机制互相转发请求,从用户的感官上来看,是感觉不到请求转发的。
-
关键点
- 从第一次发送请求到最后一次发送请求的过程中,web容器只创建一次request和response对象,新的页面继续处理同一个请求。
- 其本质是服务器将request对象在页面之间进行了相互的传递。
- 可以共用request对象信息。
- 服务器内部进行的转发
- 只有一次请求
- 地址栏不会发生变化
- 必须是在同一台服务器下完成
-
//获取请求转发器 RequestDispatcher dispatcher = req.getRequestDispatcher("/myservlet04.do"); //请求转发 dispatcher.forward(req, resp); //例如: request.getRequestDispatcher("/HelloServlet4").forward(request,response);
-
-
请求重定向
-
是客户端行为(客户端跳转)。服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。它本质上是两次HTTP请求,对应两个request对象。
-
关键点
- 有两次请求
- 地址栏会发生改变
- HttpServletRequest不可以在这两次请求中共享数据
- 可以共享context,session域的数据
- 可以在不同服务器下完成
- 状态码变成302
-
response.sendRedirect("http://localhost:8080/web/HelloServlet3");
-
❤2.3 案例1
**需求:**通过客户端发送请求,通过jdbc去查询学生数据,将学生数据封装成学生对象,添加到学生集合里面,然后将集合存放到域对象中,然后请求转发到另外一个资源,然后将学生集合响应在客户端
**注意:**导入mysql驱动jar包时,要放入web的lib下,并且要在tomcat中同样也导入这个包
@WebServlet("/HelloServlet3")
public class HelloServlet3 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
Connection connection =null;
Statement statement =null;
ResultSet result=null;
try {
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2、获取数据库连接对象
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zj1" +
"?serverTimezone=GMT&characterEncoding=utf8", "root", "123");
statement = connection.createStatement();
//sql查
String sql2 = "select name,age from student";
result =statement.executeQuery(sql2);
//创建集合实例
ArrayList<Student> users=new ArrayList<>();
//遍历结果集,并封装进User类
while(result!=null&&result.next()){
String n1=result.getString("name");
int a1=result.getInt("age");
Student user=new Student(n1,a1);
users.add(user);
}
//遍历集合ArrayList:users,并输出
for (Student us:users
) {
System.out.println(us);
}
response.setContentType("text/html;charset=UTF-8");
request.setAttribute("AL",users);
request.getRequestDispatcher("/HelloServlet4").forward(request,response);
//response.getWriter().print(users);
//response.getWriter().print("<br>"); //客户端页面换行
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
//6、关闭数据库资源
try {
if(result!=null) {
result.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
//要做一下判空,否则会报空指针异常,体现程序严谨
if(statement!=null){
statement.close(); //关闭资源statement
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(connection!=null){
connection.close(); //关闭资源connection
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
@WebServlet("/HelloServlet4")
public class HelloServlet4 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
//取出域中的数据
ArrayList<Student> stuList = (ArrayList<Student>)request.getAttribute("AL");
//请求流对象
PrintWriter writer = response.getWriter();
//将集合对象写到客户端
writer.print(stuList);
}
}
3. JSP
-
模板引擎技术
-
实质是一个servlet程序,为了解决动态生成HTML文档的技术
-
为了更高效的渲染数据
-
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%! //声明脚本 String name="Jack"; int age=22; %> <% //for循环 for(int i=0;i<10;i++){ System.out.println(i); } %> <html> <head> <title>网页名</title> </head> <body> //取值脚本 <%=name%> <%=age%> </body> </html>
-
-
jsp的四大域对象
- pageContext:取值范围:当前页面,只能在当前页面才能取到当前域中的值
- request:取值范围:一次请求范围内
- session(会话对象):取值范围:浏览器的开启到关闭
- application(对应的就是servletContext对象):取值范围:整个web工程
-
jsp中el表达式的作用
- el表达式语法:$(域中key的值)
- el表达式在后面开发中替代了取值脚本:<%=具体变量的引用%>
- el表达式功能更加完善,提供了逻辑运算,三目运算符,判空处理等非常好用的语法
<% String name = "jack"; boolean flag = false; int a = 100; int b = 150; ArrayList<String> strings = new ArrayList<>(); strings.add("hello"); strings.add("java"); strings.add("world"); strings.add("html"); HashMap<String, String> hashMap = new HashMap<>(); hashMap.put("k1","v1"); hashMap.put("k2","v2"); hashMap.put("k3","v3"); hashMap.put("k4","v4"); request.setAttribute("name",name); request.setAttribute("flag",flag); request.setAttribute("a",a); request.setAttribute("b",b); request.setAttribute("b",b); request.setAttribute("strings",strings); request.setAttribute("hashMap",hashMap); %> <html> <head> <title>el表达式</title> </head> <body> name : ${name}<br> flag : ${flag}<br> 逻辑运算 : ${a==b}<br> 逻辑运算 : ${a>b}<br> 逻辑运算 : ${a<b}<br> strings : ${strings}<br> strings : ${strings[0]}<br> strings : ${strings[1]}<br> hashMap : ${hashMap}<br> hashMap : ${hashMap.get("k1")}<br> 三目运算符 : ${a > b ? 'a大于b' : 'a小于b'}<br> </body> </html>
-
jstl标签库jar包导入(jstl,taglibs)
实操1:接上面案例1改:
实操2:接上实操1改:
浏览器搜索http://localhost:8080/web/HelloServlet3
❤**实操3:**
在实操2基础上添加网页删除&添加&编辑&姓名模糊查询功能,,其中包括文本框回显,并连接数据库
详情见D:\ProgramFile\projectidea\test
4. cookie
-
在客户端保存数据的一种技术
-
使用方式
- 需要创建cookie对象
Cookie cookie=new Cookie(key,value);
- 通知客户端保存cookie
response.addCookie(cookie);
- 需要创建cookie对象
-
cookie在以后开发中的作用
-
将数据存放在浏览器端
-
i.e. 唯品会购物车功能,当用户将商品放进购物车,实际上该商品并没有保存到后端数据库,而是将数据保存在cookie
-
i.e. 免用户名登陆,下次登陆不用手动输入,从cookie中获取
-
-
封装成cookie工具类
-
5. session
-
在服务端保存数据的技术,是一个会话对象,用来维护客户端和服务端的关系
-
当服务端发送响应给客户端时,都会通过响应头的方式将session对应的会话id传给客户端的cookie(jsonId)
-
session在以后开发中的应用
- 通常在做登录需求时,会将用户信息保存到session中,然后在前端判断session域中有没有用户数据(并不是依据用户密码是否正确来判断),如果有,则就是登陆成功。否则就是登陆失败
❤6. 总结案例:
**需求:**先输入用户名和密码,后端校验是否正确,将用户数据存到session中,客户端校验会话中是否有用户数据,有的话,登陆成功,正常显示列表页面,否则登陆失败(详细代码文件路径:D:\ProgramFile\projectidea\test)