http://localhost.9999 表示 浏览器向localhost(127.0.0.1 表示本机)的9999端口发出请求
public class MyTomcat {
public static void main(String[] args) throws IOException {
//1.服务器在9999端口监听
ServerSocket serverSocket = new ServerSocket(9999);
//永远都不可能关闭, 一直监听
while (!serverSocket.isClosed()) {
System.out.println("web服务 在9999端口监听");
//2.等待客户端/浏览器地址栏的连接
Socket socket = serverSocket.accept();
//3.通过socket得到输出流
OutputStream outputStream = socket.getOutputStream();
BufferedReader bufferedReader =
new BufferedReader(new FileReader("src/hello.html"));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
// 返回给浏览器/客户端
outputStream.write(line.getBytes());
}
//4.关闭流
outputStream.close();
socket.close();
}
serverSocket.close();
}
}
双击startup.bat文件,出现一个小黑窗口就没有了,原因是没有配置JAVA_HOME环境变量,
- JAVA_HOME必须大写
- JAVA_HOME中必须有下划线
- JAVA_HOME配置的路径指定到jdk的安装目录即可,不必指定到bin目录下
- Tomcat是Java程序,会根据JAVA_HOME使用指定jdk, 所以一定要配置JAVA_HOME
- 如果其它服务程序占用了8080端口, Tomcat同样启动不了, 或者修改Tomcat服务的默认端口
conf目录
logs目录
webapps目录
JavaWeb程序应用工程目录结构
部署方式一
- 将web工程的目录拷贝到Tomcat的webapps目录下
- 浏览器输入http://ip[域名]:port/子目录…/web资源
部署方式二: 通过配置文件来部署
- 在Tomcat的conf目录/Catalina/localhost/下配置文件
test.xml文件名最好和path="/test"保持一致
访问http://ip[域名]:port/test/hello.html就相当于
访问D:\zzw目录下的hello.html
作用: 可以把一个Web应用,映射到指定的目录,用来解决磁盘空间分配的问题ROOT工程的访问
- 在浏览器地址栏输入 :http://ip[域名]:port, 不加Web工程名/应用名时,访问的是ROOT工程
- 在浏览器地址栏输入 :http://ip[域名]:port/工程名/, 不加资源名时, 默认访问index.jsp; 比如:http://localhost:8080/test
修改hosts文件, 先复制一份到别处,修改之后再覆盖
http://localhost, 默认是访问80端口, 即http://localhost:80
文档JavaWeb学习资料\资料\Tomcat\IDEA2020.2中开发JavaWeb工程.docx
3. 这里修改端口只会影响到当前项目的tomcat端口,而不会去修改server.xml
4. 当Tomcat启动时, 会生成out目录, 该目录就是原项目资源的映射, 我们浏览器访问的资源就是out目录中的web资源
package com.zzw.servlet;
import javax.servlet.*;
import java.io.IOException;
/**
* @author 赵志伟
* @version 1.0
* 1.开发一个Servlet需要实现Servlet接口
* 2.实现Servlet接口的五个方法
*/
@SuppressWarnings({"all"})
public class HelloServlet implements Servlet {
private int count;
/**
* 1.初始化 servlet
* 2.当创建HelloServlet实例时, 会调用init方法
* 3.该方法只会被调用一次
*
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init() 被调用");
}
/**
* 返回ServletConfig 也就是返回Servlet的配置
*
* @return
*/
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 1.service方法处理浏览器的请求(包括get和post)
* 2.当浏览器每次请求Servlet时,就会调用一次service方法
* 3.当tomcat调用该方法时,会把http请求的数据封装成实现了ServletRequest接口的request对象
* 4.通过servletRequest对象,可以得到用户提交的数据
* 5.servletResponse对象可以用于返回数据给tomcat->浏览器
*
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest,
ServletResponse servletResponse) throws ServletException, IOException {
//如果count的值,在不停的累计, 说明HelloServlet是单例的
System.out.println("hi HelloServlet~, count=" + count++);
}
/**
* 返回servlet的信息,使用较少
* @return
*/
@Override
public String getServletInfo() {
return null;
}
/**
* 1.该方法是在servlet销毁时,被调用
* 2.只会调用一次
*/
@Override
public void destroy() {
}
}
web.xml注释时发现前面有空格
解决方案 Settings->Editor->Code Style->XML, 取消勾选
IDEA配置快捷键: settings->Keymap
重启(Alt+R)选择重新部署,速度快, 不要选Restart server, 这样会把JDK都重启, 速度很慢
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>HelloServletservlet-name>
<servlet-class>com.zzw.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/helloServleturl-pattern>
servlet-mapping>
web-app>
Servlet容器(比如:
Tomcat) 加载Servlet, 加载完成后, Servlet容器会创建一个Servlet实例并调用init()方法(创建的实例放入HashMap), init()方法只会调用一次, Servlet容器在下面的几种情况下会装载Servlet:
shortcuts: ctrl+alt+b 查看子接口或子类
@Override
public void service(ServletRequest servletRequest,
ServletResponse servletResponse) throws ServletException, IOException {
//如果count的值,在不停的累计, 说明HelloServlet是单例的
System.out.println("hi HelloServlet~, count=" + count++);
//System.out.println("当前线程id=" + Thread.currentThread().getId());
//1.从ServletRequest 没有得到 获取请求方式 的方法
//2.ServletRequest的子接口有无相关方法 shortcuts: ctrl+alt+b可以看到子接口和实现类
//3.servletRequest 转成HttpServletRequest引用
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
if ("GET".equals(method)) {
deGet();
} else if ("POST".equals(method)) {
doPost();
}
}
/*
用于响应get请求
*/
public void deGet() {
System.out.println("deGet() Method");
}
/*
响应post请求
*/
public void doPost() {
System.out.println("doPost() Method ");
}
public class HiServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("hiServlet doGet()");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("hiServlet doPost()");
}
}
web.xml配置
<servlet>
<servlet-name>HiServletservlet-name>
<servlet-class>com.zzw.servlet.HiServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>HiServletservlet-name>
<url-pattern>/hiServleturl-pattern>
servlet-mapping>
在WEB-INF目录下的lib文件夹下导入servlet-api.jar包并且Add As Library后右键才有新建Servlet的选项
public class OkServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//可以写自己的业务处理代码
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//可以写自己的业务处理代码
}
web.xml自动生成以下半截代码, 这里需要手动配置url-pattern
省去了在web.xml配置的麻烦
方法外不能使用.var
/**
* 显示方法之间的分割线 Editor->General->Appearance->Show method separators
* 1.@WebServlet是一个注解
* 2.@WebServlet的源码
* 3.urlPatterns 对应web.xml中的
* {"/ok1", "/ok2"} 可以给OkServlet配置多个 urlPattern
* 相当于这个@WebServlet(urlPatterns={"/ok1", "/ok2"}) 代替了web.xml的配置
* 4.浏览器可以这样访问OkServlet: http://localhost:8080/servlet/ok1 或者 http://localhost:8080/servlet/ok2
*/
@WebServlet(urlPatterns = {"/ok1", "/ok2"})
public class OkServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("annotation doGet method");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("annotation doPost method");
}
}
@WebServlet注解源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented => 在javadoc工具生成记录
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
模拟代码
/**
* @author 赵志伟
* @version 1.0
* 模拟Tomcat是如何通过注解@WebServlet(urlPatterns={"/ok1", "/ok2"})来装载一个Servlet的
*/
@SuppressWarnings({"all"})
public class TestAnnotationServlet {
private static final HashMap<String, HttpServlet> hm = new HashMap<>();
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//1.首先要得到扫描的包 路径 IO, 进而得到类的全路径
String path = "com.zzw.servlet.annotation.OkServlet";
//2.得到OkServlet的Class对象
Class<?> aClass = Class.forName(path);
//3.根据class对象得到对应的注解
WebServlet annotation = aClass.getAnnotation(WebServlet.class);
String[] urlPatterns = annotation.urlPatterns();
for (String urlPattern : urlPatterns) {
System.out.println("urlPattern=" + urlPattern);
}
//如果匹配url, 如果是第一次, tomcat就会创建一个OkServlet实例, 放入到HashMap中
Object instance = aClass.newInstance();
System.out.println("instance=" + instance);//OkServlet实例
hm.put("OkServlet", (HttpServlet) instance);
System.out.println(hm);
}
}
@WebServlet(urlPatterns = {"/ok1", "/ok2"}, initParams = {@WebInitParam(name = "zzw", value = "123"), @WebInitParam(name = "xx", value = "yy")})
public class OkServlet extends HttpServlet {}
等同于
<servlet>
<servlet-name>OkServletservlet-name>
<servlet-class>com.zzw.servlet.OkServletservlet-class>
<init-param>
<param-name>zzwparam-name>
<param-value>123param-value>
init-param>
<init-param>
<param-name>xxparam-name>
<param-value>yyparam-value>
init-param>
servlet>
@WebServlet(urlPatterns = {"/ok1/aa/bb", "/ok2"}
@WebServlet(urlPatterns = {"/ok1/*", "/ok2"})
http://localhost:8888/servlet/ok1
http://localhost:8888/servlet/ok1/aa
http://localhost:8888/servlet/ok1/aa/bb/cc
@WebServlet(urlPatterns = {"*.action", "/ok2"}
http://localhost:8888/servlet/zzw.action
http://localhost:8888/servlet/zzw.521.action
不能带斜杠
@WebServlet(urlPatterns = {"/*.action", "/ok2"},这样是错误的
@WebServlet(urlPatterns = {"/", "/ok2"}
或者
@WebServlet(urlPatterns = {"/*", "/ok2"}
http://localhost:8888/servlet/aa/bb/cc
http://localhost:8888/servlet/zzw.521.action
shortcuts: ctrl+alt+⬅ 回到上次访问的窗口
这个默认的Servlet是处理静态资源的, 一旦拦截, 静态资源则不能处理
<servlet>
<servlet-name>defaultservlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServletservlet-class>
<init-param>
<param-name>debugparam-name>
<param-value>0param-value>
init-param>
<init-param>
<param-name>listingsparam-name>
<param-value>falseparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
访问:http://localhost:8888/servlet/ok1/aa
@WebServlet(urlPatterns = {"/ok1/aa"}//优先
@WebServlet(urlPatterns = {"/ok1/*"}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("LoginServlet doGet method");
//输出一句话,给浏览器
//1.通过response获取流Print Writer,它可以给浏览器回复数据
//2.为了让浏览器显示中文,需要告诉浏览器我们的编码是utf-8
//解读: setContentType给回送数据设置编码
//(1)text/html这个是MIME类型即告诉浏览器返回的数据是text类型下的html格式数据[MIME类型 大类型/小类型]
//(2)charset=utf-8数据编码
//细节: 设置编码格式要在.getWriter()之前
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("登陆成功
");
//flush()会将缓存的数据刷新, 大多数语言的 close() 包含 flush()
writer.flush();
//close() 关闭流, 及时释放资源
writer.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("LoginServlet doPost method");
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("POST 登陆成功
");
writer.flush();
writer.close();
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>logintitle>
<link type="text/css" rel="stylesheet" href="css/my.css">
<script type="text/javascript" src="js/my.js">script>
head>
<body>
<form action="http://localhost:8080/http/login" method="post">
username: <input type="text" name="username"/><br/>
password: <input type="password" name="password"/><br/>
<input type="submit" value="登录"/>
form>
<a href="http://www.baidu.com">goto百度a>
<img src="imgs/1.png" width="245px">
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>logintitle>
<link type="text/css" rel="stylesheet" href="css/my.css">
<script type="text/javascript" src="js/my.js">script>
head>
<body>
<form action="http://localhost:8888/http/login" method="post">
username: <input type="text" name="username"/><br/>
password: <input type="password" name="password"/><br/>
<input type="submit" value="登录"/>
form>
<a href="http://www.baidu.com">goto百度a>
<img src="imgs/1.png" width="245px">
body>
html>
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。
步骤
public class Status_302 extends HttpServlet {
//将两个请求合并
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//如果有一个请求来了
// 重定向到servlet/login.html
// (1)返回302状态码 (2)响应头会带上Location:/login.html
response.sendRedirect("/servlet/login.html");
//response.sendRedirect("http://www.baidu.com");
}
}
MIME是HTTP协议中的数据类型. MIME的英文全称是"Multipurpose Internet Mail Extension", 即多功能Internet邮件扩展服务, MIME类型的格式是"大类型/小类型", 并与某一种文件的扩展名相对应
文件 | MIME类型 |
---|---|
超文本标记语言文本 | .html, .htm text/html |
普通文本 | .txt text/plain |
RTF文本 | .rtf application/rtf |
GIF图形 | .gif image/gif |
JPEG图形 | .jpeg, .jpg image/jpeg |
au声音文件 | .au audio/basic |
MIDI音乐文件 | .mid, midi audio/mid, audio/x-midi |
RealAudio音乐文件 | .ra, .ram audio/x-pn-realaudio |
MPEG文件 | .mpg, .mpeg video/mpeg |
AVI文件 | .avi video/x-msvideo |
GZIP文件 | .gz appcalition/x-gzip |
TAR文件 | .tar application/x-tar |
功能
- 获取Servlet程序的servlet-name值
- 获取初始化参数init-param
- 获取ServletContext对象
需求: 编写DBServlet.java
- 在web.xml中编写连接mysql的用户名和密码
- 在DBServlet执行doGet() / doPost()方法时, 均可以获取到web.xml配置的用户名和密码
实现
public class DBServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//DBServlet的父类GenericServlet有getServletConfig()
/**
* 1. getServletConfig()是父类GenericServlet类的
* 2. 返回的servletConfig对象是GenericServlet中的 private transient ServletConfig config;
* 3. 当一个属性被transient修饰, 表示该属性不会被串行化
*/
ServletConfig servletConfig = this.getServletConfig();//拿到的是GenericServlet中的config
String username = servletConfig.getInitParameter("username");
String password = servletConfig.getInitParameter("password");
System.out.println("doPost中=" + servletConfig);
System.out.println("初始化参数:username=" + username);
System.out.println("初始化参数:password=" + password);
}
}
功能(需求)
- 获取web.xml 中配置的上下文参数context-param[这个信息和整个web应用相关, 而不是属于某个Servlet]
- 获取当前的工程路径, 格式: /工程路径, 比如 /servlet
- 获取工程部署后在服务器硬盘上的绝对路径 (比如: D:\idea_project\zzw_javaweb\servlet\out\artifacts\servlet_war_exploded)
- 向Map一样存取数据, 多个Servlet共享数据
准备工作
实现
public class ServletContext_ extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取web.xml的context-parameter
// (1)得到ServletContext对象
ServletContext servletContext = getServletContext();
// (2)获取website
String website = servletContext.getInitParameter("website");
String favorite = servletContext.getInitParameter("favorite");
//2.获取当前项目的工程路径
String contextPath = servletContext.getContextPath();// /servlet
//3.获取项目发布后真正的工作路径
// (1)这个/表示我们的发布后的项目的根路径,即
// (2)D:\idea_project\zzw_javaweb\servlet\out\artifacts\servlet_war_exploded
String realPath = servletContext.getRealPath("/");
System.out.println("website=" + website);
System.out.println("favorite=" + favorite);
System.out.println(contextPath);
System.out.println("项目发布后的绝对路径=" + realPath);
}
}
public class OrderServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象
ServletContext servletContext = this.getServletContext();
//从servletContext获取 visit_count属性 k-v
Object visit_count = servletContext.getAttribute("visit_count");
//判断visitCount是否为空
if (visit_count == null) {//说明是第一次访问网站
visit_count = 1;
servletContext.setAttribute("visit_count", visit_count);
} else {
//取出visit_count的值 + 1
visit_count = Integer.parseInt(visit_count.toString()) + 1;
servletContext.setAttribute("visit_count", visit_count);
}
//输出
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("网站被访问的次数 "
+ visit_count + " 次");
//刷新
writer.flush();
writer.close();
}
}
PayServlet
public class PayServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象
ServletContext servletContext = this.getServletContext();
//从servletContext获取 visit_count属性 k-v
Object visit_count = servletContext.getAttribute("visit_count");
//判断visitCount是否为空
if (visit_count == null) {//说明是第一次访问网站
visit_count = 1;
servletContext.setAttribute("visit_count", visit_count);
} else {
//取出visit_count的值 + 1
visit_count = Integer.parseInt(visit_count.toString()) + 1;
servletContext.setAttribute("visit_count", visit_count);
}
//输出
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("网站被访问的次数 "
+ visit_count + " 次");
//刷新
writer.flush();
writer.close();
}
}
封装
public class WebUtils {
private static Object visit_count;
public static Integer visitCount(ServletContext servletContext, HttpServletResponse response) throws IOException {
//从servletContext获取 visit_count属性 k-v
visit_count = servletContext.getAttribute("visit_count");
//判断visitCount是否为空
if (visit_count == null) {//说明是第一次访问网站
visit_count = 1;
servletContext.setAttribute("visit_count", visit_count);
} else {
//取出visit_count的值 + 1
visit_count = Integer.parseInt(visit_count.toString()) + 1;
servletContext.setAttribute("visit_count", visit_count);
}
return Integer.parseInt(visit_count + "");
}
}
public class OrderServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
//获取ServletContext对象
ServletContext servletContext = this.getServletContext();
int visit_count = WebUtils.visitCount(servletContext, response);
//输出
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("网站被访问的次数 "
+ visit_count + " 次");
//刷新
writer.flush();
writer.close();
}
}
- getRequestURI() 获取请求的资源路径 http://localhost:8080/servlet/login.html
- getRequestURL() 获取请求的统一资源定位符(绝对路径) http://localhost:8080/servlet/login.html
- getHeader() 获取请求头
- getParameter() 获取请求的参数
- getParameterValues() 获取请求的参数(多个值时使用) 比如checkbox, 或返回的数组
- getRemoteHost() 获取客户端的主机
- getRemoteAddr() 获取客户端的ip
- getMethod() 获取请求的方式(GET或POST)
- setAttribute(key, value) 设置域数据
10.getRequestDispatcher() 获取请求转发对象(核心对象)
public class HttpServletRequestMethods extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/********************************
* 获取http请求头相关信息 *
********************************/
System.out.println("请求头信息");
System.out.println("资源路径URI(请求中的)=" + request.getRequestURI());
System.out.println("统一资源定位符(绝对路径)URL=" + request.getRequestURL());
System.out.println("客户端ip地址=" + request.getRemoteAddr());
//获取http请求头的信息: 可以使用request.getHeader("请求头字段")
// 可以指定 Accept, Accept-Encoding, Accept-Language, Connection, Cookie, Host, Referer
String accept = request.getHeader("Accept");
System.out.println("http请求头中的Accept信息=" + accept);
/********************************
* 获取表单提交的数据 *
********************************/
//1.获取单个表单数据
// 解决接收参数的中文乱码问题, 不能写在request.getParameter()后面
request.setCharacterEncoding("utf-8");//浏览器按照urlEncode编码方式提交数据, 后端要用utf-8来接收
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username=" + username);
System.out.println("password=" + password);//前端不填传给后端则是一个空字符串"", 不是null
//2.获取一组表单数据 复选框, 下拉框
String[] favorites = request.getParameterValues("favorite");
if (favorites != null) {//复选框前端不选则后端返回一个null
for (String favorite : favorites) {
System.out.println(favorite);
}
}
}
}
//本质实在http响应头加上Content-Type: text/html;charset=utf-8
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("提交的用户名="
+ username + "");
writer.flush();
writer.close();
再次理解Http协议Content-Type的含义, text/html 表示返回的数据类型, 浏览器会根据这个类型来解析数据
//本质实在http响应头加上Content-Type: text/html;charset=utf-8
// text/plain 表示返回的数据,请浏览器使用文本方式解析
// application/x-tar 表示返回的是一个文件,浏览器就会以下载文件的方式处理
response.setContentType("application/x-tar; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("提交的用户名="
+ username + "");
writer.flush();
writer.close();
前提: 新建两个Servlet, 并做好配置
public class CheckServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("CheckServlet doPost 输出");
//根据用户名来确定该用户是什么身份
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
//注意: 如果是同一个request对象(请求转发), 那么可以在不同的Servlet中使用getParameter取出同一个参数
if ("猫".equals(username)) {
//分配管理员权限
request.setAttribute("role", "管理员");
} else {
request.setAttribute("role", "普通用户");
}
//获取分发器
//解读一下:1./managerServlet写的是 要转发的servlet的url
// 2./ 会被解析成 /servlet
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/managerServlet");
// 3.forward(request, response) 会把当前Servlet的request,response对象传给下一个Servlet使用
requestDispatcher.forward(request, response);
}
}
public class ManagerServlet extends HttpServlet {
private int count;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String role = (String) request.getAttribute("role");
//输出
response.setContentType("text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("用户名 "
+ username + "");
writer.print("角色="
+ role + "");
writer.flush();
writer.close();
}
}
编写一个Servlet获取请求参数中的操作系统和位数
public class GetInfoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//谷歌浏览器:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
String userAgent = request.getHeader("User-Agent");
String regStr = "\\(([\\w\\ \\.;]+)\\)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(userAgent);
matcher.find();
//group(0) = (Windows NT 10.0; Win64; x64)
//group(1) = Windows NT 10.0; Win64; x64
String[] split = matcher.group(1).split(";");
System.out.println("操作系统=" + split[0]);
System.out.println("操作系统位数=" + split[1].trim());
}
}
public class DownServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("DownServlet 自己的业务");
//1.sendRedirect 本质会返回一个 302状态码 和 Location: /servlet/downServletNew
//2.因此 302状态码 和 /servlet/downServletNew是浏览器解析的
//3.浏览器会将 /servlet/downServletNew 解析成http://localhost:8080/servlet/downServletNew
response.sendRedirect("/servlet/downServletNew");
}
}
public class DownServletNew extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("DownServletNew doPost");
response.setContentType("application/x-tar; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("下载完成
");
writer.flush();
writer.close();
}
}
<body>
<h2>下载文件h2>
<a href="http://localhost:8888/servlet/downServlet">下载<<三体>>小说a>
body>
//第一种重定向使用
response.sendRedirect("/servlet/downServletNew");
//第二种重定向使用
response.setStatus(302);//设置http响应的状态码
//设置http响应的Location: /servlet/downServletNew
response.setHeader("Location", "/servlet/downServletNew");
//动态获取 application context
String contextPath = getServletContext().getContextPath();
System.out.println(contextPath);// /servlet
response.sendRedirect(contextPath + "/downServletNew");
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>支付页面title>
head>
<body>
<h1>支付页面h1>
<form action="/servlet/myPayServlet">
用户编号:<input type="text" name="userId"/>
支付金额:<input type="text" name="money"/>
<input type="submit" value="点击支付">
form>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>支付成功title>
head>
<body>
<h1>恭喜你支付成功h1>
body>
html>
public class MyPayServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String userId = request.getParameter("userId");
String money = request.getParameter("money");
String contextPath = getServletContext().getContextPath();
if (WebUtils.parseString(money) > 100) {
response.sendRedirect(contextPath + "/pay_ok.html");
} else {
response.sendRedirect(contextPath + "/pay.html");
}
}
}
public class WebUtils {
public static int parseString(String str) {
int num = 0;
try {
//shortcuts: ctrl+alt+t
num = Integer.parseInt(str);
} catch (NumberFormatException e) {
System.out.println("输入的str格式不正确");
}
return num;
}
}
<servlet>
<servlet-name>MyPayServletservlet-name>
<servlet-class>com.zzw.servlet.response.MyPayServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>MyPayServletservlet-name>
<url-pattern>/myPayServleturl-pattern>
servlet-mapping>