黑马程序员技术交流社区
标题: 【成都校区】java web第二阶段 [打印本页]
作者: 慢慢慢时光 时间: 2019-3-28 13:40
标题: 【成都校区】java web第二阶段
学习目标1. Tomcat & Servlet2. cookie& session3. EL && JSTL能够说出el表达式的作用
能够使用el表达式获取javabean的属性
能够使用jstl标签库的if标签
能够使用jstl标签库的foreach标签
5. filter & listener能够说出过滤器的作用
能够编写过滤器
能够说出过滤器声明周期相关方法
能够根据过滤路径判断指定的过滤器是否起作用
能够理解什么是过滤器链
能够完成filter完成用户登录验证案例
能够理解动态代理对类的方法进行增强
能够了解listener概念
day13 Tomcat&Servlet1. web服务器软件1. 服务器安装了服务器软件的计算机
2. 服务器软件接收用户的请求,处理请求,做出响应
web服务器软件:接收用户的请求,处理请求,做出响应
3. 常见java相关的web软件4. javaEE:java语言在企业级开发中使用的技术规范的综合,一共规定了13项大的规范。
2. Tomcat1. 安装卸载相关启动可能遇到的问题:
黑窗口一闪而过:
原因:没有正确配置JAVA_HOME环境变量,或者CATALINA_HOME之类的环境变量错误
解决方案:正确配置JAVA_HOME环境变量,或者在CMD命令行启动,会报相应的错
或者编辑 startup.bat,在末尾加一个pause
启动报错
2. 配置 部署项目的方式直接将项目放到webapps目录下(使用的较多,方便,针对小项目)
配置conf/server.xml文件(强烈不建议使用)
在<Host>标签体中配置 <Context docBase="D:/hello" path="/hehe" />
docBase 项目存放的位置,path虚拟目录
热部署在conf/Catalina\localhost创建任意名称的xml文件,在文件中编写
<Context docBase="D:\hello">
3. 静态项目和动态项目1. java动态项目的目录结构-- 项目的根目录
-- WEB-INF目录
-- web.xml:web项目的核心配置文件
-- classes目录: 放置字节码文件的目录
-- lib目录: 放置依赖的jar包
2. Tomcat 集成到idea集成到idea,常见javaEE的项目,部署项目
热部署,如何集成到idea
3. Servlet1. 概念:运行在服务器端的小程序
servlet就是一个接口,定义了java类被浏览器访问到(tomcat识别)的规则
一个Java类,要想被浏览器访问到(Tomcat识别到),必须实现servlet接口
我们自己定义一个类,实现Servlet接口,复写方法
2. 快速入门3. 执行原理当服务器接收到客户端浏览器的请求后,会解析请求url路径,获取访问的servlet的资源路径
查找web.xml文件,是否有对应的<url-pattern>标签体内容
如果有,则再找对应的<servlet-class>全类名
Tomcat会将字节码文件加载进内存Class.forName("全类名"),并且创建其对象cls.newInstance()
调用service方法
4. servlet的生命周期1. 被创建执行init方法,只执行一次
servlet什么时候被创建?
默认情况,第一次被访问时,创建
可以配置指定servlet的创建时机
指定servlet的创建时机
servlet的init方法,只执行一次,说明一个servlet在内存中只存在一个对象,servlet是单例的
2. 提供服务执行service方法,执行多次
3. 被销毁执行destroy方法,只执行一次
只有服务器正常关闭时,才会执行,一般用于释放资源
5. servlet3.0好处:支持注解配置,可以不需要web.xml
步骤:
6. IDEA与Tomcat的相关配置7. servlet相关配置urlpattern: servlet访问路径
一个servlet可以定义多个访问路径:@WebServlet({"/d4","/dd4","/ddd4"})
路径定义规则:
优先级: 绝对匹配 /xxx > /* > *.do
file://C:/Users/Lenovo/Desktop/java%E5%9F%BA%E7%A1%80%E5%BF%85%E8%83%8C%E7%9F%A5%E8%AF%86%E7%82%B9/img/url_pattern.png?lastModify=1553751539
servlet的体系结构genericServlet类:将servlet接口中其他方法做了默认空实现,只将service()方法作为抽象
将来定义servlet类时,可以继承GenericServlet,实现service()方法即可
HttpServlet: 对http协议的封装,简化操作
Ctrl+H 查看继承
GenericServlet类:
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();//调用init()方法,将init()方法里的方法体内容输出
}
public void init() throws ServletException {
}
Servlet接口:
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
public abstract class HttpServlet extends GenericServlet
为什么GenericServlet重写了Servlet的init方法后,自己又写了个空参的init()方法day14-18 HTTP1. 概念Hyper Text Transfer Protocol超文本传输协议
传输协议:定义了客户端和服务器端通信时,发送数据的格式
特点:
基于TCP/IP的高级协议
默认端口:80
基于请求/响应模型的:一次请求对应一次响应
无状态的:每次请求之间相互独立,不能交互数据
历史版本
1.0:每一次请求都会响应都会建立新的连接
1.1:复用连接
发展史:
在java开发中不管用线程,数据库,网路请求,建立的连接,都是宝贵的,不要随意乱用和浪费
2. request1. request消息数据格式file://C:/Users/Lenovo/Desktop/java%E5%9F%BA%E7%A1%80%E5%BF%85%E8%83%8C%E7%9F%A5%E8%AF%86%E7%82%B9/img/%E5%9B%BE%E4%B8%80%20HTTP%E5%8D%8F%E8%AE%AE%E7%9A%84%E8%AF%B7%E6%B1%82%E9%83%A8%E5%88%86.bmp?lastModify=1553751539
1. 请求行请求方式 请求url 请求协议/版本
GET /login.html HTTP/1.1
2. 请求头客户端浏览器告诉服务器一些信息
请求头名称:请求头值
常见的请求头:
3. 请求空行空行,分隔post请求头和请求体
4. 请求体(正文)封装POST请求消息的请求参数的
字符串格式
POST /login.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 12. request对象1. request对象和response对象的原理Tomcat服务器会根据请求url中的资源路径,创建对应的servletDemo1的对象
Tomcat服务器,会创建request和response对象,request对象中封装请求消息数据
Tomcat将request和response对象传递给service方法,并且调用service方法
程序员,可以通过request对象获取请求消息数据,通过response对象设置响应消息数据
服务器再给浏览器做出响应之前,会从response对象中拿程序员设置的响应消息数据
2. request对象的继承体系结构
ServletRequest --接口
|
HttpServletRequest -- 接口
|
org.apache.catalina.connector.RequestFacade类实现
3. request功能1. 获取请求行消息数据获取请求行数据 GET /day14/demo1?name=zhangsan HTTP/1.1
获取请求方式 GET String getMethod()
获取虚拟目录 /day14 String getContextPath()
获取Servlet路径 /demo1 String getServletPath()
获取get方式请求参数 name=zhangsan String getQueryString()
获取请求URI: /day14/demo1
获取协议及版本:HTTP/1.1 String getProtocol
获取客户机的IP地址: String getRemoteAddr()
2. 获取请求头数据方法:
3. 获取请求体数据请求体:只有post请求方式,才有请求体,在请求体中封装post请求的请求参数
步骤:
4. 其他功能4.1获取请求参数通用方式String getParameter(String name) 根据参数名称获取参数值
String[] getParameterValues(String name) 根据参数名称获取参数值的数组,常见复选框
Enumeration<String> getParameterNames() 获取所有请求的参数名称
Map<String, String[]> getParameterMap() 获取所有参数的map集合
4.2 请求转发一种在服务器内部的资源跳转方式
请求次数:代表的是浏览器到服务器端的次数,不包含服务器内部跳转
步骤:
通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
特点:
浏览器地址栏路径不发生变化
只能转发到当前服务器内部资源中
转发是一次请求
4.3 共享数据4.4 获取ServletContext3. request案例1. 用户登录案例需求:
1.编写login.html登录页面
username & password 两个输入框
2.使用Druid数据库连接池技术,操作mysql,day14数据库中user表
3.使用JdbcTemplate技术封装JDBC
4.登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您
5.登录失败跳转到FailServlet展示:登录失败,用户名或密码错误
2. 分析file://C:/Users/Lenovo/Desktop/java%E5%9F%BA%E7%A1%80%E5%BF%85%E8%83%8C%E7%9F%A5%E8%AF%86%E7%82%B9/img/%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90.png?lastModify=1553751539
3. 开发步骤创建项目,导入HTML项目,配置文件,jar包
创建数据库环境
CREATE DATABASE day14;
USE day14;
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(32) UNIQUE NOT NULL,
PASSWORD VARCHAR(32) NOT NULL
);创建包cn.itcast.domain创建类User
创建包cn.itcast.dao 创建类UserDao 操作数据库,提供login的方法
创建工具吧con.itcast.util创建JDBCUtils工具类,使用Druid连接池,获取连接池对象和连接对象
public class JDBCUtils {
private static DataSource ds;
static {
try {
// 加载配置文件
Properties pro = new Properties();
InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(in);
// 初始化连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接池对象
public static DataSource getDataSource(){
return ds;
}
// 获取连接connection对象
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}完善UserDao的方法
public class UserDao {
// 声明JDBCTemplate对象共用
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 登录方法
* @param loginUser 只有用户名和密码
* @return user包含用户全部数据,没有,返回null值
*/
public User login(User loginUser){
try {
// 1. 编写SQL
String sql = "select * from user where username = ? and password = ?";
// 2. 调用query方法
User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), loginUser.getUsername(), loginUser.getPassword());
return user;
} catch (DataAccessException e) {
e.printStackTrace();//记录日志
return null;
}
} }
7. 测试方法,看Dao代码运行是否正常,创建包`cn.itcast.test`,测试类`UserDaoTest`
```java
public class UserDaoTest {
@Test
public void testLogin(){
// 创建登录用户对象
User loginUser = new User();
loginUser.setUsername("superbaby");
loginUser.setPassword("123111");
// 查看数据库是否有该对象
UserDao dao = new UserDao();
User user = dao.login(loginUser);
System.out.println(user);
}
} 发现问题,如果用户名密码不一致,会出现异常,不应该抛出异常,应该返回null,用try/catch包裹(ctrl+alt+t)
@WebServlet("/successServlet") public class SuccessServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取request域中共享的user对象
User user =(User) request.getAttribute("user");
if (user!=null) {
// 给页面写一句话
// 设置编码
response.setContentType("text/html;charset=utf-8");
// 输出
response.getWriter().write("登录成功,"+user.getUsername()+"欢迎您!");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
} }
### 4. 错误日志
问题:登录后跳转找不到网页,转不到loginServlet的页面
解决方法:部署的问题,在idea该项目的部署中,将虚拟目录改为`/day14_test`,之前误改为`/day14`
### 5. 优化
使用Apache的BeanUtils包封装loginUser对象,修改部分如下
```java
/*// 获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
// 封装user对象
User loginUser = new User();
loginUser.setUsername(username);
loginUser.setPassword(password);*/
// 2. 获取所有请求参数
Map<String, String[]> map = request.getParameterMap();
// 3. 创建User对象
User loginUser = new User();
// 3.2 使用BeanUtils封装
try {
BeanUtils.populate(loginUser,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}6. BeanUtils工具类简化数据封装,用于封装JavaBean,原理:内省机制
1. J
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |