第一章Java EE基础
Java EE 本质是一种容器加组建的技术,容器是用来管理组件行为的一个集合工具,组件是开发者编写或者引入的第三方程序代码。只要开发者按照容器所定义的规范开发组件,组件就可以在容器中运行了。
Java EE容器和组件
容器,不需要用户开发
Web容器
包含一个Servlet容器,该容器可以运行Java的核心组件Servlet,而JSP最终也会被Web容器翻译为Servlet,再通过Servlet运行。此外,Web容器还可以运行HTML文件。Tomcat就实现了Web容器规范。
EJB容器
一个企业级Java Bean规范,被大部分企业抛弃。Tomcat无法运行,Wildfly和Glassfish能够运行,但存在很多问题。
专门解决某类问题的容器,如Java NIO,一种支持字节组件的容器。
组件,运行在Java容器中的程序片段
Web容器的组件主要为,Servlet和JSP,EJB容器主要组件为EJB
Tomcat
文件夹 | 说明 |
bin | 放置Tomcat的命令,如启动是startup.bat |
conf | 配置文件夹,可以设置编码参数 |
lib | 启动的包,比如可以放数据库连接包 |
logs | 放置Tomcat日志文件 |
temp | 缓存文件夹 |
webapp | Web项目部署目录,可以自动发布放在其中的Web项目 把web项目或者war包整个放到该目录下就可以发布 |
work | 工作目录,编译Servlet后生成的class文件可以放在这里 |
Tomcat日志编码修改:
打开conf文件夹下的logging.properties
java.util.logging.ConsoleHandler.encoding = GBK
Tomcat运行时编码设置:
找到conf目录下的server.xml文件,找到<Connecter>元素进行修改
<Connecter port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8">
Maven
一种常见的构建工具,可以通过一小段描述信息进行项目的构建、报告和文档管理的工具软件
如何将Maven的下载路径指向阿里巴巴的镜像?
去Maven目录的conf下找到配置文件setting.xml,再找到<mirrors>元素
maven配置文件位置:.m2/settings.xml
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
Web组件容器Servlet
Web容器包含Servlet容器,Servlet容器中最基础的组件为Servlet
以下是一段简单的servlet代码,拦截路径为/my
package com.learn.ssm.chapter1.servlet;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(
name="myServlet",
urlPatterns = "/my"
)
public class MyServlet extends HttpServlet{
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().print("Hello Servlet");
}
}
4.1 Servlet生命周期
Servlet是Servlet容器的一个接口,在此基础上定义了GenericServlet和HttpServlet两个抽象类
其中HttpServlet主要有三类方法
init方法
服务方法:service、doGet和doPost
destroy方法:会在Servlet容器关闭或实例超时时被调用
第一次Http请求
Servlet容器构建Servlet实例 -> 调用实例的init方法 -> 调用服务方法响应请求
第二次和之后的请求,复用实例
以下测试Servlet生命周期的代码
package com.learn.ssm.chapter1.servlet;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(
name="myServlet",
urlPatterns = "/my"
)
public class MyServlet extends HttpServlet{
@Override
public void init() {
System.out.println("init 方法调用");
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("doGet 方法调用");
response.getWriter().print("Hello Servlet");
}
@Override
public void destroy() {
System.out.println("destroy 方法调用");
}
}
第一次测试输入 http://localhost:8080/MyJavaEE_war/my
刷新网页后,只调用了doGet
最后停止服务器,调用destroy
4.2 修改Servlet参数
@WebServlet(
name = "myServlet",
urlPatterns = "/my",
asyncSupported = true, // 是否异步执行
loadOnStartup = 1, // 启动顺序,只有大于0才在项目启动时加载
initParams = {
@WebInitParam(name = "init.param1", value = "init-value1"),
@WebInitParam(name = "init.param2", value = "init-value2")
}
)
public class MyServlet extends HttpServlet {
@Override
public void init() {
System.out.println("init 方法调用");
String param1 = getServletConfig().getInitParameter("init.param1");
String param2 = getServletConfig().getInitParameter("init.param2");
System.out.println("param1: " + param1);
System.out.println("param2: " + param2);
}
4.3 HttpServletRequest的使用
a. 写一个继承自HttpServlet的类
获取并设置请求属性
获取并设置session属性,设置session间隔为半小时
获取并设置application属性
application的作用域是Web项目在Servlet容器中存活期间有效
注意:页面跳转可以使用response.sendRedirect,但是该跳转不传递请求上下文,意味着HttpServletRequet设置的属性无法被读取。
以下为代码
package com.learn.ssm.chapter1.servlet;
import javax.servlet.ServletContext;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet(
name = "reqServlet", // Servlet名称
urlPatterns = "/request/*"
)
public class RequestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取端口,url,uri
int port = request.getServerPort();
String url = request.getRequestURL().toString();
String uri = request.getRequestURI();
System.out.println("服务器端口: " + port);
System.out.println("url: " + url);
System.out.println("uri: " + uri);
// 获取请求头
String userAgent = request.getHeader("User-Agent");
System.out.println("User-Agent: " + userAgent);
//获取参数
String param1 = request.getParameter("param1");
String param2 = request.getParameter("param2");
//获取请示上下文
ServletContext application = request.getServletContext();
// 设置上下文属性
application.setAttribute("application", "application-value");
// 设置请求属性
request.setAttribute("param1", param1);
request.setAttribute("param2", param2);
// 设置Session属性
HttpSession session = request.getSession();
// 设置Session超时时间为半小时,这里单位为s
session.setMaxInactiveInterval(1800);
session.setAttribute("session1", "session-value1");
// 跳转到JSP页面
request.getRequestDispatcher("/request-result.jsp").forward(request, response);
// response.sendRedirect("/MyJavaEE_war/request-result.jsp");
}
}
b. 跳转jsp页面代码
<%--
Created by IntelliJ IDEA.
User: xunzhou
Date: 2023/3/12
Time: 09:16
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
out.print("<h2>内置对象request</h2>");
String param1 = (String) request.getAttribute("param1");
String param2 = (String) request.getAttribute("param2");
out.print("param1 => " + param1 + "<br>");
out.print("param2 => " + param2 + "<br>");
out.print("<h2>内置对象session</h2>");
String session1 = (String) session.getAttribute("session1");
out.print("session1 => " + session1 + "<br>");
out.print("<h2>内置对象application</h2>");
String appValue = (String) application.getAttribute("application");
out.println("application => " + appValue + "<br>");
%>
</body>
</html>
c. 最后的效果画面
http://localhost:8080/MyJavaEE_war/request?param1=value1¶m2=value2
4.4 HttpServletResponse设置响应类型和json数据
以下代码获取两个请求参数,转换为json,构造响应,并输出json
package com.learn.ssm.chapter1.servlet;
import com.alibaba.fastjson.JSON;
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.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@WebServlet(
name = "respServlet",
urlPatterns = "/response/*"
)
public class ResponseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取参数
String param1 = request.getParameter("param1");
String param2 = request.getParameter("param2");
// 封装到Map数据结构中
Map<String, String> resultMap = new HashMap<String, String>();
resultMap.put("param1", param1);
resultMap.put("param2", param2);
// 转换为json数据集
String json = JSON.toJSONString(resultMap);
// 谁知响应JSON类型
response.setContentType("application/json");
// 设置响应编码为UTF-8
response.setCharacterEncoding("UTF-8");
// 设置响应头
response.setHeader("sueccess", "true");
// 获取输出对象
PrintWriter writer = response.getWriter();
writer.println(json);
}
}
浏览器输入: http://localhost:8080/MyJavaEE_war/response?param1=10¶m2=100
4.5 过滤器的使用
过滤器的作用是在Servlet的执行过程前后执行一些逻辑
Filter的init优于Servlet的init,它的doFilter可以拦截Servlet
以下代码,如果request和repsonse的url没有初始化param1,则会被filter拦截后停下
package com.learn.ssm.chapter1.servlet;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(
filterName = "servletFilter",
// 拦截请求范围
urlPatterns = {"/request/*", "/response/*"},
// 需要的拦截的Servlet,提供名称
servletNames = {"reqServlet", "respServlet"},
// 初始化参数
initParams = {
@WebInitParam(name = "init.param1", value = "init-value-1"),
@WebInitParam(name = "init.param2", value = "init-value-2")
}
)
public class ServletFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
String initParam1 = filterConfig.getInitParameter("init.param1");
String initParam2 = filterConfig.getInitParameter("init.param1");
System.out.println("Filter初始化参数: param1 => " + initParam1);
System.out.println("Filter初始化参数: param2 => " + initParam2);
}
/**
* @param servletRequest 请求对象
* @param servletResponse 响应对象
* @param filterChain 过滤器责任链
* @throws IOException
* @throws ServletException
*/
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 强制转换
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 获取参数
String param1 = request.getParameter("param1");
if (param1 == null || param1.trim().equals("")) {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
response.getWriter().println("没有参数: param1,拦截请求");
// 不再转发到Servlet
return;
}
// 放行请求
filterChain.doFilter(request, response);
}
public void destroy() {
System.out.println("filter 销毁方法");
}
}
效果如下
4.6 监听
以下代码实现ServletContextListener
该接口方法监听上下文,在filter创建之前和销毁之后执行
package com.learn.ssm.chapter1.servlet;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class WebContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听器: Servlet上下文初始化后的逻辑");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听器: Servlet上下文摧毁");
}
}
4.7 使用Cookie
Cookie是服务器写入用户本地浏览器的数据
package com.learn.ssm.chapter1.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(
name = "cookieServlet",
urlPatterns = "/cookie/*"
)
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
// 获取参数
String action = req.getParameter("action");
if ("write".equalsIgnoreCase(action)) {
this.writeCookie(req, resp);
} else if ("show".equalsIgnoreCase(action)) {
this.showCookie(req, resp);
} else {
resp.getWriter().println("参数错误!");
}
}
private void writeCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException{
for (int i = 1; i < 10; i++) {
Cookie cookie = new Cookie("cookie" + i, "cookie" + i);
resp.addCookie(cookie);
}
}
private void showCookie(HttpServletRequest req, HttpServletResponse resp) throws IOException{
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
resp.getWriter().println("<br> Cookie[" + name + "]: " + value);
}
}
}
以下为先调用- http://localhost:8080/MyJavaEE_war/cookie?action=write
再调用 - http://localhost:8080/MyJavaEE_war/cookie?action=show
提交表单,doPost
4.8 首先是开发表单jsp
package com.learn.ssm.chapter1.servlet;
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.io.PrintWriter;
@WebServlet(
name = "postServlet",
urlPatterns = "/post"
)
public class PostServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String role_name = req.getParameter("role_name");
String note = req.getParameter("note");
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
writer.println("提交表单参数: " + role_name);
writer.println("备注: " + note);
}
}
然后/post路径接收参数打印
package com.learn.ssm.chapter1.servlet;
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.io.PrintWriter;
@WebServlet(
name = "postServlet",
urlPatterns = "/post"
)
public class PostServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String role_name = req.getParameter("role_name");
String note = req.getParameter("note");
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
writer.println("提交表单参数: " + role_name);
writer.println("备注: " + note);
}
}