服务器:安装了服务器软件的计算机
服务器软件:接受用户的请求,处理请求,做出响应
web服务器软件:接受用户的请求,处理请求,做出响应
常见的Java相关的web服务器软件
JavaEE:Java语言在企业级开发中使用的技术规范的总和,一共规定了13项大的规范
安装:解压压缩包(安装的目录不要有空格和中文)
卸载:删除目录
启动:
bin/starp.bat,双击运行即可
访问:在浏览器输入 http://localhost:8080 回车访问自己
http://别人的ip:8080 回车访问别人
可能遇到的问题:
运行后的黑窗口一闪而过:
启动报错:
暴力解决方案:找到占用8080对应的进程,杀死该进程
netstat -ano
温柔解决方案:修改自身的端口号(不建议)
打开conf/server.xml文件
修改默认端口号
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
一般会将Tomcat的默认端口号修改为80。80端口号是http协议的默认端口号。
关闭
正常关闭:
强制关闭:(不推荐)
配置
部署项目的方式:
直接将项目放在webapps文件夹下
localhost/hello/hello.html
即可访问/hello
:项目的访问路径--->虚拟目录 一般和资源名称相同hello.html
:资源名称配置conf/server.xml文件(不推荐,很不安全)
<Context docBase="D:\hello" path="/hehe"/>
在conf\Catalina\localhost下创建任意名称的xml文件。在文件中编写
<Context docBase="D:\hello" />
静态项目和动态项目区别
目录结构不同
java动态项目的目录结构:
项目的根目录
WEB-INF目录:
将Tomcat继承到IDEA中,并且创建JavaEE的项目,部署项目(本人使用IDEA 2021 3.3 版本)
IDEA集成Tomcat:
创建JavaEE项目
Servlet即 server applet,运行在服务器端的小程序
servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
将来我们自定义一个类,实现Servlet接口,复写方法
创建JavaEE项目
定义一个类,实现Servlet接口
关于手写类实现Servlet不会导包的问题解决办法:
实现接口中的抽象方法
public class ServletDemo1 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {}
@Override
public ServletConfig getServletConfig() {
return null;
}
//提供服务的方法
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello Servlet");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
配置Servlet
<!--配置Servlet-->
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>com.mark.web.servlet.ServletDemo1</servlet-class>
</servlet><!--映射-->
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping></code></pre></li>
在浏览器中输入http://localhost:8080/demo1 会发现IDEA控制台上输出Hello Servlet
当服务器接收到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
查找web.xml文件,是否有对应的
如果有则再找到对应的
tomcat会将字节码文件加载进内存,且创建其对象
调用其方法
public class ServletDemo2 implements Servlet {
/**
* 初始化方法
* 在Servlet被创建时执行,只执行一次
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init...");
}
/**
* 获取ServletConfig对象
* ServletConfig是Servlet的配置对象
* @return
*/
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 提供服务的方法
* 每一次Servlet被访问时执行,执行多次
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet...");
}
/**
* 获取Servlet的一些信息:版本、作者等等
* @return
*/
@Override
public String getServletInfo() {
return null;
}
/**
* 销毁方法
* 在Servlet被杀死时执行(在服务器正常关闭时执行),只执行一次
*/
@Override
public void destroy() {
System.out.println("destroy...");
}
}
Servlet的生命周期方法:
被创建:执行init方法,只执行一次
默认情况下,第一次被访问时,Servlet被创建
可以指定Servlet的创建时机:修改web.xml配置文件
<servlet>
<servlet-name>demo2</servlet-name>
<servlet-class>com.mark.web.servlet.ServletDemo2</servlet-class>
<!--指定Servlet的创建时机
1.第一次被访问时创建
<load-on-startup>的值为负数(默认值为-1)
2.在服务器启动时创建
<load-on-startup>的值为0或正整数(一般配0-10)
-->
<load-on-startup>5</load-on-startup><!--当服务器启动时加载-->
</servlet>
init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
提供服务:执行service方法,执行多次
被销毁:执行destory方法,只执行一次
Servlet 3.0:
@WebServlet(urlPatterns = "/demo")
@WebServlet("/demo")
引号中直接写资源路径IDEA会为每一个Tomcat部署的项目单独建立一份配置文件
Using CATALINA_BASE: "C:\Users\Mark\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat\2cbcd2b9-3ae3-45b3-b582-c86f8e7e95e4"
工作空间项目 和 tomcat部署的web项目
断点调试:加断点后Debug(小虫子)
Interface Servlet
-----GenericServlet抽象类 实现了Servlet接口
-----HttpServlet抽象类 继承于GenericServlet抽象类
GenericServlet:将Servlet接口中的其他方法做了默认空实现,只将service()作为抽象
将来定义Servlet类时,可以继承GenericServlet,实现service()即可
@WebServlet("/demo2")
public class ServletDemo2 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Demo2...");
}
}
HttpServlet:对HTTP协议的一种封装,可以简化操作。接收数据不再需要在service()中写if-else判断HTTP的方式为get还是post
步骤:
定义类继承HttpServlet
复写doGet()或者doPost()方法
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet...");//默认为get方式
}@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost...");//可以通过表单方式改用post
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="demo3" method="post">
<!--如果配置中Deployment-Application context为/则可以写为/demo3
但是如果为/路径 则只能写demo3,不能加/
-->
<input name="username">
<input type="submit" value="提交">
</form>
</body>
</html>
urlpartten:Servlet的访问路径
一个Servlet可以定义多个访问路径,浏览器可以通过任意一个访问路径访问
@WebServlet({"/d4","/dd4","/demo4"})
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo4...");
}
}
路径定义规则:
/xxx
/xxx/xxx
:多层路径,目录结构
@WebServlet("/user/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo4...");
}
}
@WebServlet("/user/*")//访问时可以通过任意路径访问,/*是访问优先级最低的
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo4...");
}
}
*.do
@WebServlet("*.do")//※不要加/ 访问时通过xxx.do访问 xxx为任意路径
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo4...");
}
}
概念:HTTP即Hyper Text Transfer Protocol,超文本传输协议
特点:
历史版本:
请求行
请求方式 请求url 请求协议/版本
Get /myServlet/login.html HTTP/1.1
HTTP协议有7中请求方式,常用的有两种
GET:
请求参数在请求行中(在URL后):
http://localhost:8080/myServlet/demo3?username=aaa
请求的url长度有限制
不太安全
POST:
请求头:浏览器告诉服务器浏览器自身的一些信息
请求头名称:请求头值
常见的请求头:
User-Agent:浏览器告诉服务器,浏览器访问服务器使用的浏览器版本信息
Referer:告诉服务器,当前请求从哪里来
作用:
请求空行:就是用于分割POST请求的请求头和请求体的
请求体(正文):封装POST请求消息的请求体
字符串格式:
GET /myServlet/login.html HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;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, br
Referer: http://localhost:8080/myServlet/login.html
Connection: keep-alive
Cookie: JSESSIONID=7AAA4903DCD0183D7F0A8ECD445090E1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
request和response对象的原理
ServletRequest --- 接口
获取请求行数据
Get /myServlet/demo1?name=zhangsan HTTP/1.1
方法:
获取请求方式:GET
String getMethod()
获取虚拟目录:/myServlet
String getContextPath()
获取Servlet路径:/demo1
String getServletPath
()
获取get方式的请求参数:?name=zhangsan
String getQueryString()
获取请求URI:/myServlet/demo1
String getRequestURI()
String getRequestURL()
: 返回 http://myServlet/demo1
获取协议以及版本:HTTP/1.1
String getProtocol()
获取客户机的IP地址
String getRemoteAddr()
public class RequestDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求方式:GET
String method = request.getMethod();
System.out.println(method);
//获取虚拟目录:/myServlet
String contextPath = request.getContextPath();
System.out.println(contextPath);
//获取Servlet路径:/demo1
String servletPath = request.getServletPath();
System.out.println(servletPath);
//获取get方式的请求参数:?name=zhangsan
String queryString = request.getQueryString();
System.out.println(queryString);
//获取请求URI:/myServlet/demo1
String requestURI = request.getRequestURI();
System.out.println(requestURI);
StringBuffer requestURL = request.getRequestURL();
System.out.println(requestURL);
//获取协议以及版本:HTTP/1.1
String protocol = request.getProtocol();
System.out.println(protocol);
//获取客户机的IP地址
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
}
}
获取请求头数据
方法:
String getHeader(String name)
:通过请求头的名称获取请求头的值
Enumeration getHeaderNames()
:获取所有的请求头名称
@WebServlet("/RequestDemo2")
public class RequestDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取所有请求头名称
Enumeration
//遍历
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
//根据名称获取请求头名称
String value = request.getHeader(name);
System.out.println(name+"--"+value);
}
}
}
host--localhost:8080
user-agent--Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0
accept--text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/
*;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, br
connection--keep-alive
cookie--JSESSIONID=324F172A257FA6B8DF4869314F01E64B; Webstorm-ec1c0726=62f9d3ca-a2fa-4d36-aef6-9086650fec79
upgrade-insecure-requests--1
sec-fetch-dest--document
sec-fetch-mode--navigate
sec-fetch-site--none
sec-fetch-user--?1
@WebServlet("/RequestDemo3")
public class RequestDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求头数据:user-agent
String agent = request.getHeader("user-agent");
//判断agent的浏览器版本
if (agent.contains("Chrome")) {
System.out.println("谷歌");
} else if (agent.contains("Firefox")) {
System.out.println("火狐");
}
}
}
@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求头数据:referer
String referer = request.getHeader("referer");
System.out.println(referer);//http://localhost:8080/myServlet/login.html //防盗链
if (referer != null) {
if (referer.contains("/myServlet")) {
// System.out.println("正常访问");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("正常访问");
} else {
// System.out.println("你进不去哦");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("你进不去哦");
}
}
}
}
获取请求体数据
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
步骤:
获取流对象
BufferReader getReader()
:获取字符输入流,只能操作字符数据ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据再从流对象中拿数据
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求消息体
//1. 获取字符流
BufferedReader br = request.getReader();
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
username=aaa&password=ddd
获取请求参数通用方式
String getParameter(String name)
:根据参数名称来获取参数值 username=aaa&password=ddd
@WebServlet("/RequestDemo6")
public class RequestDemo6 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("get");
System.out.println(username);
}@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// String username = request.getParameter("username");
// System.out.println("post");
// System.out.println(username);
this.doGet(request,response);//执行doGet的代码逻辑,节省代码重复
}
}
<form action="/myServlet/RequestDemo6" method="post">
<input type="text" name="username" placeholder="username"><br>
<input type="text" name="password" placeholder="password"><br>
<input type="submit" value="注册">
</form>
String[] getParameterValues(String name)
:根据参数名称来获取参数值的数组 hobby=xx&hobby=game
@WebServlet("/RequestDemo6")
public class RequestDemo6 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String[] hobbies = request.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
}
}
<form action="/myServlet/RequestDemo6" method="get">
<input type="text" name="username" placeholder="username"><br>
<input type="text" name="password" placeholder="password"><br>
<input type="checkbox" name="hobby" value="game">游戏
<input type="checkbox" name="hobby" value="study">学习<br>
<input type="submit" value="注册">
</form>
Enumeration getParameterNames()
:获取所有请求参数的名称
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
System.out.println(name);
String value = request.getParameter(name);
System.out.println(value);
System.out.println("----");
}
Map<String,String[]> getParameterMap()
:获取所有参数的map集合
Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> keyset = parameterMap.keySet();
for (String name : keyset) {
//根据key键获取值
String[] values = parameterMap.get(name);
System.out.println(name);
for (String value : values) {
System.out.println(value);
}
System.out.println("---------");
}
中文乱码问题
get方式:tomcat8已经将get方式乱码问题解决
post方式:会乱码
解决方式:获取参数前设置request编码
request.setCharacterEncoding("utf-8");
请求转发:一种在服务器内部的资源跳转方式
步骤:
通过request对象来获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo8被访问");
//转发到demo9资源
// RequestDispatcher requestDispatcher = request.getRequestDispatcher("/RequestDemo9");
// requestDispatcher.forward(request,response);
request.getRequestDispatcher("/RequestDemo9").forward(request,response);
}
特点:
共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
void setAttribute(String name,Object obj)
:存储数据
Object getAttribyte(String name)
:通过键获取值
removeAttribute(String name)
:通过键移除键值对
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo8被访问");
//存储数据
request.setAttribute("msg","hello");
//转发到demo9资源
request.getRequestDispatcher("/RequestDemo9").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo9被访问");
//获取数据
Object msg = request.getAttribute("msg");
System.out.println(msg);
}
获取ServletContext动态获取虚拟目录
ServletContext getServletContext()
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
System.out.println(servletContext);
//org.apache.catalina.core.ApplicationContextFacade@5e3dfad6
}
1.编写login.html登录页面
username & password 两个输入框
2.使用Druid数据库连接池技术,操作mysql,day14数据库中user表
3.使用JdbcTemplate技术封装JDBC
4.登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您
5.登录失败跳转到FailServlet展示:登录失败,用户名或密码错误
创建项目,导入HTML页面,配置文件、jar包
创建数据库环境
CREATE DATABASE Login;
USE Login;
CREATE TABLE USER(
id INT PRIMARY KEY auto_increment,
username VARCHAR(32) UNIQUE NOT NULL,
password VARCHAR(32) NOT NULL
);
创建包com.mark.domain,创建类User
package com.mark.domain;
/**
- @ClassName User
- @Description TODO 用户的JavaBean(实体类)
- @Author Mark
- @Date 2022/7/31 20:44
- @Version 1.0
*/
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
创建包com.mark.dao,创建类UserDao,提供login()方法
package com.mark.dao;
import com.mark.domain.User;
import com.mark.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @ClassName UserDao
* @Description TODO 操纵数据库中User表的类
* @Author Mark
* @Date 2022/7/31 20:48
* @Version 1.0
*/
public class UserDao {//声明JDBCTemplate对象共用
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 登陆方法
* @param loginUser 只有用户名和密码
* @return User包含用户全部数据, 没有查询到,返回null
*/
public User login(User loginUser) {
try {
String sql = "select * from user where username=? and password = ?";
User user = template.queryForObject(sql,
new BeanPropertyRowMapper<User>(User.class),
loginUser.getUsername(), loginUser.getPassword());
return user;
} catch (DataAccessException e) {
e.printStackTrace();//记录日志
return null;
}
}
}
编写com.mark.web.servlet.LoginServlet类
login.html中form表单的action路径的写法:
package com.mark.web.servlet;
import com.mark.dao.UserDao;
import com.mark.domain.User;
import javax.servlet.;
import javax.servlet.http.;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
User loginUser = new User();
loginUser.setUsername(username);
loginUser.setPassword(password);
UserDao dao = new UserDao();
User user = dao.login(loginUser);
if (user == null) {
//登陆失败
request.getRequestDispatcher("/FailServlet").forward(request, response);
} else {
//登陆成功
request.setAttribute("user", user);
request.getRequestDispatcher("/SuccessServlet").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
package com.mark.web.servlet;
import javax.servlet.;
import javax.servlet.http.;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/FailServlet")
public class FailServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//给页面写一句话
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("登录失败,用户名或密码错误");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
package com.mark.web.servlet;
import com.mark.domain.User;
import javax.servlet.;
import javax.servlet.http.;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/SuccessServlet")
public class SuccessServlet extends HttpServlet {
@Override
protected void doGet(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() + ",欢迎您");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
完成(简化)数据的封装,用于封装JavaBean
request.setCharacterEncoding("utf-8");
// String username = request.getParameter("username");
// String password = request.getParameter("password");
// User loginUser = new User();
// loginUser.setUsername(username);
// loginUser.setPassword(password);
//获取所有请求参数
Map<String, String[]> parameterMap = request.getParameterMap();
//创建User对象
User loginUser= new User();
//使用BeanUtils封装
try {
BeanUtils.populate(loginUser,parameterMap);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
JavaBean:标准的Java类,一般放在domain包里
要求:
功能:封装数据
概念:
成员变量
属性:setter和getter方法截取后的产物。
例如:getUsername() ---> Username --->username
大多数时候和成员变量一样,少数情况不一样
private String gender;
public void setHehe(String gender) {
this.gender = gender;
}
方法:
setProperty():设置属性值
@Test
public void test(){
User user = new User();try {
BeanUtils.setProperty(user,"username","张三");
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(user);
}
getProperty():获取属性值
String username = null;
try {
username = BeanUtils.getProperty(user, "username");
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
populate():封装
数据格式:
响应行
组成:协议/版本 响应状态码 状态码 描述
响应状态码:服务器告诉客户浏览器本次请求和响应的一个状态
状态码都是3位数字
分类:
1xx:服务器接收客户端消息但没有接收完成,等待一段时间后,发送1xx状态码
2xx:成功
3xx:重定向。代表:302(重定向)、304(访问缓存)
4xx:客户端错误。
代表:
5xx:服务器端错误。代表:500(服务器内部出现异常)
响应头
格式:头名称 : 值
常见的响应头::
Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
Content-disposition:服务器告诉客户端以什么格式打开响应体数据
值:
响应空行
响应体:传输的数据
响应字符串格式
HTTP/1.1 200 OK
Bdpagetype: 1
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Date: Mon, 01 Aug 2022 04:36:04 GMT
Server: BWS/1.1
<html>
<head>
<title>$Title$</title>
</head>
<body>
hello,Response
</body>
</html>
设置响应消息
设置响应行
setStatus(int sc)
设置响应头
setHeader(String name, String value)
设置响应体
使用步骤:
获取输出流
PrintWriter getWriter()
ServletOutputStream getOutputStream()
使用输出流,将数据输出到客户端浏览器
重定向:资源跳转的方式
@WebServlet("/ResponseDemo1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Demo1...");
//访问ResponseDemo1会自动跳转到ResponseDemo2 /*
//1.设置状态码为302
response.setStatus(302);
//设置响应头location
response.setHeader("location","/myServlet/ResponseDemo2");
*/
//简单的重定向
response.sendRedirect("/myServlet/ResponseDemo2");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
重定向特点:redirect
路径写法:
路径的分类:
相对路径:通过相对路径不可以确定唯一资源
规则:找到当前资源和目标资源之间的相对位置关系
绝对路径:通过绝对路径可以确定唯一资源
规则:判断定义的路径是给谁用的?判断请求将来从哪发出
给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
request.getContextPath()
给服务器使用:不需要加虚拟目录
动态获取虚拟目录:
//动态获取虚拟目录
String contextPath = request.getContextPath();
//简单的重定向
response.sendRedirect(contextPath+"/ResponseDemo2");
步骤:
获取字符输出流
输出数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取字符输出流
PrintWriter pw = response.getWriter();
//输出数据
//pw.write("hello response");
pw.write("<h1>hello response</h1>");
}
中文乱码问题:编解码使用的字符集不一致。客户端浏览器于电脑一致:使用GBK2312,而tomcat使用ISO-8859-1
request.setCharacterEncoding("GBK");
获取流对象之前设置流的默认编码。
告诉浏览器,服务器发送的消息体数据的编码,建议浏览器使用该编码解码
response.setHeader("content-type", "text/html;charset=utf-8");
简单形式:response.setContentType("text/html;charset=utf-8");
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("content-type", "text/html;charset=utf-8");
//获取字节输出流
ServletOutputStream sos = response.getOutputStream();
//输出数据
sos.write("hello".getBytes());
}
本质:图片
目的:防止恶意表单注册
package com.mark.web.response;
import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/CheckCodeServlet")
public class CheckCodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建一个对象,在内存中代表图片(验证码图片对象)
int width = 100;
int height = 50;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
//美化图片
//填充背景色
Graphics g = image.getGraphics();//画笔对象
g.setColor(Color.PINK);//设置画笔颜色
g.fillRect(0, 0, width, height);//填充颜色
//画边框
g.setColor(Color.BLUE);
g.drawRect(0, 0, width - 1, height - 1);
//写验证码
String str = "QWERTYUIOPASDGFHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789";
//生成随机角标
Random random = new Random();
for (int i = 1; i <= 4; i++) {
int index = random.nextInt(str.length());
//获取字符
char ch = str.charAt(index);
g.drawString(ch + "", width / 5 * i, height / 2);
} //干扰线
g.setColor(Color.GREEN);
for (int i = 1; i < 10; i++) {
//随机生成坐标点
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
g.drawLine(x1, y1, x2, y2);
}
//将图片输出到页面展示
ImageIO.write(image, "jpg", response.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title><script>
/* 点击超链接或者图片,换一张
1.给超链接和图片绑定单击事件
2.重新设置src的属性值
*/
window.onload=function () {
//获取图片对象
var img = document.getElementById("checkCode");
//绑定单击事件
img.onclick=function () {
//加时间戳
var date = new Date().getTime();
img.src="/myServlet/CheckCodeServlet?"+date;
}
}
</script>
</head>
<body>
<img id="checkCode" src="/myServlet/CheckCodeServlet"/>
<a id="change" href="">看不清,换一张</a>
</body>
</html>
概念:代表整个web应用,可以和程序的容器(服务器)来通信
功能:
通过request对象获取
request.getServletContext();
通过HttpServlet获取:this.getServletContext();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.通过request对象获取
ServletContext context1 = request.getServletContext();
//2.通过HttpServlet获取
ServletContext context2 = this.getServletContext();
System.out.println(context1);
System.out.println(context2);
System.out.println(context1==context2);
/*
org.apache.catalina.core.ApplicationContextFacade@483e3ce3
org.apache.catalina.core.ApplicationContextFacade@483e3ce3
true
*/
}
获取MIME类型:
MIME类型:在互联网通信过程中定义的一种文件数据类型标准
获取:String getMimeType(String file)
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//定义文件名称
String filename="a.jpg";
//获取MIME类型
String mimeType = context.getMimeType(filename);
System.out.println(mimeType);//image/jpeg
}
域对象:共享数据
setAttribute(String name,Object value)
getAttribute(String name)
removeAttribute(String name)
ServletContext对象的范围:所有用户所有请求的数据
@WebServlet("/ServletContextDemo3")
public class ServletContextDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = this.getServletContext();
context.setAttribute("msg","haha");
}@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = this.getServletContext();
Object msg = context.getAttribute("msg");
System.out.println(msg);
}
获取文件真实(服务器)路径
方法:String getRealPath(String path)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//获取文件的服务器路径
String realPath = context.getRealPath("/b.txt");//web目录下资源访问
//File file = new File(realPath);
System.out.println(realPath);
//D:\Code\IJavaMyJavaWeb\out\artifacts\myServlet_war_exploded\b.txt
String realPath1 = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println(realPath1);
//D:\Code\IJavaMyJavaWeb\out\artifacts\myServlet_war_exploded\WEB-INF\c.txt
String realPath2 = context.getRealPath("/WEB-INF/clsses/a.txt");//src目录下的资源路径
System.out.println(realPath2);
//D:\Code\IJavaMyJavaWeb\out\artifacts\myServlet_war_exploded\WEB-INF\clsses\a.txt
}
文件下载需求:
分析:
content-disposition:attachment;filename=xx;
步骤:
定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
定义Servlet
获取文件名称
使用字节输入流加载文件进内存
指定response的响应头content-diposition:attachment;filename=xx;
将数据写出到response输出流
<a href="/myServlet/img/1.mp4">视频1</a>
<hr>
<a href="/myServlet/DownloadServlet?filename=1.jpg">图片2</a>
<a href="/myServlet/DownloadServlet?filename=1.mp4">视频2</a>
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取请求参数、文件名称
String filename = request.getParameter("filename");
//使用字节输入流加载文件进内存
//找到文件服务器路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename);
//用字节流关联
FileInputStream fis = new FileInputStream(realPath);
//设置response的响应头
//设置响应头类型content-type
String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
response.setHeader("content-type", mimeType);
//设置响应头打开方式content-disposition
response.setHeader("content-disposition", "attachment;filename" + filename);
//将输入流的数据写出到输出流中
ServletOutputStream sos = response.getOutputStream();
byte[] buff = new byte[1024 * 8];
int len = 0;
while ((len = fis.read(buff)) != -1) {
sos.write(buff, 0, len);
}
fis.close();
}
中文文件名问题:
解决思路:
//解决中文文件名问题
//获取user-agent请求头
String agent = request.getHeader("user-agent");
//使用工具类方法编码文件名
filename = DownloadUtils.getFileName(agent,filename);
手机扫一扫
移动阅读更方便
你可能感兴趣的文章