热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

web基础2servlet入门1(request,response)

web基础2-servlet入门1(request,response)一、Servlet1.1servlet简介Servlet就是sun公司开发动态web的一门技术Sun在这些AP

web基础2-servlet入门1(request,response)

一、Servlet


1.1 servlet简介



  • Servlet就是sun公司开发动态web的一门技术



  • Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成3个步骤:



    • 编写一个类,实现servlet接口

    • 把开发好的Servlet注册在web.xml中

    • 把开发好的JAVA类部署到web服务器中



把实现了Servlet接口的java程序叫做servlet


1.2 第一个servlet-HelloServlet


servlet在sun公司有两个默认继承类,Httpservlet,GenericServlet



1.2.1 构建父子工程。(也可以不用父子工程)

构建一个普通的maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立module了。这个空的工程就是maven主工程。详细见1.3


1.2.2 Maven环境优化



  • 修改web.xml为最新的,换头

  • 将maven的结构搭建完毕


1.2.3 编写一个servlet程序



  • 编写一个普通类

  • 实现一个servlet接口,我们这里直接继承Httpservlet


idea中查看继承关系树

方法一:

ctrl+H

方法二:

ctrl+alt+U


1.2.4 编写servlet映射

为什么需要映射:我们写的是java程序,但是要通过浏览器访问,而浏览器需要连接的web服务器,所以我们需要:



  • 在web服务器中注册我们写的servlet



  • 还需要给他一个浏览器能够访问的路径。





helloServlet
com.happy.servlet.HelloWorld


helloServlet

/hello


1.2.5 配置tomcat

注意:配置项目发布的路径即可


1.3 关于maven 父子工程的理解

注意:有时候用idea创建子项目的时候,parent标签会丢失,注意检查项目

父项目中会有


servlet-01

子项目中会有


PureMavenWeb
org.example
1.0-SNAPSHOT

父项目中的java子项目可以直接使用,而子项目中的父项目不能使用。同多态一样。


二、servlet原理


三、Mapping问题


3.1 一个Servlet请求可以指定一个映射路径



helloServlet
com.happy.servlet.HelloWorld


helloServlet

/hello


3.2 一个Servlet可以指定多个映射路径


helloServlet
com.happy.servlet.HelloWorld


helloServlet

/hello


helloServlet

/hello2


3.3 一个Servlet可以指定通用映射路径


helloServlet

/hello/*


3.4 自定义后缀实现请求映射

注意:前面不能加映射的路径,如/hello/*.do


helloServlet
com.happy.servlet.HelloWorld


helloServlet

*.do


3.5 默认请求路径(兜底)


helloServlet
com.happy.servlet.HelloWorld


helloServlet

/*


3.6 优先级匹配

指定了固有的映射路径=》优先级最高。

如果找不到就会走默认的处理请求/*


四、servlet重要对象和API


4.1 init-parm vs context-param


loginServlet
com.qcc.study.servlet02.LoginServlet


initParam

qcc


0


loginServlet
/login


contextParam

admin

配置在标签中,用来初始化当前的Servlet的,属于当前Servlet的配置,因此存放在 servletConfig对象中;

通过getServletConfig().getInitParameter("initParam")的方式获取;

直接配置在web.xml的标签中,属于上下文参数,在整个web应用中都可以使用,它是全局的,因此存放在servletContext对象中(即application对象);

通过getServletContext().getInitParameter("contextParam")的方式获取;

4.2 ServletContext


web容器在启动的时候,他会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用。(在容器启动时候就有)


作用:


4.2.1 共享数据


我在这servlet中保存的数据,可以在另外一个servlet获取。

注意:实际工作中,一般不用servletContext存取数据,一般用session和COOKIE和request存取数据


一个servlet用于通过ServletContext来set数据

package com.happy.servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class SetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
ServletContext servletCOntext= this.getServletContext();
//
//
//

happyContextParam
//

admin
//
String happy = servletContext.getInitParameter("happyContextParam");
System.out.println(happy);
int i=0;
Object object= servletContext.getAttribute("happy");
if (object==null){
i=0;
} else {
i=(int)object+1;
}
servletContext.setAttribute("happy",i);
ServletConfig servletCOnfig= this.getServletConfig();
String happyServletParam = servletConfig.getInitParameter("happyServletParam");
System.out.println(happyServletParam);
PrintWriter writer = resp.getWriter();
writer.println("访问次数+1");
writer.println("http://localhost:8080/s2/get");
System.out.println(i);
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPut(req, resp);
}
}

一个servlet用于通过ServletContext来get数据

package com.happy.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletCOntext= this.getServletContext();
Object happy = servletContext.getAttribute("happy");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("访问次数共计:"+happy);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}

web.xml如下

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"
metadata-complete="true">


happyContextParam

admin


SetServlet
com.happy.servlet.SetServlet

happyServletParam

happyvalue



SetServlet
/set/*


GetServlet
com.happy.servlet.GetServlet


GetServlet
/get



4.2.2 获取初始化参数


可以用来配置一些web应用初始化参数

注意:实际工作中一般不在web.xml中放参数,而用properties文件等存全局参数




happyContextParam

admin


setByConf

setByConfValue

package com.happy.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class GetInitParamsServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletCOntext= this.getServletContext();
String setByCOnf= (String)servletContext.getInitParameter("setByConf");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("setByConf:"+setByConf);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}

4.2.3 请求转发


实际工作中一般不用ContextServlet对象的dispatcher,而用response对象的dispatcher方法


package com.happy.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ContextDispatcherServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletCOntext= this.getServletContext();
servletContext.getRequestDispatcher("/get").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}


ContextDispatcherServlet
com.happy.servlet.ContextDispatcherServlet


ContextDispatcherServlet
/cds


4.2.4 读取项目资源文件


实际工作中一般不用这个api,而是用反射和类加载等加载资源文件



前景补充知识

关于classpath


  • java目录,作为source目录

  • resources目录,作为resources目录

对回被打包到同一个路径下:classes,我们俗称这个路径为classpath:


maven构建时候,部分source目录下面资源文件不能打包问题

解决方案:在build中配置resources.来防止我们资源导出失败的问题




src/main/resources

**/*.properties
**/*.xml

true


src/main/java

**/*.properties
**/*.xml

true




获取资源文件

写一个servlet调用context对象的获取资源文件的api方法getResourceAsStream

InputStream is = servletContext.getResourceAsStream("/WEB-INF/classes/db.properties");


PropertiesServlet
com.happy.servlet.PropertiesServlet


PropertiesServlet
/ps

package com.happy.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletCOntext= this.getServletContext();
InputStream is = servletContext.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(is);
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
response.getWriter().println(url+" "+username+" "+password);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}

效果如下:


4.3 HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个httpServeletResponse。



  • 如果要获取客户端请求过来的参数:找HttpServeletRequest

  • 如果要给客户端响应一些信息:找HttpServeletResponse


4.3.1 HttpServletResponse简单分类


负责向浏览器发送数据的方法

ServletOutputStream getOutputStream() throws IOException; //其他,如果老用中文会造成字符窜丢失
PrintWriter getWriter() throws IOException; //中文

负责向浏览器设置响应头方法

void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setBufferSize(int var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
void setStatus(int var1);

响应的状态码:

int SC_COnTINUE= 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_COnTENT= 204;
int SC_RESET_COnTENT= 205;
int SC_PARTIAL_COnTENT= 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_COnFLICT= 409;
int SC_GOnE= 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LOnG= 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

4.3.2 HttpServletResponse常见应用


1. 向浏览器输出消息

2.下载文件resp.setHeader("Content-disposition","attachment;filename"+filename);

核心:

resp.setHeader("Content-disposition","attachment;filename="+filename);

URLEncoder.encode(filename,"utf-8")) //解决文件名乱码


  1. 要获取下载文件的路径

  2. 下载文件名是啥

  3. 设置想办法让浏览器能够支持下载我们需要的东西

  4. 获取下载文件的输入流

  5. 创建缓存区

  6. 获取OutputStream对象

  7. 将FIleOutputStream流写入到buffer缓冲区

  8. 使用outputstream将缓冲区中的数据输出到客户端

package com.happy.servlet;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class DownServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/* 1. 要获取下载文件的路径
2. 下载文件名是啥
3. 设置想办法让浏览器能够支持下载我们需要的东西
4. 获取下载文件的输入流
5. 创建缓存区
6. 获取OutputStream对象
7. 将FIleOutputStream流写入到buffer缓冲区
8. 使用outputstream将缓冲区中的数据输出到客户端*/
String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/书.jpg");
System.out.println(realPath);
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
System.out.println(filename);
// resp.setHeader("Content-disposition","attachment;filename"+filename);
String userAgent = req.getHeader("USER-AGENT");
if (StringUtils.contains(userAgent, "MSIE") || StringUtils.contains(userAgent, "Edge")) {
// IE浏览器
filename = URLEncoder.encode(filename, "UTF-8");
} else if (StringUtils.contains(userAgent, "Firefox") || StringUtils.contains(userAgent, "Chrome") || StringUtils.contains(userAgent, "Safari")) {
// google,火狐浏览器
// filename = new String(filename.getBytes(), "ISO-8859-1");
filename = URLEncoder.encode(filename, "UTF-8");
} else {
filename = URLEncoder.encode(filename, "UTF-8");
// 其他浏览器
}
System.out.println(filename);
resp.setHeader("Content-disposition", "attachment;filename=" + filename);
// 创建输入流,把文件变成流
FileInputStream is = new FileInputStream(realPath);
// 创建输出流
ServletOutputStream os = resp.getOutputStream();
// 创建缓存区,new 一个byte【】作为byte
byte[] buff = new byte[1024];
int len = 0;
try {
System.out.println("开始读取数据");
while ((len = is.read(buff)) > 0) {
os.write(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
is.close();
os.close();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

3.生成验证码

原生生成验证码方法:

package com.happy.servlet;
import org.junit.jupiter.api.Test;
import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 前端刷新为windows.location.refresh
// 通过后端响应给前端设置头信息,响应可以设置前端所有东西
response.setHeader("refresh","8");
BufferedImage bufferedImage=drawNum();
// 告诉浏览器,这个请求的响应用图片方式打开
response.setContentType("image/png");
// 取消缓存
response.setDateHeader("expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
boolean jpg = ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Test
public BufferedImage drawNum(){
// 在内存中创建一个空白的图片
BufferedImage bufferedImage = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();
// 设置图片的背景颜色
graphics.setColor(Color.white);
// 画边框
graphics.fillRect(0,0,80,20);
// 给图片写数据
graphics.setColor(Color.blue);
graphics.setFont(new Font(null,Font.BOLD,20));
graphics.drawString(makeNum(),0,20);
return bufferedImage;
}
public String makeNum(){
Random random = new Random();
String num = String.valueOf(random.nextInt(999999+1));
StringBuffer sb = new StringBuffer(num);
for(int i=0;i<=5-num.length();i++){
sb.append(0);
}
return sb.toString();
}
}


4.实现重定向

本质上是302和location设置重定向地址


response.sendRedirect();

常见场景:



  • 用户登陆

package com.happy.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 方式一
// 可以直接重定向到外部网站
// response.sendRedirect("http://www.baidu.com");
// 也可以内部地址,要带项目名
response.sendRedirect("/response/image");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}

所以本质上是302和location设置重定向地址

// 方式二,拆分两步
response.setHeader("Location","/response/image");
// response.setStatus(302);
response.setStatus(HttpServletResponse.SC_FOUND);

重定向和转发的区别





















重定向转发
相同点页面实现跳转页面实现跳转
不同点url地址栏会发生变化url不会产生变化

${pageContext.request.contextPath}


登陆跳转(重定向实战)

index.jsp作为登陆页面如下:

<%@ page cOntentType="text/html;charset=UTF-8" language="java" %>





<%--这里提交的路径,需要寻找项目的路径--%>
<%----%>

用户:
密码:




web.xml配置映射


FormServlet
com.happy.servlet.FormServlet


FormServlet
/login

处理servlet

package com.happy.servlet;
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 FormServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("进入这个请求了");
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username+":"+password);
response.sendRedirect("/response/success.jsp");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}

4.4 HttpServletRequest


4.4.1 响应重定向和请求转发


重定向和转发的区别


























重定向转发
相同点页面实现跳转页面实现跳转
不同点url地址栏会发生变化url不会产生变化
状态码302307

重定向response.sendRedirect

注意:重定地址(外部地址)要带项目名

获取方式:



  1. 写死response.sendRedirect("projectContextName/success.jsp");



  2. this.getServletContext().getContextPath()
    response.sendRedirect(this.getServletContext().getContextPath()+"/success.jsp");


  3. request.getContextPath()
    response.sendRedirect(request.getContextPath()+"/success.jsp");




转发request.getRequestDispatcher

注意:转发地址(内部地址)不用带项目名



转发this.getServletContext().getRequestDispatcher

4.4.2 获取前端参数

package com.happy.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.Arrays;
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username+":"+password);
String[] hobbies = request.getParameterValues("hobbies");
System.out.println(Arrays.toString(hobbies));
System.out.println(this.getServletContext().getContextPath());
System.out.println(request.getContextPath());
// 方式一:response redirect转发
// response.sendRedirect(this.getServletContext().getContextPath()+"/success.jsp");
// 方式二:servletContext 重定向
// this.getServletContext().getRequestDispatcher("/success.jsp").forward(request,response);
//方式三:request 重定向
request.getRequestDispatcher("/success.jsp").forward(request,response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}


推荐阅读
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • Apache Shiro 身份验证绕过漏洞 (CVE202011989) 详细解析及防范措施
    本文详细解析了Apache Shiro 身份验证绕过漏洞 (CVE202011989) 的原理和影响,并提供了相应的防范措施。Apache Shiro 是一个强大且易用的Java安全框架,常用于执行身份验证、授权、密码和会话管理。在Apache Shiro 1.5.3之前的版本中,与Spring控制器一起使用时,存在特制请求可能导致身份验证绕过的漏洞。本文还介绍了该漏洞的具体细节,并给出了防范该漏洞的建议措施。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 标题: ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有