文章目录

  • 1.nginx的conf文件:以前网络编程中B/S架构中服务器是用socket写,用文件输入流读一个文件,读到后socket通过outputstream写出去,这些过程有了nginx后再也不用写
  • 2.nginx反向代理与负载均衡:nginx是被广泛使用的网页服务器,在www.163.com的F12的Network中Headers中有server:nginx,使用nginx首当其冲,做反向代理,将请求分发到公司的多台服务器上
    • 2.1 location匹配方式:location / 默认匹配所有请求,相当于第四优先级(最弱)
    • 2.2 反向代理写法:http80,
    • 2.3 负载均衡写法:基于反向代理
  • 3.服务器:软件为tomcat或nginx,程序为servlet
  • 4.servlet:多态,web.xml
  • 5.servlet生命周期:LifecycleServlet
  • 6.servlet优化:GenericServelt/HttpServelt
  • 7.http协议和抓包:枚举Enumeration,request.getHeaderNames()
  • 8.request对象:.getParameterMap(),post请求中文参数乱码
  • 9.请求转发:jrss,request.setAttribute()
  • 10.登陆案例(1):成功和失败页面相当于两个模块
  • 11.response对象:text/html,重定向(.setStatus,.setHeader)
  • 12.文件下载:request/response

1.nginx的conf文件:以前网络编程中B/S架构中服务器是用socket写,用文件输入流读一个文件,读到后socket通过outputstream写出去,这些过程有了nginx后再也不用写

nginx软件链接:https://pan.baidu.com/s/1zvF2irI6OenDKVfvSIOZmg ,提取码:gsn9。

如果http协议是80端口的话,80端口会被隐藏,本机浏览器输入http://localhost:80启动服务端显示如下,hello nginx是E\my81\index.html里内容。本机ipconfig显示192.168.33.71。上面红框浏览器(客户端)是别人的电脑【局域网下同一网段】,上面两个大框是服务端,浏览器和服务器三要素对应。

nginx作用:1.反向代理:s被代理1个公网ip,但有n台s对外服务。
2.负载均衡:基于反向代理。
3.正向代理:我们电脑接入VPN 后,我们对外IP地址就会变成VPN服务器的公网IP。
4.动静分离:网页f12显示js,css,img属静态数据。

线程通讯:volatile关键字,wait(),notify()
线程安全:synchronized关键字
计算密集型:进行(多核)
io密集型:线/协程(只1个核在做,占资源轻,io等待时间拿来用)

2.nginx反向代理与负载均衡:nginx是被广泛使用的网页服务器,在www.163.com的F12的Network中Headers中有server:nginx,使用nginx首当其冲,做反向代理,将请求分发到公司的多台服务器上

原生nginx没有集成很多插件,使用不方便。推荐使用openresty(在nginx基础上集成了很多lua写的插件),官网下载openresty后解压后进一级目录输入nginx.exe回车运行服务端,浏览器输入localhost默认:80端口。修改conf目录下nginx.conf文件,删除注释。50x.html是错误页面,暂时不用。


如下还是在nginx.conf文件里,stream类型执行下载,echo是插件。


2.1 location匹配方式:location / 默认匹配所有请求,相当于第四优先级(最弱)

1.如下最强级别=。



2.如下优先级第二,^~以什么开头。如下/是路径,不是转义符。



3.如下优先级第三,正则表达式~\w匹配数字、字母、下划线,转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\。如下/是路径。



如下同优先级的,按匹配程度较高的先匹配。


同优先级并且匹配程度相同的话,写在上面的优先执行。

2.2 反向代理写法:http80,

如下是其他服务器,记住192…:80是it works页面。



如下localhost先到本机127.0.0.0,再转到192上面的这个服务器。

如下是apach返回的Not Found返回的信息,192…:80/a路径没有,不是nginx返回的信息,因为已经把请求转到192…

1.默认拼接。


如下其实转到了192...:80/a

2.如下转到192...:80/,两个/省去后一个字母。

2.3 负载均衡写法:基于反向代理


两个ip+端口根据权重切换。

3.服务器:软件为tomcat或nginx,程序为servlet

Web(World Wide Web)即全球广域网,也称为万维网。

nginx不支持java规范,tomcat支持。tomcat8:https://tomcat.apache.org/download-80.cgi。免安装,解压即可用:链接:https://pan.baidu.com/s/1UJM9kbIHGIXkNXlYLpcoGw ,提取码:g610。dos系统识别文件后缀名不能超过3位(先有dos后有windows),所以.htm。8080一般是用来连接代理的(8080不能省,只有80才能省)。 只有index.html是默认的,不用加在最后,localhost:8080/a.html。

如下javaee新建项目,apache-tomcat8…是前面tomcat软件解压路径。如下不需要自己开启tomcat,idea配置自动开启。


如下New和上面一样,关联tomcat软件解压路径。

如下将web文件夹当成前端static web项目,web文件夹里都可以访问,除了web-info无法访问(如【Mysql3】最后一节,-info文件夹放jar包),Toolbar工具栏。


如下是点乌龟运行后,浏览器自动打开的原理。改变路径 / 写法。

如上若还是不会默认打开谷歌,需要File - Settings - Tools - Web Browsers。

4.servlet:多态,web.xml


如下选中src右击new - java class,name为com.itheima01.servlet.MyServlet,还有一件事配置web.xml如上图所示。

package com.itheima01.servlet;
import javax.servlet.*;
import java.io.IOException;public class MyServlet implements Servlet { //javax.servlet.Servlet (x指extend,如果没有提示,则上面tomcat项目配置失败)   //没有main函数,右击run不了,点乌龟@Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("控制台日志: 服务器被访问了"); servletResponse.getWriter().print("hello servlet"); //在网页上打印(英文,中文会乱码)}    @Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}

如下点击idea中乌龟,自动打开网页,改变/my路径。


tomcat+servlet原理(4步):以前解析xml文件(web.xml)用dom4j,将xml先读到内存里在进行解析。第4步:mapping映射后,tomcat(中介即代理默认端口8080)底层会进行反射,当前类com.itheima01.servlet.MyServlet肯定是Servlet接口的implements实现类,可以向上转型,父类Servlet调用方法执行子类重新的方法。

为什么tomcat底层用反射?tomcat底层设计不能和MyServlet耦合,只有全限定名和MyServlet有关(自己设定的),通用性。tomcat像管家中介(用户,tomcat软件【中介】,jdk的Servlet)在第3步等客人,第4步客人来了找my,tomcat根据客人请求找到my的住址com....MyServlet,把my叫醒进行service办公。

如上在web.xml中,MyServlet01可以随便命名但要上下一致,my是资源位置,/my(因为在当前项目,http…8080可以省略,url)和com…MyServlet(class,全限定名就是全类名就是包名加类名)对应关系。

5.servlet生命周期:LifecycleServlet

package com.itheima02.life;
import javax.servlet.*;
import java.io.IOException;public class LifecycleServlet implements Servlet {public LifecycleServlet(){  //不写也可以,一个类默认有 空参构造System.out.println("LifecycleServlet");}  //如下生命周期 5个重写  @Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("init");}    @Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("service");}    @Overridepublic void destroy() {System.out.println("destroy");}//11111111111111111111111111111111111111111111111111111111以下没用@Overridepublic ServletConfig getServletConfig() {System.out.println("getServletConfig");return null;}    @Overridepublic String getServletInfo() {System.out.println("getServletInfo");return null;}
}

//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><servlet><servlet-name>MyServlet01</servlet-name><servlet-class>com.itheima01.servlet.MyServlet</servlet-class></servlet><servlet-mapping><servlet-name>MyServlet01</servlet-name><!-- <url-pattern>http://localhost:8080/my</url-pattern>--><url-pattern>/my</url-pattern></servlet-mapping><servlet><servlet-name>LifecycleServlet</servlet-name><servlet-class>com.itheima02.life.LifecycleServlet</servlet-class></servlet><servlet-mapping><servlet-name>LifecycleServlet</servlet-name><url-pattern>/life</url-pattern></servlet-mapping><servlet><servlet-name>GoodServlet</servlet-name><servlet-class>com.itheima03.good.GoodServlet</servlet-class></servlet><servlet-mapping><servlet-name>GoodServlet</servlet-name><url-pattern>/good</url-pattern></servlet-mapping><servlet><servlet-name>BetterServlet</servlet-name><servlet-class>com.itheima03.good.BetterServlet</servlet-class></servlet><servlet-mapping><servlet-name>BetterServlet</servlet-name><url-pattern>/better</url-pattern></servlet-mapping>
</web-app>


如下默认调用空参构造创建实例(第一行)。

6.servlet优化:GenericServelt/HttpServelt

只留一个接口叫适配器设计模式。将service方法根据不同请求方式分化出两个不同方法。

package com.itheima03.good;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class GoodServlet extends GenericServlet {//ServletRequest : 请求(前端发送服务器的数据), 兼容大部分协议(包括http), 子接口: HttpServletRequest@Override   public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { //这个service方法将下面3个方法(service2,doPost,doGet)都调用了System.out.println("goodServlet");    //没有ServletRequest.getgetMethod()  //因为不是所有的协议都有请求方式,所以要向下转型成httpHttpServletRequest request = (HttpServletRequest) servletRequest; //协议: 必须是httpHttpServletResponse response = (HttpServletResponse) servletResponse;//request.getMethod(); //http协议有请求方式service2(request,response);        }private void service2(HttpServletRequest request, HttpServletResponse response) {        String method = request.getMethod(); //请求方式if("GET".equals(method)){doGet(request,response);}else if("POST".equals(method)){doPost(request,response);}}//以后再写Servlet只要继承GoodServlet(GoodServlet可以改名为HttpServlet),重写doPost和doGet就行    //如下相当于 http协议中post请求方式的service方法,HttpServletRequest类比原ServletRequest类好用private void doPost(HttpServletRequest request, HttpServletResponse response) {}//如下相当于 http协议中get请求方式的service方法private void doGet(HttpServletRequest request, HttpServletResponse response) {        }
}

浏览器:localhost:8080/good,网页无显示,控制台打印goodServlet。

package com.itheima03.good;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class BetterServlet extends HttpServlet { //sun公司已经封装HttpServlet@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}

如上解决了前二个问题。如下解决第三个问题,不用配置web.xml。

package com.itheima03.good;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns = "/best")
public class BestServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp); }@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("被访问了");}
}



如下把上面BestServlet类设置为模板,使用:选中包(包下)-new-servlet。

如上模板如下:

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")@javax.servlet.annotation.WebServlet(urlPatterns = "/${Entity_Name}")
public class ${Class_Name} extends javax.servlet.http.HttpServlet {@Overrideprotected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {doGet(request,response);}@Overrideprotected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {}
}

7.http协议和抓包:枚举Enumeration,request.getHeaderNames()

http的request对象:由tomcat创建,并且里面数据由tomcat set进去,我们只需要get出来。

File-New-Project-Java Enterprise。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head><!--111111111111111111111111111111111111111111111111111111111111111111111111111-->
<body><!--http协议两种主要请求协议1. get (默认, 只要看到可以发起请求,但是没看到请求方式设置)2. post (需要收到设置)--><h1>get请求方式</h1><form action="http://localhost:8080/MyServlet" method="get"><input type="text" placeholder="请输入用户名" name="name"> <br><input type="text" placeholder="请输入密码" name="pwd"> <br><input type="submit"></form><h1>post请求方式</h1>  <form action="/MyServlet" method="post">    <!-- 本服务器前面可以省略 --><input type="text" placeholder="请输入用户名" name="name"> <br><input type="text" placeholder="请输入密码" name="pwd"> <br><input type="submit"></form>
</body>
</html>

如上html文件建在web文件夹路径下,如下创建的是servlet的模板。

package com.itheima01.http;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
/***  http://192.168.139.236:8080/MyServlet 或 MyServlet换成..请求报文.html**  #request对象核心功能: 获取前端的请求数据如下:*  1. 请求行*      请求方式 / 请求url / 协议*       方法:1. String getMethod() : 获取请求方式的类型2. StringBuffer getRequestURL() : 获取客户端发出请求完整URL3. String getProtocol(): 获取当前协议的名称和版本   4. String getRemoteAddr() : 获取IP地址**  2. 请求头*        1. 获取指定请求头的信息: value = request.getHeader("name");2. 获取所有的请求头的name值:request.getHeaderNames();**  3. 请求参数*      tomcat: 会根据不同的请求方式(自动get请求从url获取参数,post请求从请求体里获取参数),从不同的地方获取参数并设置到request对象,这样不需要知道过程,只有结果。**/
@WebServlet(urlPatterns = "/MyServlet")
public class MyServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}    @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //doGet方法相当于get请求方式下的service方法
//        System.out.println("服务器被访问了");  //idea下面显示
//        response.getWriter().print("hello http");  //在网页上输出//        line(request); //请求行String agent = request.getHeader("user-agent"); //出bug执行的//用户访问我的网站突然崩溃,实际已获取了用户环境,在服务器所在地方可以模拟用户String referer = request.getHeader("referer"); //防盗链System.out.println(agent);System.out.println(referer);//11111111111111111111111111111111111111111111111111111111111111111111111111111111HashMap<String, String> map = new HashMap<>();Iterator<String> it = map.keySet().iterator();while(it.hasNext()){String key = it.next();String value = map.get(key);}  //如下枚举Enumeration相当于上面迭代器      Enumeration<String> it2 = request.getHeaderNames(); //=号右边等价于map.keySet().iterator()while(it2.hasMoreElements()){String name = it2.nextElement();String value = request.getHeader(name);System.out.println(name + "->" + value);}}//11111111111111111111111111111111111111111111111111111111111111111111111111111111private void line(HttpServletRequest request) {  //请求行,抓包String method = request.getMethod();StringBuffer url = request.getRequestURL();String protocol = request.getProtocol();String remoteAddr = request.getRemoteAddr();        System.out.println(method);System.out.println(url.toString());System.out.println(protocol);       System.out.println("访问者的ip:" + remoteAddr);}
}


如上浏览器网址中…报文.html是Referer中的上一次访问页面,因为已跳转到如下下个页面。

如下请求行中的请求url省略了如上的http://localhost:8080。cookie是浏览器缓存的一种。get请求中最后一行不是请求体,是谷歌浏览器工具抓包进行的参数强调渲染。

8.request对象:.getParameterMap(),post请求中文参数乱码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head><!--111111111111111111111111111111111111111111111111111111111111111111111111111-->
<body><h1>get请求</h1><form action="/ParamServlet" method="get">用户名: <input type="text" name="name"> <br>密码: <input type="password" name="pwd"> <br>性别: <input type="radio" name="gender" value="boy">男<input type="radio" name="gender" value="girl"> 女<br>爱好:<input type="checkbox" name="hobby" value="smoke"> 抽烟<input type="checkbox" name="hobby" value="drink"> 喝酒<input type="checkbox" name="hobby" value="firehead"> 烫头 <br><input type="submit"></form><h1>post请求</h1><form action="/ParamServlet" method="post">用户名: <input type="text" name="name"> <br>密码: <input type="password" name="pwd"> <br>性别: <input type="radio" name="gender" value="boy"><input type="radio" name="gender" value="girl"> <br>爱好:<input type="checkbox" name="hobby" value="smoke"> 抽烟<input type="checkbox" name="hobby" value="drink"> 喝酒<input type="checkbox" name="hobby" value="firehead"> 烫头 <br><input type="submit"></form>
</body>
</html>
package com.itheima02.param;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
/**请求参数: parameter   ?n1=v1&n2=v2...方法:1. 根据name值获取value值: String value = request.getParameter(name);2. 根据name值获取多个value值:String[] value = request.getParameterValues(name);3. 获取所有的请求参数,封装到map中:Map<String, String[]>  map = request.getParameterMap();name为String,value为String[]问题: post请求中文参数乱码原因: 编解码使用的字符集不一样编码:  浏览器 ( utf-8 )解码:  服务器 (tomcat + servlet)ISO-8859-1   utf-8解决:  tomcat的编码表改成utf-81. 永久2. 临时 (选用)  request.setCharacterEncoding("utf-8");  注意: 必须放在获取参数之前【get请求 tomcat8以上被优化 不乱码(post请求参数在请求体中,走io流)】**/
@WebServlet(urlPatterns = "/ParamServlet")
public class ParamServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}     @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//       request.setCharacterEncoding("utf-8");String name = request.getParameter("name");String pwd = request.getParameter("pwd");String gender = request.getParameter("gender");String[] hobbies = request.getParameterValues("hobby"); //复选框可重复System.out.println(name+"," + pwd + "," + gender + "," + Arrays.toString(hobbies));//11111111111111111111111111111111111111111111111111111111111111111111111111111111111Map<String, String[]> map = request.getParameterMap();
//        System.out.println(map); //这个map没有重写tostring方法Set<String> set = map.keySet();for (String key : set) {String[] value = map.get(key); //value数组没有重写tostring方法,不能
//            System.out.println(key + "=" + Arrays.toString(value));}}
}


如下选中的是map遍历出来的结果和下面第一行一样。

9.请求转发:jrss,request.setAttribute()

request表面上获取请求数据,还有快递员身份。

如下forward方法中request是邮件及内容,response是回应权限。A模块指MyServlet,B模块指ZhouServlet。一次请求链如下只有一去一回。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head><!--111111111111111111111111111111111111111111111111111111111111111111111111111-->
<body>        人事<!--<a href="http://localhost:8080/ShiServlet?msg=有人来面试">发送邮件</a>--><a href="/ShiServlet?msg=有人来面试">发送邮件</a>  <!--点发送邮件后,地址栏修改为/Shi..,没写就是get请求-->
</body>
</html>
package com.itheima03.transfer;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns = "/ShiServlet")
public class ShiServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 接收请求String msg = request.getParameter("msg");System.out.println("shi:" + msg);System.out.println("shi:我现在没空,叫周楠同学帮我面试");            request.setAttribute("extra","比我帅的不要~~");  //添加备注,这行注掉不写,ZhouServlet写request.getAttribute会得到null//2. 请求转发
//        RequestDispatcher dispatcher = request.getRequestDispatcher("/ZhouServlet"); //比作邮件服务器或快递员
//        dispatcher.forward(request,response); //快递员发货request.getRequestDispatcher("/ZhouServlet").forward(request,response); //这行等价上面两行}
}
package com.itheima03.transfer;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns = "/ZhouServlet")
public class ZhouServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  //request和response两个参数由A模块传递来//1. 接收请求String msg = request.getParameter("msg");System.out.println("zhou:" + msg);                Object extra = request.getAttribute("extra");System.out.println("zhou:" + extra);//2. 业务处理System.out.println("周楠同学放下手机,难得做点事情: 面试");//3. 响应数据response.getWriter().print("this boy is ok,about 3k~~");}
}


10.登陆案例(1):成功和失败页面相当于两个模块


File - New - Project - Java Enterprise。

如下想到Junit包失效。

//JdbcUtil.java
package com.itheima.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.jdbc.core.JdbcTemplate;public class JdbcUtil {private static ComboPooledDataSource ds = new ComboPooledDataSource(); //先new一个连接池public static JdbcTemplate getTemplate(){JdbcTemplate template = new JdbcTemplate(ds); //再new一个Template,把连接池交给给JdbcTemplate管理return template;}
}
//LoginServlet.java
package com.itheima.login;
import com.itheima.bean.User;
import com.itheima.utils.JdbcUtil;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns = "/LoginServlet")
public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}    @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.接收请求String username = request.getParameter("userName"); //userName区分大小写String password = request.getParameter("password");//2.业务处理  //如下只有两种结果: 返回一行(一行是一个对象) 或 返回nullString sql = "select * from user where username = ? and password = ?";JdbcTemplate template = JdbcUtil.getTemplate(); //一定要封装成JdbcUtil,不然new ComboPooledDataSource,每访问一次就会创建一次连接池,内存崩。User user =  template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username, password); //把如下注掉,用如上一行,即查不到数据,抛出异常,不抓异常,这样会密码错误直接跳转500(500服务器错误,404地址输错),而不是error.html               /*User user = null;try {user = template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username, password);} catch (DataAccessException e) {e.printStackTrace();}*/if(user != null){request.getRequestDispatcher("/success.html").forward(request,response); //登录成功}else{request.getRequestDispatcher("/error.html").forward(request,response);}}
}
// User.java
package com.itheima.bean;public class User {private Integer id; //和表字段一致private String username;private String password;@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}public Integer getId() {return id;}public void setId(Integer 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;}
}
//login.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>登录页面</title><link href="css/bootstrap.min.css" rel="stylesheet"><link href="css/login.css" rel="stylesheet"><script src="js/jquery.js"></script><script src="js/bootstrap.js"></script>
</head><!--1111111111111111111111111111111111111111111111111111111111111111111111111-->
<body><div class="container text-center"><form class="form-signin" action="/LoginServlet"><h2 class="form-signin-heading">登录页面</h2><input type="text"  name="userName" class="form-control" placeholder="用户名" required autofocus><input type="password"  name="password" class="form-control" placeholder="密码" required><button class="btn btn-lg btn-primary btn-block" type="submit">登录</button></form></div>
</body>
</html>

11.response对象:text/html,重定向(.setStatus,.setHeader)



package com.itheima01.http;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;@WebServlet(urlPatterns = "/MyServlet")
public class MyServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException            {doGet(request, response);}        @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("服务器被访问了");
//        int i = 1/0; //服务器崩了出异常,没有try catch,状态码500        response.setStatus(302); //状态码设置,只有302需要我们手动设置
//      response.setStatus(404); //这样设置状态码是404,servlet优先级高于tomcat,但是访问服务端依旧成功
//        response.getWriter().print("hello response"); //前端网页打印出//响应体输出流设置,字节输出流(写)  //待会下载文件案例中使用
//       ServletOutputStream os = response.getOutputStream();
//       os.write("abc".getBytes()); //01_响应报文.html中点击“访问MyServlet”超链接跳转到显示“abc”的新页面//方便输出字符数据,不用转换为字节了,print和write一样
//       PrintWriter writer = response.getWriter();
//       response.getWriter().print("xx");  }
}

请求报文分get和post两种,在响应报文里看到了非servlet设置的内容,那就是tomcat设置的。将前端改为href=“/MyServlet123”,则会出现404。servlet关了,tomcat自动设置为500状态码。

如下体中hello response长度一共为Content-Lenth为14,头中GMT格林位置需+8小时为东八区北京时间。如下行和头都是tomcat默认自动设置,体是我们servlet手动设置。想修改状态码,需要在servlet(对我们暴露的小程序)中修改。


如下响应头分四种(蓝色字),如下简易API等同上行。


如下点击后,5秒后跳转到百度。

package com.itheima02.header;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns = "/RefreshAndTypeServlet")
public class RefreshAndTypeServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}    @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("服务器被访问了");
//        response.setHeader("refresh","5;http://www.baidu.com");//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111/**   问题: 响应体中文乱码 。request.setCharacterEncoding("utf-8");*   原因:  编码: 服务器(utf-8 : servlet:因为在servlet里写的"哈哈",idea右下角显示utf-8)*          解码: 浏览器(iso-8859-1 : tomcat默认设置如下行)     // response.setHeader("content-type","text/plain");  //在Response Headers(浏览器F12看出)中多出tomcat默认设置(不加这行不显示):Content-Type: text/plain;charset=ISO-8859-1*   解决: servlet中手动设置覆盖tomcat默认设置**    windows系统:      txt        html          jpg          avi     ...*    早期MIMEType :  text/plain   text/html     image/jpeg (tomcat解压包中web.xml中有对应说明)*/
//        response.setHeader("content-type","text/plain;charset=utf-8"); //新页面显示 <h1>哈哈</h1>
//        response.setHeader("content-type","text/html;charset=utf-8");  //点击网页上RefreshAnd..跳转新页面显示 哈哈response.setContentType("text/html;charset=utf-8"); //setContentType是简易API,同上一行response.getWriter().print("<h1>哈哈</h1>"); }
}

因为重定向不是一次请求链,所以超过域对象,不能用request传递数据。ZhouServlet收不到人事的msg,能收到ShiServlet的response.setHeader(…/ZhouServlet?msg=…)。

package com.itheima03.redirect;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns = "/ShiServlet")
public class ShiServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");doGet(request, response);}        @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 接收请求String msg = request.getParameter("msg");System.out.println("shi:" + msg);//2. 重定向response.setStatus(302);response.setHeader("location","/ZhouServlet?msg=xx"); //不写?msg=xx,ZhouServlet就收不到msg,写了就能收到}
}
package com.itheima03.redirect;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns = "/ZhouServlet")
public class ZhouServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}    @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 接收请求String msg = request.getParameter("msg");System.out.println("zhou:" + msg);//2. 业务处理System.out.println("这个哥们还不错");//3. 响应数据response.setContentType("text/html;charset=utf-8");response.getWriter().print("这个哥们还可以,大约3K");}
}




如下浏览器F12,第二行没有带参数,拿不到msg。

前面登陆成功请求转发到成功.html页面,失败.html…。用请求转发不合适,因为没有传递数据,应该用重定向。请求转发一次请求,地址指向第一次访问位置如下(网址阅读性太差,实际页面应该为localhost:8080/success.html)。

如下红框用重定向,登陆失败逻辑错误,之后再改。

如下重定向,第一次请求收到302。

12.文件下载:request/response

首先服务器要有文件,在网络编程做过文件上传。在servlet里写代码覆盖tomcat默认设置。

//02文件下载.html
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head><!--1111111111111111111111111111111111111111111111111111111111111111111111111-->
<body><!--方案A:浏览器打开此网页点击后自动下载的话,说明tomcat默认设置,因为servlet一个字没写--><!-- <a href="dir/1.zip">1.zip</a> <br>   <a href="dir/2.exe">2.exe</a> <br><a href="dir/3.txt">3.txt</a> <br><a href="dir/4.jpg">4.jpg</a> <br>--><a href="/DownloadServlet?file=1.zip">1.zip</a> <br><a href="/DownloadServlet?file=2.exe">2.exe</a> <br><a href="/DownloadServlet?file=3.txt">3.txt</a> <br><a href="/DownloadServlet?file=4.jpg">4.jpg</a> <br>
</body>
</html>
package com.itheima04.down;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;@WebServlet(urlPatterns = "/DownloadServlet")
public class DownloadServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String file = request.getParameter("file"); // 拿到1.zip之类//1. 告诉浏览器如何处理文件response.setHeader("content-disposition","attachment;filename=x" + file); //下载以x命名//2. 读取服务器本地文件,写出浏览器。绝对路径 等会要改成 相对路径//以前java工程: web/dir/文件(相对路径,里面是1.zip,2.exe等需下载的文件)//web工程: main方法在tomcat里,造成和java工程相对路径不一样
//   FileInputStream fis = new FileInputStream("E:/mywork/IdeaProjects/class897/web-day03/web/dir/" + file);//ServletContext servletContext1 = this.getServletContext(); //this是当前的servlet对象:servlet.getServletContext()  //同下一行ServletContext servletContext = request.getServletContext(); //request小域对象可获取ServletContext大域对象 String realPath = servletContext.getRealPath("dir/" + file); //绝对路径换成相对路径 FileInputStream fis = new FileInputStream(realPath);ServletOutputStream os = response.getOutputStream();int length;byte[] buffer = new  byte[1024];while((length = fis.read(buffer)) != -1){os.write(buffer,0,length);}fis.close();os.close();System.out.println("文件下载完毕");}
}

响应体交给浏览器,浏览器自动下载。

linux没有盘符,所以不能用绝对路径,不好部署。如下artifacts指整个项目,运行的是如下蓝字编译的内容(黄色文件夹),只要获得web_war_exploded文件夹就能得到其他文件相对路径。用serlvetContext = web_war_exploded文件夹路径(exploded部署意思,如下红线),如下右边servletContext是生命周期最长的域对象,所以可以将数据传到服务器任何地方。

request除了作为域对象还有本职工作即获取请求数据,servletContext很像连接池(连接池一个就够),服务器没关,连接池不消毁。servletContext生命周期和web应用一样长,所以也叫application应用,环境参数如相对路径。request和session两个域对象用的最多,pageContext太短,servletContext太长。重定向不能通过request传递数据,可以用servletContext传递数据,但是一般也不这么做,servletContext占用内存大。

上图灰色WEB-INF文件夹中添加lib文件夹里放druid-1.0.9.jar包并右击add as library【Mysql3】,点乌龟运行tomcat后,会生成黄色lib文件夹黄色classes文件夹里代码不能直接访问,需用web.xml或用注解建立映射关系访问:WEB-INF下是浏览器无法直接访问,通过建立映射,url访问,由tomcat访问。

热更新不做编译,新增类必须停下来。


【Java12】tomcatservlet(nginx,web.xml,生命周期,适配器优化),requestresponse(请求转发,登陆案例(1),重定向,文件下载)相关推荐

  1. 【JavaWeb】一文Servlet全解:继承关系、生命周期、容器和请求转发与重定向等

    文章目录 一.Servlet 概述 二.Servlet HelloWorld 三.Servlet 继承关系 四.Servlet 生命周期 五.ServletConfig 和 ServletContex ...

  2. Vue生命周期,Vue中在哪个生命周期阶段调用异步请求最佳

    Vue生命周期 beforeCreate(创建前): 在数据观测和初始化事件还未开始,data.watcher.methods都还不存在,但是$route已存在,可以根据路由信息进行重定向等操作. c ...

  3. 六十五、vue生命周期和发送Ajax请求

    vue生命周期和发送Ajax请求 一 vue生命周期介绍 二 vue生命周期钩子函数 三 测试 三 发送Ajax请求 四 计算属性 五 监听属性 一 vue生命周期介绍 每个 Vue 实例在被创建时都 ...

  4. Swift之深入解析Xcode13对Swift对象生命周期的优化

    在 Xcode13 中,在 Build Setting 中,新增 Optimize Object Lifetimes 编译选项,默认是关闭的,Apple 建议将该选项设置为 YES,打开此优化项,可以 ...

  5. react生命周期与优化

    转载自https://www.cnblogs.com/penghuwan/p/6707254.html 凡是参阅过react官方英文文档的童鞋大体上都能知道对于一个组件来说,其state的改变(调用t ...

  6. 微信小程序 - 在自定义组件中请求后端 API 数据接口(引入该组件的页面触发)组件在哪个生命周期钩子函数中请求接口数据呢?

    前言 我开发了一个 A 页面,然后在 A 页面引入了一个组件 B ,我想在 B 组件中加载进来的时候执行一个后端请求,获取数据进行 B 组件渲染. 今天遇到这么一个问题,我写好的小程序 组件(comp ...

  7. Servlet 的生命周期详解

    目录 1.Servlet 的生命周期 2.Spring 中一个 Controller 是一个Servlet 吗? 3.在 Spring 中有多少个 Servlet ? 4.DispatcherServ ...

  8. [译] ASP.NET 生命周期 – ASP.NET 上下文对象(六)

    使用 HttpApplication 对象 ASP.NET 框架中的许多类都提供了许多很方便的属性可以直接映射到 HttpContext 类中定义的属性.这种交叠有一个很好的例子就是 HttpAppl ...

  9. ASP.NET 应用程序生命周期概述

    本主题概述应用程序生命周期,列出重要的生命周期事件,并描述如何编写适合应用程序生命周期的代码.在 ASP.NET 中,若要对 ASP.NET 应用程序进行初始化并使它处理请求,必须执行一些处理步骤.此 ...

  10. jsp学习(1)jsp请求过程和生命周期

    一.服务器处理jsp请求的过程: 以下步骤表明了 Web 服务器是如何使用JSP来创建网页的: 1.浏览器发送一个 HTTP 请求给服务器. 2.Web 服务器识别出这是一个对 JSP 网页的请求,并 ...

最新文章

  1. 使用ecshop电子商务系统的100个小问题
  2. #我要10000+# 计划启动啦!让文章拥有更多曝光~
  3. Winforn中使用SaveFileDialog实现另存为对话框
  4. 2021牛客多校5 - Double Strings(dp+组合数学)
  5. 坚果Pro 3发布,罗永浩大赞科大讯飞:不成器国产厂商尽早跟讯飞合作
  6. SQL2008数据类型
  7. System V与Posix
  8. python输入流和输出流_Python 初体验之 输入输出流
  9. JDBC基础篇(MYSQL)——自定义JDBCUtil工具类
  10. 微技能|几分钟搭建网站内容平台
  11. Linux nmon 命令
  12. Python设计模式(七)【命令模式】
  13. SENT协议学习总结
  14. PADS9.5实战攻略与高速PCB设计-强烈推荐教程资料(完整书签)
  15. Git 团队协作中常用检查术语 WIP PTAL CC LGTM 等解释
  16. 5328笔记 Advanced ML Chapter3-Hypothesis Complexity and Generalisation
  17. 文心一言眼里的Java世界
  18. AI电话机器人有没有效果?具体的功能都有哪些?
  19. WindowsCE目录解析
  20. 【83】secureCRT 7.0登录Ubuntu 20.04提示key exchange failed

热门文章

  1. where和having的区别
  2. uva 11992 - Fast Matrix Operations
  3. 在pl/sql中使用exp/imp工具实现oracle数据导出/导入
  4. Axure RP Pro 6.0 原型设计工具(产品经理必备)
  5. jsp复选框追少选择一个否则不能提交_Filecoin的惩罚机制/至联云IPFS:选择无良矿商,你的抵押币就回不来了...
  6. c# json datatable_KoobooJson一款高性能且轻量的JSON库
  7. java类使用其他类的变量_如何将java类中的变量加载到其他类
  8. Windows内核原理-同步IO与异步IO
  9. XAML 布局StackPanel
  10. lis最长上升子序列o(nlogn)优化