Java后端进阶之路: JavaWeb(一)https://developer.aliyun.com/article/1469547
5.Maven
我为什么要学习这个基数
- 在javaweb开发中,需要使用大量的jar包,我们需要去手动去导入jar包
- 如何能够让一个东西自动帮我们导入和配置这些jar包
由此,Maven诞生了!
5.1Maven项目架构管理工具
我们目前用它来方便导入jar包
Maven核心思想:约定大于配置
- 有约束,不要去违反
Maven会规定好你该如何去编写java代码,目录结构必须要按照这个规范来
5.2下载安装Maven
官网网址:https://maven.apache.org/download.cgi
下载完成后解压即可:
建议:电脑上的所有环境都放在一个文件夹下方便管理
5.3配置环境变量
在系统环境变量之中
配置如下:
- M2_HOME maven目录下的bin目录
- MAVEN_HOME maven 的目录
- 在系统的path中配置MAVEN_HOME目录 %MAVEN_HOME%\bin
5.4阿里云镜像
- 镜像:mirrors
- 作用:加速下载
- 建议使用阿里云
2 <mirror> 3 <id>nexus-aliyun</id> 4 <mirrorOf>*</mirrorOf> 5 <name>Nexus aliyun</name> 6 <url>http://maven.aliyun.com/nexus/content/groups/public</url> 7 </mirror>
5.5本地仓库repository
本地仓库,远程仓库
建立一个本地仓库:
<localRepository>D:\apache-maven-3.6.3\maven-repo</localRepository>
5.6在idea使用maven
- 启动idea
- 创建一个maven项目
- 等待项目初始化完毕
4.观察maven仓库多了什么东西
5.idea中maven设置
注意:IDEA创建成功后看一眼maven的配置,
6.到这,maven在IDEA的配置和使用就ok了
5.7创建一个普通的maven项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZfdyIk91-1648909270901)(C:\Users\doomwstcher\AppData\Roaming\Typora\typora-user-images\image-20210329144558685.png)]
5.9在idea配置tomcat
解决警告问题
必须配置,为什么会有问题,我们访问一个网站,需要指定一个文件夹的名字;
5.10pom文件
pom.xml是Maven的核心配置文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--创建项目的时候生成的配置gav--> <groupId>com.hyc</groupId> <artifactId>javaweb01-maven</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>javaweb01-maven Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <!-- 项目依赖文件--> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <!--项目构建文件--> <build> <finalName>javaweb01-maven</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
maven由于约定大于配置,会出现我们之后遇到写的配置文件无法被导出或者生效的问题,
解决方案:
<!-- 配置resouce来防止我们导出失败的问题--> <build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <exclude>**/*.properties</exclude> <exclude>**/*.xml</exclude> </excludes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
6.Servlet
6.1什么是Servlet
- sun公司开发动态web的一门技术
- sun公司在api中提供了一个借口叫Servlet,你想开发Servlet程序。只需要两个小步骤
- 编写一个类,实现Servlet接口
- 把开发好的java类部署到web服务器中
把实现了Servlet接口的java程序叫做Servlet
6.2 HelloServlet
Servlet接口有两个默认的实现类:httpServlet,GenericServlet
- 构建一个普通的maven项目,删掉里面的src目录,以后我们的学习就在这里面建立moudel;这个空的工程就是maven的主工程
- 关于maven父子工程的理解:
- 父项目中会有:
<modules> <module>Servlet-01</module> </modules>
子项目中会有:
<parent> <artifactId>javaweb-maven-02</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent>
- Maven环境优化
- 修改web.xml为最新的
- 将Maven的结构搭建完整
- 编写一个Servlet程序
- 编写一个普通类
- 继承接口实现类
package com.hyc.servlet; 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 helloServlet extends HttpServlet { //get,post只是请求实现的不同的方式,可以相互调用,应为业务逻辑都一样 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.print("Hello,servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
- 编写Servlet的映射
为什么需要映射呢,我们写的是java程序,通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中出册我们写的Servlet,还需要给他一个浏览器访问的url
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1" metadata-complete="true"> <display-name>Welcome to Tomcat</display-name> <description> Welcome to Tomcat </description> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.hyc.servlet.helloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
- 配置tomcat
配置项目发布路径 - 启动测试
6.3servlet原理
Servlet是由web服务器调用,web服务器在收到浏览器请求之后会:
6.4Mapping
- 一个servlet可以指定一个映射路径
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.hyc.servlet.helloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
- 一个sevlet可以指定多个映射路径
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.hyc.servlet.helloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello1</url-pattern> </servlet-mapping>
- 一个sevlet可以指定默认映射路径(尽量不要去写)
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
- 一个sevlet可以指定前缀或者是后缀映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello1/*</url-pattern> </servlet-mapping>
6.5优先级问题
指定了固有映射路径的优先级最高,如果找不到怎么办那么就会进行默认的
<!--404--> <servlet> <servlet-name>err</servlet-name> <servlet-class>com.hyc.servlet.errServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>err</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
6.6ServletContext
web容器的启动时,它会为每个web程序都创建一个对应ServletContext对象,它代表了当前的web应用。
1.共享数据
在一个servlet的数据可以从另一个servlet拿到
- 共享数据
我在这个servlet中保存的数据,可以在另外一个servlet中拿到
package com.hyc.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; public class getServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); ServletContext context = this.getServletContext(); String name =(String)context.getAttribute("username"); resp.getWriter().print(name); } }
测试结果
2.获取初始化参数
设置初始化参数
<context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost/3306/mybaties</param-value> </context-param>
读取参数
resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); ServletContext context = this.getServletContext(); String name =(String)context.getAttribute("username"); String url =(String)context.getInitParameter("url"); resp.getWriter().print( url );
3.请求转发
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); ServletContext context = this.getServletContext(); context.getRequestDispatcher("/get").forward(req,resp); }
4.读取资源文件
properties
- 在java目录下新建properties文件
- 在resouesce目录下新建properties文件
发现都会打包到同一个路径下:classes,我们俗称这个路径为classpath
思路:需要一个文件流
resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); ServletContext context = this.getServletContext(); InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties"); Properties prop = new Properties(); prop.load(is); String user = prop.getProperty("username"); String pwd = prop.getProperty("password"); resp.getWriter().print(user+" "+pwd);
username=root password = 123456
访问测试即ok
6.6 HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过HTTP协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息
1.获取前端传递参数,并且请求转发
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); String username = req.getParameter("username"); String password = req.getParameter("pwd"); String[] hobbys = req.getParameterValues("hobby"); System.out.println("===================="); System.out.println(username); System.out.println(password); System.out.println(Arrays.toString(hobbys)); System.out.println("===================="); req.getRequestDispatcher("/success.jsp").forward(req,resp); }
请求转发和重定向的区别
6.7HttpServletResponse
响应:web服务器接受到客户端的http请求,会针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端一些响应信息:找到HttpServletResponse
1.简单分类
负责向浏览器发送数据的方法
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 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);
响应状态码
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;
2,常见应用
- 向浏览器输出消息
- 下载文件,上传文件
- 要获取下载文件的路径
- 下载的文件名是什么?
- 设置让浏览器支持下载我需要的文件
- 获取下载文件的输入流
- 创建缓冲区
- 获取outinputstream对象
- 将fileoutinputstream写入buffer缓冲区
- 使用outinputstream将缓冲区中的数据输出到客户端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 要获取下载文件的路径 String realPath ="D:\\javaweb-maven-02\\response\\target\\classes\\梦.jpg"; //2. 下载的文件名是什么? System.out.println("下载文件路径"+realPath); String Filename =realPath.substring(realPath.lastIndexOf("//")+1); // 3. 设置让浏览器支持下载我需要的文件 resp.setHeader("Content-disposition","attachment;filename"+ URLEncoder.encode(Filename,"UTF-8")); //4. 获取下载文件的输入流 FileInputStream in = new FileInputStream(realPath); //5. 创建缓冲区 int len = 0; byte[] buffter = new byte[1024]; //6. 获取outinputstream对象 ServletOutputStream out = resp.getOutputStream(); //7. 将fileoutinputstream写入buffer缓冲区, 使用outinputstream将缓冲区中的数据输出到客户端 while ((len = in.read(buffter))>0){ out.write(buffter,0,len); } //关闭 in.close(); out.close(); }
3.验证码功能
验证码怎么来的
- 前端实现
- 后端实现,需要用到java的图片类来实现
4.实现重定向
一个web资源收到客户端请求后,他会通知客户端去访问另一个web资源这个过程叫做重定向
常见场景:
- 用户登录
void sendRedirect(String var1) throws IOException;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // resp.setHeader("location","/r/img"); // resp.setStatus(resp.SC_MOVED_TEMPORARILY); resp.sendRedirect("/r/img"); }
面试题:请你聊聊重定向和转发的区别?
相同点
- 页面都会实现跳转
不同点
- 请求转发的时候,url不会产生变化
- 重定向时候,url地址栏会产生变化
Java后端进阶之路: JavaWeb(三)https://developer.aliyun.com/article/1469549