【JavaWeb】核心技术
目录
Tomcat
1.安装配置目录使用部署创建
配置:修改启动端口号:conf/server.xml
port="8080" protocol="HTTP/1.1"
可以将8080改为80默认端口
项目部署:将项目放到webapps目录下,即部署完成。
一般javaweb项目会被打包成war包,然后将war包放到webapps目录下,Tomcat会自动解压缩war文件
2.idea集成Tomcat
1.直接添加本地Tomcat
添加服务配置项,选择Tomcat路径,然后再添加一个项目模板就可以了。
2.使用maven配置项添加Tomcat
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>common-tomcat-maven-plugin</artifactId>
<version>2.2</version>
</plugin></plugins>
Servlet
java提供的一门动态web资源开发技术
例子:
localhost:8080/web/login?username=1
localhost:8080/web/login?username=2
localhost:8080/web/login?username=3
这三个页面所返回的内容不同,这就是动态web资源
Servlet是JavaEE的规范之一,是一个接口,将来需要定义Servlet类来实现Servlet接口,并由web服务器运行Servlet。
Servlet快速入门
1.创建web项目,导入Servlet依赖坐标
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
2.创建:定义一个类,实现Servlet接口,重写接口中的所有方法,并在service方法中输入一句话
public void service() {
System.out.println("Servlet hello world~");
}
3.配置:在类上使用@webServlet注解,配置访问路径 /demo1
@WebServlet("/demo1")
public class aaa implements Servlet {
4.访问:启动Tomcat,访问Servlet
package com.lyp.web;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/demo1")
public class aaa implements Servlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Servlet hello world~");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
}
Servlet生命周期
1.加载和实例化,Servlet第一次被访问的时候,由容器创建Servlet对象。
2.初始化:init()方法,只调用一次。
3.请求处理:每次请求Servlet时,都会调用service()方法对请求处理。
4.服务终止:destroy()方法释放资源,释放Servlet实例。
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Servlet hello world~");
}
@Override
public void destroy() {
}
//获取Servelet信息,基本不用
@Override
public String getServletInfo() {
return null;
}
//获取ServletConfig对象,Servlet配置信息
@Override
public ServletConfig getServletConfig() {
return null;
}
两个方法共同使用一个变量:
public class aaa implements Servlet {
private ServletConfig config;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
this.config=config;
System.out.println("init...");
}
@Override
public ServletConfig getServletConfig() {
return config;
}
Servlet体系结构
@WebServlet("/demo4")
public class Servlet_demo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("GET...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("POST...");
}
}
为什么要根据请求方式的不同,调用不同的方法?
get和post请求参数的位置不同,service方法要先获取请求方式,再分别写处理逻辑,这些逻辑代码或很繁琐
可以直接extends HttpServlet类来实现这些不同方式的逻辑代码。
如何调用?
获取请求方式来进行逻辑判断。根据不同请求方式,调用不同的doxxx方法
Servlet urlPattern配置
配置访问路径(urlPattern)
1.一个Servlet可以配置多个urlPattern
@WebServlet(urlPatterns = {"/demo1" , "/demo2"})
2.urlPattern配置规则
- 精确匹配
- 目录匹配
- 扩展名匹配
- 任意匹配
XML配置Servlet
可以直接在web.xml里配置Servlet的路径
<!--
Servlet 全类名
-->
<servlet>
<servlet-name>demo4</servlet-name>
<servlet-class>com.lyp</servlet-class>
</servlet>
<!--
Servlet 访问路径
-->
<servlet-mapping>
<servlet-name>demo4</servlet-name>
<url-pattern>/demo4</url-pattern>
</servlet-mapping>
Request,Responce
把请求数据和返回数据放在一个对象里。
例子:
@WebServlet("/name1")
public class requ_resp extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用res对象,获取请求数据,这是一个get方式的数据
String name = req.getParameter("name");//localhost:8080/name1?name=aaa
//使用resp对象,设置响应数据
resp.setHeader("content-type","text/html;charset=utf-8");
resp.getWriter().write("<h1>"+name+"欢迎您!</h1>");
}
}
request继承体系
接口不能直接用,要继承,我们用的都是类和类实例化之后的对象
实现类要Tomcat来定义,因为实现类是Tomcat解析的,不是java语言本身
Tmocat解析请求数据,封装成request对象,创建request对象传递到service方法里面去。
request获取请求数据
1.获取请求行数据
例如这样的请求行:
GET /day14/demo1?name=zhangsan HTTP/1.1
方法:
-
获取请求方式:GET
String getMethod()
-
获取虚拟目录: /day14
String getContextPath()
-
获取Servlet路径:/demo1
String getServletPath()
-
获取get方式请求参数:name=zhangsan
String getQueryString()
-
获取请求URI:/day14/demo1
String getRequestURI() : /day14/demo1 URI:统一资源标识符 StringBuffer getRequestURL() : http://localhost/day14/demo1 URL:统一资源定位符
-
获取协议及版本:HTTP/1.1
String getProtocol()
-
获取客户机ip地址
String getRemoteAddr()
2.获取请求头数据
例:
user-agent: Mozilla/5.0 Chrome/105.0.0.0
方法:
String getHeader(String name):通过请求头名称获取请求头的值 String header = req.getHeader("user-agent"); Enumeration<String> getHeaderName():获取所有的请求头名称
3.获取请求体数据
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
username=admin&password=123456
步骤:
1.获取流对象
BufferedReader getReader() :获取字节输入流 BufferedReader br = req.getReader();
2.再从流对象中读取数据
String line = br.readline(); System.out.println(line);
4.统一方式获取请求参数
doget和dopost里面都可以用的方法
可以把代码直接copy过去(要传递一下req和resp
this.doget(req,resp)
)1. String getParameter(String name): 根据参数名称获取参数值 2. String[] getParameterValues(String name): 根据参数名称获取参数值的数组 3. Enumeration<String> getParameterValueNames(): 获取所有的参数名称 4. Map<String, String[]> getParameterMap(): 获取所有参数的键值对集合
request请求转发
一种在服务器内部的资源跳转方式。
步骤:
-
通过request对象来获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path)
-
使用RequestDispatcher对象进行转发:
forward(ServletRequest request, ServletResponse response)
一行代码:
req.getRequestDispatcher("/demo6").forward(request,response);
特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前的服务器内部资源中
- 转发是一次请求
资源之间怎么共享数据:request对象
1. void setAttribute(String name, Object obj): 存储数据
2. Object getAttribute(String name): 通过键获取值
3. void removeAttribute(): 通过键移除键值对
responce设置响应数据
设置响应行:
-
格式:HTTP/1.1 200 ok
-
设置状态码:
void setStatus(int sc)
设置响应头:
void setHeader(String name, String value)
设置响应体:
使用步骤:
-
获取输出流
字符输出流:PrintWriter getWriter()
字节输出流:ServletOutputStream getOutputStream()
-
使用输出流,将数据输出到客户端浏览器中
responce重定向
responce响应字符、字节数据
@WebServlet("/resp1")
public class resp extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//1.获取字符输出流:(默认编码iso,中文会乱码)
PrintWriter write = resp.getWriter();
//content-type
//resp.setHeader("content-type","text/html");
write.write("aaa");
write.write("<h1>hello</h1>");
//细节:字符流不需要关闭
}
@WebServlet("/resp2")
public class resp2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.读取文件
FileInputStream fis = new FileInputStream("d://a.jpg");
//2.获取response字节输出流
ServletOutputStream os = resp.getOutputStream();//重要代码
//3.完成流的copy
// byte[] buff = new byte[1024];
// int len = 0;
// while ((len = fis.read(buff))!=-1){
// os.write(buff,0,len);
// }
//或者采用工具类的copy方法:
IOUtils.copy(fis,os);
fis.close();
}
JSP
Java Server Pages:java服务端页面
一种动态的网页技术,既可以定义Html,js,css等静态内容,还可以定义Java代码的动态内容
JSP=HTML+Java
JSP本质上就是一个Servlet
JSP的脚本:
JSP定义Java代码的方式
<% 代码 %>:定义的Java代码,在service方法中。service可以定义什么,该脚本中就可以定义什么。
<%! 代码 %>:定义的Java代码,在jsp转换后的java类的成员位置。
<%= 代码 %>:定义的Java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
MVC三层架构: