写出web开发中三层架构的包结构
控制层 servelet ,后续会称作controller
业务层 service,主要写业务逻辑
数据访问层dao,后续会称作mapper
其他的包,model(pojo,entry,bean),util,filter...
2 响应正文是什么,如何实现向浏览器展示内容?
在浏览器上显示的内容,就是响应正文
响应对象,获得输出流,向外写数据
PrintWrite out = response.getWrite(); out.write("内容");
3 请求中有中文乱码的解决方案
request.setCharacterEncoding("UTF-8");
4 响应乱码中有乱码的解决方案
resppnse.setContentType("text/html;charset=UTF-8");
5 使用注解开发servlet,替换掉web.xml中【八行代码】的注解是?
@WebServlet("/user")
回顾
上周重点Servlet,servlet是用来接收请求,做出响应.
以后写Servlet项目,都要继承HttpServlet,重写对应的doGet ,doPost
记住接收请求数据的方法:
getParameter()
getParameterValues()
记住流程
-
浏览器发请求,
-
servlet接收请求,
-
将数据传递给service
-
service再传递给dao
-
dao将数据返回给service
-
service将数据返回给servlet
-
servlet做出响应
记住包结构
com.qf.servlet
.service
.service.impl
.dao
.dao.impl
请求转发(重点)
现有问题
-
响应的代码与接收请求代码在一起
-
这也没有遵循单一职责,不便于后期维护
解决
-
将代码拆开
-
请求完之后,再单独设计个Servlet去做出响应
-
这就是请求转发
演示
// 类1
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1 接收请求
// 2 调用业务层查询数据
System.out.println("请求执行LoginServlet.doGet()" );
// 使用请求转发,到另外一个servlet
// RequestDispatcher requestDispatcher = req.getRequestDispatcher("/login/page");
// requestDispatcher.forward(req,resp);//需要携带请发和响应对象
// 常常直接写完整
req.getRequestDispatcher("/login/page").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
// 类2
@WebServlet("/login/page")
public class LoginPageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("请求执行LoginPageServlet.doGet()" );
// 3 做出响应
PrintWriter out = resp.getWriter( );
out.write("<html>");
out.write("<body>");
out.write("<h1>登录成功</h1>");
out.write("</body>");
out.write("</html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
请求域
设计两个Servlet,来读取CookieServlet1设置的cookie
一个叫UserServlet,映射路径/user/ck,读取cookie
一个叫AdminServlet,映射路径/admin/ck,读取cookie
演示1:
CookieServlet1设置的cookie的路径默认是http://localhost/day40/
通过http://localhost/day40/user/ck 能读取到cookie值
通过http://localhost/day40/admin/ck 能读取到cookie值
演示2
CookieServlet1设置的cookie的路径为是==/day40/user==
通过http://localhost/day40/user/ck 能读取到cookie值
通过http://localhost/day40/admin/ck ==能读取不到cookie值==
// 设置cookie路径 cookie.setPath("/day40/user");
总结: cookie设置路径,其实就是设置cookie的读取范围
Session[重点]
// 销毁session session.invalidate();
删除session一般用在注销登录
-
在两个servlet请求转发时,会存在A类的数据需要传递给B类
-
此时就需要使用请求对象的请求域功能
-
req.setAttribute(key,value),这样就可以将数据存储在请求对象
-
再另外一个servlet使用请求对象取出值req.getAttribute("key")
-
特点
-
请求转发地址栏不变,这是一次请求
-
请求转发是服务器内部行为
-
当做域对象使用,即相当于容器,可以转载数据
-
两个servlet中请求域数据在一次
请求转发中共享
重定向
重定向也可以使用Servlet直接的跳转,以及跳转页面.
resp.sendRedirect("路径");
演示:
重定向
重定向也可以使用Servlet直接的跳转,以及跳转页面.
resp.sendRedirect("路径");
演示:
路径问题
请求转发是服务器行为,服务器根路径是项目名,
所以发请求,从/开始,不会丢失项目名
重定向是浏览器行为,浏览器根路径是端口
所以发请求,从/开始,就会丢项目名
// req.getContextPath(); // 获得项目名 ,例如 /day40 resp.sendRedirect(req.getContextPath()+"/redirect2"); // 拼接项目名
回顾上午
请求转发
req.setAttribute(key,value)
req.getRequestDispatcher("路径").forward(req,resp);
req.getAttribute("key")
响应重定向
resp.sendRedirect(req.getContextPath+"/login");
会话技术-状态保存(了解)
某网站,如何记录你的登录状态?
HTTP是无状态
保存会话数据的技术:cookie,session
cookie是浏览器技术
session是服务器技术
Cookie[熟悉]
-
创建
-
响应到浏览器
// 在服务器中 Cookie cookie = new Cookie(key,value); resp.addCookie(cookie)
-
获取cookie
// 从请求中获得cookie.一次获得全部的cookie对象 // 但是一次获得当前站点所有cookie对象,没有获得单独某一个cookie Cookie[] cookies = req.getCookies(); for (int i = 0; cookies != null && i < cookies.length; i++) { Cookie ck = cookies[i]; String name = ck.getName( ); String value = ck.getValue( ); System.out.println(name+"="+value ); }
-
删除cookie
-
没有删除的方法
-
主要靠最大生命值来确定
-
默认保存至会话结束(浏览器关闭)
-
也可以通过在创建时指定生命周期时间
-
setMaxAge
-
大于0,存在指定的秒
-
等于0,直接删除
-
小于0,一般是-1 ,保存至浏览器关闭
-
// 创建cookie Cookie cookie = new Cookie("username","admin");// 中文会乱码 // 创建的cookie,默认存储到浏览器关闭. // 可以设置时间,单位是秒!! // cookie.setMaxAge(30); // cookie.setMaxAge(0); // 直接删除该cookie cookie.setMaxAge(-1); // 保存至浏览器关闭
-
-
设置cookie的路径
-
中文乱码解决
// 中文编码 URLEncoded.encoded("value","UTF-8") // 将乱码解码成中文 URLDecode.decode(value,"UTF-8") // cookie中文解决 // jdk自带有将中文编码和解码的方法 Cookie cookie = new Cookie( URLEncoder.encode("姓名","UTF-8"), URLEncoder.encode("张三","UTF-8"));
for (int i = 0; cookies != null && i < cookies.length; i++) { Cookie ck = cookies[i]; String name = ck.getName( ); String value = ck.getValue( ); // 解码 String u = URLDecoder.decode(name, "UTF-8"); String v = URLDecoder.decode(value, "UTF-8"); System.out.println(u+"="+v ); }
-
是什么
-
会话技术,是将数据保存在服务器
-
session基于cookie
-
浏览器会利用cookie存储一个叫做JSESSIONID的值
-
-
创建
-
存储数据
-
一般用在登录成功后,将用户信息存储到session
-
-
获取数据[重点]
-
请求转发后从另外一个Servlet取值,可以取出session的值
-
重定向后从另外一个Servlet取值,可以取出session的值
-
因为session域是在整个会话有效,只要会话不结束,当前服务器中的请求都可以获得session域的数据
-
-
删除