欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 编程语言 > java >内容正文

java

【java12】tomcatservlet(nginx,web.xml,生命周期,适配器优化),requestresponse(请求转发,登陆案例(1),重定向,文件下载) -凯发k8官方网

发布时间:2024/4/24 java 162 豆豆

文章目录

  • 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

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等待时间拿来用)

原生nginx没有集成很多插件,使用不方便。推荐使用openresty(在nginx基础上集成了很多lua写的插件),凯发k8官方网官网下载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 端口根据权重切换。

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。


如下选中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,全限定名就是全类名就是包名加类名)对应关系。

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 <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>myservlet01servlet-name><servlet-class>com.itheima01.servlet.myservletservlet-class>servlet><servlet-mapping><servlet-name>myservlet01servlet-name><url-pattern>/myurl-pattern>servlet-mapping><servlet><servlet-name>lifecycleservletservlet-name><servlet-class>com.itheima02.life.lifecycleservletservlet-class>servlet><servlet-mapping><servlet-name>lifecycleservletservlet-name><url-pattern>/lifeurl-pattern>servlet-mapping><servlet><servlet-name>goodservletservlet-name><servlet-class>com.itheima03.good.goodservletservlet-class>servlet><servlet-mapping><servlet-name>goodservletservlet-name><url-pattern>/goodurl-pattern>servlet-mapping><servlet><servlet-name>betterservletservlet-name><servlet-class>com.itheima03.good.betterservletservlet-class>servlet><servlet-mapping><servlet-name>betterservletservlet-name><url-pattern>/betterurl-pattern>servlet-mapping> web-app>


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

只留一个接口叫适配器设计模式。将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 {} }

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

file-new-project-java enterprise。

doctype html> <html lang="en"> <head><meta charset="utf-8"><title>titletitle> head> <body><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 getrequest : 获取客户端发出请求完整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请求中最后一行不是请求体,是谷歌浏览器工具抓包进行的参数强调渲染。

doctype html> <html lang="en"> <head><meta charset="utf-8"><title>titletitle> head> <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 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遍历出来的结果和下面第一行一样。

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

如下forward方法中request是邮件及内容,response是回应权限。a模块指myservlet,b模块指zhouservlet。一次请求链如下只有一去一回。

doctype html> <html lang="en"> <head><meta charset="utf-8"><title>titletitle> head> <body> 人事<a href="/shiservlet?msg=有人来面试">发送邮件a> 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~~");} }



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> <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>



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"); //新页面显示 // response.setheader("content-type","text/html;charset=utf-8"); //点击网页上refreshand..跳转新页面显示 哈哈response.setcontenttype("text/html;charset=utf-8"); //setcontenttype是简易api,同上一行response.getwriter().print(""); } }

因为重定向不是一次请求链,所以超过域对象,不能用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。

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

//02文件下载.html <html lang="en"> <head><meta charset="utf-8"><title>titletitle> head> <body><a href="/downloadservlet?file=1.zip">1.zipa> <br><a href="/downloadservlet?file=2.exe">2.exea> <br><a href="/downloadservlet?file=3.txt">3.txta> <br><a href="/downloadservlet?file=4.jpg">4.jpga> <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访问。

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


与50位技术专家面对面20年技术见证,附赠技术全景图

总结

以上是凯发k8官方网为你收集整理的【java12】tomcatservlet(nginx,web.xml,生命周期,适配器优化),requestresponse(请求转发,登陆案例(1),重定向,文件下载)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图