# 一、JavaWeb
# 1. 基本概念
# 1.1、分类
- 静态 web:
- 动态 web:Servlet/JSP,ASP,PHP
# 1.2、web 应用程序
web 应用程序:可以提供浏览器访问的程序
# 1.3、技术
JSP/Servlet:
B/S: 浏览器服务器
C/S: 客户端服务器
# 2.web 服务器
IIS
微软的: ASP…,windows 中自带的
Tomcat
Tomcat 是 Apache 软件基金会(Apache Software Foundation)的 Jakarta 项目中的一个核心项目,由 Apache、Sun 和其他一些公司及个人共同开发而成。由于有了 Sun 的参与和支持,最新的 Servlet 和 JSP 规范总是能在 Tomcat 中得到体现,Tomcat 5 支持最新的 Servlet 2.4 和 JSP 2.0 规范。因为 Tomcat 技术先进、性能稳定,而且免费,因而深受 Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的 Web 应用服务器。
# 3.TomCat
配置环境变量: jdk,tomcat --> startup.bat 启动服务
tomcat 默认端口: 8080
mysql: 3306
http: 80
https: 443
# 4.Http
略,内容比较多,且很重要
# 5.Maven
为什么需要 maven
1. 在 javaweb 开发中,需要大量 jar 包,如果不用 maven 需要很复杂的手动导入;
2. 利用 maven 自动导入和配置 jar 包
# 5.1Maven 项目架构管理工具
Maven 的核心思想: 约定大于配置
# 5.2 下载安装
[Maven 下载地址](Index of /dist/maven/maven-3 (apache.org))
# 5.3 环境变量
![image-20221130143107012]()
# 5.4 配置国内镜像
1 2 3 4 5 6
| <mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>
|
# 5.5 本地仓库
建立本地仓库: localRepository
1
| <localRepository>F:\Environment\Maven\apache-maven-3.8.6-bin\apache-maven-3.8.6\maven-repo</localRepository>
|
# 5.6 在 IDEA 中使用 Maven (配置 tomcat)
- 启动 IDEA
- 创建一个 MavenWeb 项目
- 配置
4. 等待仓库初始完毕
![image-20221130155949899]()
5. 配置 Tomcat
6.Maven 依赖包.
1 2 3 4 5 6 7 8 9
| <dependencies>
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency>
</dependencies>
|
7. 解决配置文件 无法导出 或失效的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
|
# 5.7 在 IDEA 中创建非 Maven 的 javaweb 项目
新建项目 ->javaEE->web Application
# 6.servlet
什么是 servlet?
由 java 编写的程序,运行在 web 服务器上,用来处理来自客户端的请求,返回 html 页面,在客户端形成动态网页。可跨平台.
本质上来讲: servlet 就是一种实现了 servlet 接口的类,由 web 容器负责创建并调用,用于接收和响应用户的请求。
# 6.1 在项目中配置 servlet
# 6.2 两种配置 web.xml 的方式
-
用 <servlet> 标签
-
用 @WebServlet 注解
![image-20221201005307929]()
# 6.3 项目结构
![image-20221201091903042]()
1 2 3 4 5 6 7 8 9 10 11
| @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter writer = response.getWriter(); writer.write("this is Post"); Student stu = new Student(); stu.setStuid("001"); stu.setStuname("张三"); writer.write(JSON.toJSONString(stu)); }
|
# 6.4 中文乱码
![image-20221201092114864]()
# 方法一
-
设置 HTTPServletResponse 使用 utf-8 编码
response.setCharacterEncoding("utf-8");
-
通知浏览器使用 utf-8 解码
response.setHeader("Content-Type","text/html;charset=utf-8");
# 方法二
包含方法一中的两个功能
response.setContentType("text/html;charset=utf-8");
注意要放在开头
![image-20221201094338943]()
# 6.5 数据转 json
-
fastjson.jar
1 2 3 4 5 6 7 8 9
| writer.write(JSON.toJSONString(stu));
List<Student> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { Student s = new Student("20203106150"+i,"鲁班"+i+"号"); list.add(s); } writer.write(JSON.toJSONString(list));
|
-
gson.jar
//用Gson转换
Gson gson = new Gson();
writer.write(gson.toJson(stu));
writer.write(gson.toJson(list));
-
jackson.jar
1 2 3 4
| ObjectMapper mapper = new ObjectMapper(); writer.write(mapper.writeValueAsString(stu)); writer.write(mapper.writeValueAsString(list));
|
# 7.JDBC
![image-20221201110106611]()
- 导入 jar 包
- 注册驱动
- 创建连接
- 定义 SQL 语句
- 获取执行 SQL 对象
- 执行 SQL 并处理结果
- 释放资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
List<Users> userList = new ArrayList<>();
try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/javaeestudy"; String username = "root"; String password = "248789"; Connection con = DriverManager.getConnection(url, username, password); Statement stmt = con.createStatement(); String sql = "select * from users"; ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { Users user = new Users(); user.setUserid(rs.getInt("userid")); user.setUsername(rs.getString("username")); user.setUserpsd(rs.getString("userpsd")); userList.add(user); } rs.close(); stmt.close(); con.close(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } writer.write(JSON.toJSONString(userList));
|
# 8. 项目结构 + 基本功能
![项目结构]()
src 中放后端代码
- **controller ** 负责请求转发,接受页面过来的参数,传给 Service 处理,接到返回值,再传给页面。
- dao 一定是和数据库的某一张表一一对应的,其中封装了增删改查基本操作,建议 DAO 只做原子操作,增删改查。
- entity 存放需要操作的实体类,如 (user,person,student)。
- service 一个或多个 DAO 进行的再次封装,封装成一个服务,所以这里也就不会是一个原子操作了,需要事物控制。
- utils 工具包,将一些重复的操作解耦封装进来,如数据库连接,资源释放等。
# 8.1. 添加数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public int addUser(Users user) { int ret = 0;
try { Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/javaeestudy"; String username = "root"; String password = "248789"; Connection con = DriverManager.getConnection(url, username, password);
String sql = "INSERT INTO users(username, userpsd)values(?,?)";
PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, user.getUsername()); pst.setString(2, user.getUserpsd()); ret = pst.executeUpdate();
stmt.close(); con.close(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } return ret; }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter(); Users users = new Users(request.getParameter("username"),request.getParameter("userpsd"));
usersService usersService = new usersServiceImpl(); int ret = usersService.addUser(users); if (ret > 0) { writer.write("数据添加成功!"); } else { writer.write("失败"); }
}
|
# 9. 思考优化
# 9.1 封装数据库连接类,放入 utils 工具包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package com.jilin.utils;
import java.sql.*;
public class MySqlUtil { public static Connection getConn(){ Connection con = null; try{ Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/javaeestudy"; String username = "root"; String password = "248789"; con = DriverManager.getConnection(url, username, password); }catch(Exception e){ e.printStackTrace(); } return con; } public static void close(ResultSet rs, Statement stmt, Connection con){ try{ if(rs!=null){rs.close();} if(stmt!=null){stmt.close();} if( con!=null){con.close();} }catch(Exception e){ e.printStackTrace(); } } public static void close(PreparedStatement pst, Connection con){ try{ if(pst!=null){pst.close();} if( con!=null){con.close();} }catch(Exception e){ e.printStackTrace(); } } }
|
# 9.2 优化 servlet 事务,抽象封装
只需要一个 Servlet 类 —— indexServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| package com.jilin; import ...
@WebServlet(name="indexServlet", urlPatterns = "/") public class indexServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { start(req,resp); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { start(req, resp); }
private void start(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); PrintWriter writer = resp.getWriter();
String path = req.getServletPath(); String className = path.substring(1, path.lastIndexOf("/")); String methodName = path.substring(path.lastIndexOf("/") + 1); System.out.println(className + "," + methodName); try { Class<?> clazz = Class.forName("com.jilin.controller." + className); Object instance = clazz.getConstructor().newInstance(); Method method = clazz.getMethod(methodName,HttpServletRequest.class); Object object = method.invoke(instance, req); writer.write(JSON.toJSONString(object)); } catch (Exception ex) { ex.printStackTrace(); }
} }
|
利用 反射 调用 userController 类方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.jilin.controller; import ...
public class userController { public int addUser(HttpServletRequest request){ Users users = new Users(request.getParameter("username"),request.getParameter("userpsd")); usersService usersService = new usersServiceImpl(); int ret = usersService.addUser(users); return ret; } public List<Users> getList(HttpServletRequest request){ usersService usersservice = new usersServiceImpl(); List<Users> list = usersservice.getList(); return list; } }
|
# 10. 过滤器 Filter
![过滤器图示]()
# 10.1 过滤器解决乱码
新建一个 filter 过滤器,主要方法有三个 init()
, doFilter()
, destroy()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @WebFilter(urlPatterns = "*") public class CharaterEncoding implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp; request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); filterChain.doFilter(request,response); } @Override public void destroy() { } }
|
# 10.2 过滤器解决跨域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @WebFilter("/*") public class CORSFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); response.setHeader("Access-Control-Allow-Credentials","true"); filterChain.doFilter(servletRequest, servletResponse); } }
|
暂时先写这么多吧,基本上都是跟着老师视频做的,感觉还需要多熟悉多理解。 2022/12/3