优化网站内容,预付网站建设费会计处理,商丘住房和城乡建设厅网站,用华为云建立Wordpress网站servlet servlet是前端和数据库交互的一个桥梁 静态网页资源的技术#xff1a;在前端整个运行的过程中 我们的网页代码不发生改变的这种情况就称为静态的网页资源技术动态网页资源的技术#xff1a;在前端运行的过程中 我们的前端页面代码会发生改变的这种情况就称为 动态的网… servlet servlet是前端和数据库交互的一个桥梁 静态网页资源的技术在前端整个运行的过程中 我们的网页代码不发生改变的这种情况就称为静态的网页资源技术动态网页资源的技术在前端运行的过程中 我们的前端页面代码会发生改变的这种情况就称为 动态的网页资源技术 servlet的生命周期 生命周期 就是这个Servlet从创建到销毁的整个过程 问题来了Servlet什么时候创建呢?默认情况下 程序启动是不会 创建Servlet对象的程序在第一次启动的时候 创建对象 执行init方法那么有没有方法在程序启动的时候 就让Tomcat将这个对象创建好呢?WebServlet(urlPatterns /ticket/sell,loadOnStartup 1)servlet!-- 这个名字逻辑上可以随便写 但是一般见名之意 写这个类的类名--servlet-nameUserServlet/servlet-name!-- 这个配置的是Servlet的全路径--servlet-classcom.qfedu.edu.servlet.UserServlet/servlet-class!--load-on-startup1/load-on-startup 是一个在web.xml文件中常见的参数配置。它用于指定在应用程序启动时是否要立即加载某个Servlet或其他组件。当设置为1时表示在应用程序启动时立即加载当设置为0时表示不立即加载而是在第一次请求时才加载。--load-on-startup1/load-on-startup/servlet程序的销毁是在 Tomcat关闭的时候 这个Servlet才会被销毁 全局参数 所谓的这个全局的参数指的是 在任何一个Servlet中都能取到这个参数 那么这个参数就是全局参数 在web.xml中申明全局参数 !-- 申明全局参数--context-paramparam-namefilename/param-nameparam-valuetest.txt/param-value/context-paramcontext-paramparam-name键/param-nameparam-value值/param-value/context-param 局部参数 Request对象 tomcat将请求封装成了一个对象这个对象就是Request Request相关方法 //req中参数的含义
//http://localhost:8080/users?usernameadminpassword123456%E8%AF%B7%E6%B1%82%E6%8F%90%E4%BA%A4
// /users
String requestURI req.getRequestURI();//端口之后问号之前的数据
String method req.getMethod(); //获取请求的方法
//String parameter req.getParameter();通过名字请求参数
req.getContextPath();//获取上下文信息
req.getCookies(); //cookies信息获取
req.getHeaderNames();//获取HTTP协议中所有的key
req.getRequestURL();//获取请求地址 Request获取请求数据 GET String queryString req.getQueryString();
System.out.println(获取到的数据是queryString);
//获取到的数据是username%E5%BC%A0%E4%B8%89password123456%E8%AF%B7%E6%B1%82%E6%8F%90%E4%BA%A4
//获取到的数据是加密的使用的是URLEncode编码
//要使用URLDecode解码
String decode URLDecoder.decode(queryString,UTF-8);
System.out.println(decode);
//
//如果是tomcat8以前的版本会出现乱码问题
//因为tomcat在处理数据的时候将这些数据进行了ISO-8859-1的编码
//这个ISO-8859-1是欧洲人的编码
//解决办法是先采用ISO-8859-1解码后再采用汉字编码重新编码再解码就可以了
String username req.getParameter(username);
String password req.getParameter(password);//解码
// byte[] bytes username.getBytes(ISO-8859-1);
// usernamenew String(bytes,UTF-8);System.out.println(usernamepassword); URL和URI的区别 URI统一资源标记符 不光可以标记本地资源还可以标记网络资源 URL统一资源定位符 只能定位网络资源 从范围上看URL的范围小于URI POST public class RequestParameterServlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//第一种方式getParameter//设置编码格式
// req.setCharacterEncoding(UTF-8);
// String username req.getParameter(username);
// String password req.getParameter(password);
// System.out.println(username:username-----password:password);//第二种方式流 post方式都可以使用流来获取ServletInputStream in req.getInputStream();//将输入流放到缓冲区byte[] buf new byte[8192];int readLength in.read(buf);String val new String(buf, 0, readLength);String values URLDecoder.decode(val,UTF-8);System.out.println(取出的数据是values);}Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//get第第一种方式String queryString req.getQueryString();System.out.println(queryString);//URLEncode编码String values URLDecoder.decode(queryString, UTF-8);System.out.println(获取到的数据时values);//username%E5%BC%A0%E4%B8%89password123456//第二种方式String username req.getParameter(username);String password req.getParameter(password);//????是ISO-8859-1编码需要解码byte[] bytes username.getBytes(ISO-8859-1);username new String(bytes, UTF-8);byte[] bytepwd password.getBytes(ISO-8859-1);password new String(bytepwd, UTF-8);System.out.println(username:username-----password:password);}
} Response对象的使用 http响应码 对于HTTP协议的这样一个请求 的响应码很重要 200表示的是请求成功302重定向错误(多次重定向)400服务器接受到数据了 但是无法处理参数 简单的说就是参数不匹配401未认证403没权限访问404路径没对500服务器报错 页面转发 转发的特点是啥?转发的时候请求地址不变 转发只能转发到服务器的内部 不能抓没法到第三方的服务器上 转发是一次性的请求 req 统一的一个转发如何实现 req.getRequestDispatcher(/teudan.html).forward(req,resp); 页面重定向 重定向的特点地址会发生改变重定向是可以定位到任意的服务器的重定向的请求和原始的请求不是一个 resp.sendRedirect(http://www.baidu.com); 响应数据的编写 //响应数据给客户端
//你就告诉他编码是啥
resp.setContentType(text/html;charsetutf-8);
PrintWriter writer resp.getWriter();
writer.write(小波波最帅);
writer.flush();
writer.close(); json格式 Filter 什么是过滤器呢? 所谓的过滤器 你可以认为 这个请求和响应都要经过他、经过他的时候他就可以干预你 这个Filter就是横跨在 我们的前端请求 和 Servlet之间的一个桥梁 这个Filter可以单独的对我们的请求 和 响应 进行干预(改变他|拦截他) 这个Filter的出现 就是为了规避Java中的一个职责 (单一职责)-----实际上是一个 责任链的设计模式 单一职责自己的事情自己干 浏览器上发送的请求 默认都是 get请求 Filter的使用 filter的编写 public class AuthticationFilter implements Filter {/*** 请求和响应都会经过这个方法** param servletRequest* param servletResponse* param filterChain* throws IOException* throws ServletException*/public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {System.out.println(过滤器执行了....之前);//这句话的意思就是放行...//filterChain.doFilter(servletRequest,servletResponse);System.out.println(过滤器执行了....之后);}
} 编写声明 !-- 配置 --filterfilter-nameAuthticationFilter/filter-namefilter-classcom.qfedu.edu.filter.AuthticationFilter/filter-class
/filterfilter-mappingfilter-nameAuthticationFilter/filter-nameurl-pattern/*/url-pattern
/filter-mapping 第二种使用方式 WebFilter(urlPatterns /*)
public class BlackFilter implements Filter {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println(黑名单的Filter----之前);
filterChain.doFilter(servletRequest, servletResponse);
System.out.println(黑名单的Filter----之后);
}
} Filter的生命周期 在程序启动的时候创建Filter对象对象创建完成调用init方法进行对资源的初始化操作当Tomcat关闭的时候这个Filter的destroy执行 参数的初始化 package com.wz.practice.servlet.filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;WebFilter(urlPatterns /*,initParams {WebInitParam(namekey1,value val1)
})
public class AuthenticationFilter implements Filter {public AuthenticationFilter() {System.out.println(AuthenticationFilter创建对象);}/*** 资源初始化** param filterConfig 这个参数拿到你设计的全局变量或局部变量* throws ServletException*/public void init(FilterConfig filterConfig) throws ServletException {System.out.println(AuthenticationFilter--init执行的地方);String test filterConfig.getServletContext().getInitParameter(test);System.out.println(拿到的(全局)参数值是test);//下面这个方法只能拿到自己的参数String key1 filterConfig.getInitParameter(key1);System.out.println(拿到的局部参数是key1);}/*** 拦截请求** param servletRequest* param servletResponse* param filterChain* throws IOException* throws ServletException*/public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println(请求之前的拦截);filterChain.doFilter(servletRequest, servletResponse);System.out.println(请求之后的拦截);}public void destroy() {System.out.println(destory执行的地方);}
} !DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd web-appdisplay-nameArchetype Created Web Application/display-namecontext-paramparam-nametest/param-nameparam-value123/param-value/context-param/web-app Filter的运行原理 配置模式下这个运行顺序的问题 !--申明Filter--
filterfilter-nameAuthFilter/filter-namefilter-classcom.wz.practice.filter.AuthFilter/filter-class
/filter
filterfilter-nameBlackFilter/filter-namefilter-classcom.wz.practice.filter.BlackFilter/filter-class
/filter
filterfilter-nameLimitFilter/filter-namefilter-classcom.wz.practice.filter.LimitFilter/filter-class
/filter!--谁先申明谁先执行--
filter-mappingfilter-nameLimitFilter/filter-nameurl-pattern/*/url-pattern
/filter-mapping
filter-mappingfilter-nameAuthFilter/filter-nameurl-pattern/*/url-pattern
/filter-mapping
filter-mappingfilter-nameBlackFilter/filter-nameurl-pattern/*/url-pattern
/filter-mapping 注解方式的顺序 注解方式的时候 跟这个Filter名字字母的先后顺序有关系 排在前面的先执行 排在后面的后执行 混合方式的顺序 先配置 在按照注解的Filter的手写字母排序 配置 注解排序 责任链的设计模式 需求通过一个全局的过滤器 执行到自定义的这个链条中来 这个自定义的链条就可以实现 限流 降级 认证 鉴权 黑名单校验 敏感词校验 .....责任链的设计模式主要实现的功能就是 过滤器 或者拦截器 给所有的链编写一个父接口(BaseSlot) package com.wz.practice.slot.base;import javax.servlet.http.HttpServletRequest;/**
* 我们这里的目的是为了实现仿写
* 给这个过滤器整了个爹 这个接口类似于我们的 Filter接口
*/
public interface BaseSlot {/*** 这个就要要处理的方法* 这个方法类似于我们的 doFilter方法* param req*/void dealReq(HttpServletRequest req);
} 给这个BaseSlot的执行 编写一个父接口 最终需要一个类去调用这个BaseSlot的所有孩子 SlotChain package com.wz.practice.slot.base;import javax.servlet.http.HttpServletRequest;/**
* 这个接口的抽象是为了调用BaseSlot的实现类的
*/
public interface SlotChain {/*** 这个就要要处理的方法* 这个方法类似于我们的 doFilter方法** param req*/void dealReq(HttpServletRequest req);
} 编写链条 --------- 给这个BaseSlot编写实现类 package com.wz.practice.slot.impl;import com.wz.practice.slot.base.BaseSlot;import javax.servlet.http.HttpServletRequest;public class AuthSlot implements BaseSlot {public void dealReq(HttpServletRequest req) {System.out.println(----AuthSlot-----------);}
}package com.wz.practice.slot.impl;import com.wz.practice.slot.base.BaseSlot;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;public class BlackSlot implements BaseSlot {public void dealReq(HttpServletRequest req) {System.out.println(-------BlackSlot--------);}
}package com.wz.practice.slot.impl;import com.wz.practice.slot.base.BaseSlot;import javax.servlet.http.HttpServletRequest;public class LimitSlot implements BaseSlot {public void dealReq(HttpServletRequest req) {System.out.println(-------LimitSlot--------);}
} 编写链条的调用者 -------- SlotChain的实现类 在SlotChainImpl中去申明我们的BaseSlot的容器 package com.wz.practice.slot.impl;import com.wz.practice.slot.base.BaseSlot;
import com.wz.practice.slot.base.SlotChain;import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;public class SlotChainImpl implements SlotChain {private static MapString, BaseSlot maps new ConcurrentHashMapString,BaseSlot();private static String slotOrder;static {maps.put(authSlot,new AuthSlot());maps.put(blackSlot,new BlackSlot());maps.put(limitSlot,new LimitSlot());//资源加载InputStream in SlotChainImpl.class.getClassLoader().getResourceAsStream(slot.properties);Properties properties new Properties();try {properties.load(in);slotOrder (String) properties.get(slotOrder);} catch (IOException e) {e.printStackTrace();}}public void dealReq(HttpServletRequest req) {if(maps.size()0){throw new RuntimeException(slot数据为空无法启动链条);}if(.equals(slotOrder)||nullslotOrder){throw new RuntimeException(slot执行顺序未定义....);}//执行到这里两边都有值if(!slotOrder.contains(,)){//说明只有一个值BaseSlot baseSlot maps.get(slotOrder);handlerSimpleSlot(req, baseSlot);return ;}//程序如果是执行到这里 说明有多个名字String[] split slotOrder.split(,);for (int i 0; i split.length ; i) {//取出这个名字String slotName split[i];//说明只有一个值BaseSlot baseSlot maps.get(slotName);//接下来从maps中取出数据handlerSimpleSlot(req, baseSlot);}}/*** 处理单个Slot* param req* param baseSlot*/private static void handlerSimpleSlot(HttpServletRequest req, BaseSlot baseSlot) {if(null baseSlot){throw new RuntimeException(slot执行顺序的名字不对);}//执行到这里说明名字是对的baseSlot.dealReq(req);}
} 给这个BaseSlot编写调用顺序----slot.properties slotOrder limitSlot,authSlot,blackSlot 在SlotChainImpl中去进行BaseSlot链条的调用 package com.wz.practice.filter;import com.wz.practice.slot.base.SlotChain;
import com.wz.practice.slot.impl.SlotChainImpl;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/**
* 全局过滤器
*/
WebFilter(urlPatterns /*)
public class GlobleFilter implements Filter {private SlotChain slotChain new SlotChainImpl();public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {try {slotChain.dealReq((HttpServletRequest) servletRequest);} catch (Exception e) {System.out.println(执行到了异常);}}
} 代理的设计模式 代理模式的主要实现功能是什么 对方法进行监听在执行方法是动态的植入我们的代码 静态代理 静态代理和动态代理被代理的类必须实现接口 静态代理的步骤1、编写一个代理类和被代理类实现相同的接口2、在这个代理类维护被代理类的类对象3、在下面的方法中调用被代理类中相同名字的方法就能完成代理 静态代理的步骤 编写接口 package com.wz.practice.proxy.static1;public interface IUserService {void add();void update();
} 编写被代理类 package com.wz.practice.proxy.static1;public class UserService implements IUserService{public void add() {System.out.println(-------add执行------);}public void update() {System.out.println(--------update执行-----);}
} 编写代理类 package com.wz.practice.proxy.static1;public class UserServiceProxy implements IUserService{//在这个类中维护被代理的对象private IUserService userService;public UserServiceProxy(IUserService userService){this.userServiceuserService;}//在下面的方法中调用 被代理类中相同名字的方法 就可以完成监控了public void add() {System.out.println(打开事务);userService.add();System.out.println(提交事务);}public void update() {System.out.println(打开事务);userService.update();System.out.println(提交事务);}
} 测试 package com.wz.practice.proxy.static1;public class test {public static void main(String[] args) {UserServiceProxy userServiceProxy new UserServiceProxy(new UserService());userServiceProxy.update();userServiceProxy.add();}
} 结果 动态代理(JDK代理) 静态代理和动态代理被代理的类必须实现接口 整个代理的过程被JDK实现了 Proxy.newProxyInstance 动态代理的步骤 编写接口 package com.wz.practice.proxy.dynamic;public interface IUserService {void add();void update();
} 编写被代理的类 package com.wz.practice.proxy.dynamic;public class UserService implements IUserService{public void add() {System.out.println(-------add执行-------);}public void update() {System.out.println(---------update执行-----);}
} 测试 package com.wz.practice.proxy.dynamic;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class Test {public static void main(String[] args) {/*** 第一个参数类加载器 这个是有固定的写法* 被代理的类.class.getClassLoader* 第二个参数就是我们被代理的类实现的接口* 如果被代理的是类被代理的类.class.getInterfaces();* 如果被代理的是接口new Class[]{被代理的接口.class}* 第三个参数就是对这个代理的类或者接口中方法执行的监听* new InvocationHandler(){}*/IUserService userServiceProxy (IUserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), UserService.class.getInterfaces(), new InvocationHandler() {/*** 这个方法就是对你当前执行方法的监听* proxy代理类对象* method当前执行的方法* args执行方法需要的参数* return* throws Throwable*/public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(打开事务);String name method.getName();System.out.println(当前执行的方法是name);//可以去执行这个方法//这里的第一个参数被代理类的对象Object invoke method.invoke(new UserService(), args);System.out.println(提交事务.....);return invoke;}});userServiceProxy.add();userServiceProxy.update();}
}