✅✅作者主页:🔗孙不坚1208的博客
🔥🔥精选专栏:🔗JavaWeb从入门到精通(持续更新中)
📋📋 本文摘要:本篇文章主要分享JavaWeb的学习重点内容。💞💞觉得文章还不错的话欢迎大家点赞👍➕收藏⭐️➕评论💬支持博主🤞
👉 👉你的一键三连是我更新的最大动力❤️❤️
JavaWeb复习重点
javaweb期末题型有2大类:问答题、编程题
一、问答题7个左右,共40分
1.Servlet的定义、配置(使用xml或注解)
Servlet是用Java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。
Servlet的配置有xml和注解两种方式
xml方式:
<servlet><servlet-name>demo</servlet-name><!--全类名--><servlet-class>web.servlet.ServletDemo</servlet-class></servlet><servlet-mapping><servlet-name>demo</servlet-name><!--url访问的资源名--><url-pattern>/index</url-pattern></servlet-mapping>
注解方式:在类上使用注解@WebServlet注解配置
@WebServlet("/demo")publicclassServletDemoimplementsServlet{// 实现Servlet接口}
2.重定向与请求转发的区别,使用API完成重定向和转发
重定向(Redirect)和请求转发(Forward)是两种不同的HTTP请求处理机制。
重定向是在接收到请求后,服务器向客户端返回一个特殊的响应,指示客户端重新向指定的url发送请求,这个过程是完全由客户端完成的,客户端会发送一个新的请求到指定的url,并接收新的响应。重定向经常被用来处理资源的移动,url的更改,或者是需要访问其他网站的情况。
请求转发则是在服务器端将请求转发给另一个资源进行处理,这个过程是在服务器内部完成的。客户端发送请求到服务器,服务器会将请求转发到另一个资源进行处理,然后将处理结果返回给客户端。请求转发经常被用来组合多个资源进行处理,例如在JSP中使用include指令将多个JSP页面组合在一起。
重定向:
response.sendRedirect("http://www.example.com");
转发:
RequestDispatcher dispatcher = request.getRequestDispatcher("/example.jsp");
dispatcher.forward(request, response);
在以上示例代码中,
response
和
request
是
javax.servlet.http.HttpServletResponse
和
javax.servlet.http.HttpServletRequest
的实例对象。重定向通过调用
sendRedirect()
方法并传入要重定向到的URL字符串来实现。请求转发则通过创建一个
RequestDispatcher
对象,该对象通过
getRequestDispatcher()
方法获取,并传入要转发到的资源的路径,然后调用
forward()
方法来实现。在请求转发中,
request
和
response
对象被传递给了要转发到的资源。
需要注意的是,重定向会向客户端发送一个新的请求,因此客户端的URL会发生改变,而请求转发是在服务器内部完成的,客户端的URL不会改变。
3.重定向与请求转发的优缺点
重定向的优点:
- 简单易用:使用
response.sendRedirect()
方法非常简单,可以很容易地将客户端重定向到其他URL。 - 安全性高:重定向会向客户端发送一个新的请求,因此客户端的URL会发生改变,可以避免某些安全漏洞,比如在表单提交后刷新页面导致的重复提交等。
重定向的缺点:
- 频繁网络请求:重定向会向客户端发送一个新的请求,会导致网络请求的增加,影响性能。
- 无法访问原始请求对象:重定向会生成一个新的请求对象,因此无法访问原始请求对象,如原始的HTTP请求头等。
请求转发的优点:
- 性能高:请求转发是在服务器内部完成的,不会向客户端发送新的请求,因此不会增加网络请求,性能比较高。
- 可以访问原始请求对象:请求转发可以访问原始请求对象,如原始的HTTP请求头等。
请求转发的缺点:
- 不适用于跨域请求:由于请求转发只能转发到同一Web应用程序中的资源,因此不能用于跨域请求。
- 不支持修改URL:请求转发是在服务器内部完成的,客户端无法感知,也无法修改URL。
4.给出了Servlet的代码实现,让大家用JSP来实现该功能
这个参考课本
使用JSP实现重定向和请求转发的示例代码:
重定向:
<%
response.sendRedirect("http://www.example.com");
%>
请求转发:
<jsp:forward page="/example.jsp" />
jsp转换如下
<jps:useBean id="user" class="package.User" pageScope="session"/>
<%
if(session.getAttribute("user")) == null {
User user = new new User();
session.getAttribute("user",user);
}
%>
5.JavaBean的规范,应该详细掌握
JavaBean是一种符合Java语言规范的特殊类,通常用于存储和操作数据。JavaBean类应该遵循以下规范:
- 应该提供一个无参的构造方法:JavaBean的构造方法应该是无参的,这样可以方便地在其他类中创建JavaBean的实例。无参构造方法可以通过手动编写或者使用编译器自动生成的方式实现。
- 所有属性应该私有化:JavaBean的属性应该使用private修饰符进行私有化,通过提供公共的getter和setter方法来访问属性。
- getter和setter方法的命名应该符合JavaBean命名规范:JavaBean的getter和setter方法应该遵循一定的命名规范。getter方法的名称应该以“get”开头,setter方法的名称应该以“set”开头,后面跟着属性名的首字母大写的形式。
- 应该提供默认的toString方法:JavaBean应该提供一个默认的toString方法,以便在调试和日志记录时方便查看JavaBean的属性值。
- 应该提供其他有用的方法:除了getter和setter方法以外,JavaBean还可以提供一些其他的有用方法,例如校验方法、计算方法等。
6.给出了Servlet的代码实现,让大家用JSTL来实现该功能
这个参考课本
JSTL(JavaServer Pages Standard Tag Library)是一个标准的JSP标签库,提供了一些常用的标签,可以方便地实现一些常见的操作,包括重定向和转发。以下是使用JSTL实现重定向和转发的示例代码:
重定向:
<c:redirect url="http://www.example.com" />
以上代码中,
<c:redirect>
标签用于实现重定向,
url
属性指定要重定向到的URL字符串。
请求转发:
<c:forward page="/example.jsp" />
以上代码中,
<c:forward>
标签用于实现请求转发,
page
属性指定要转发到的JSP页面的路径。
7.过滤器的概念,写出一个过滤器类
过滤器(Filter)是Java Web应用程序中的一个重要组件,可以拦截客户端请求和服务器响应,对它们进行预处理和后处理,实现一些通用的功能,例如日志记录、权限控制、字符编码转换等。
一个过滤器类必须实现
javax.servlet.Filter
接口,并重写其中的
doFilter()
方法。以下是一个简单的过滤器类的示例代码,实现了字符编码转换的功能:
importjavax.servlet.*;importjava.io.IOException;@WebFilter(filterName ="CharacterEncodingFilter", urlPatterns ="/*")publicclassCharacterEncodingFilterimplementsFilter{privateString encoding;publicvoidinit(FilterConfig config)throwsServletException{// 读取初始化参数,设置字符编码
encoding = config.getInitParameter("encoding");}publicvoiddoFilter(ServletRequest request,ServletResponse response,FilterChain chain)throwsIOException,ServletException{// 设置请求和响应的字符编码
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);// 调用后续的过滤器或Servlet/JSP处理请求
chain.doFilter(request, response);}publicvoiddestroy(){// 释放资源}}
以上代码中,使用
@WebFilter
注解配置了过滤器的名称和URL模式。
filterName
属性指定过滤器的名称,
urlPatterns
属性指定需要过滤的URL模式。在此示例中,过滤器会拦截所有的请求。
以上代码中,
CharacterEncodingFilter
类实现了
javax.servlet.Filter
接口,并重写了其中的
init()
、
doFilter()
和
destroy()
方法。
init()
方法在过滤器初始化时被调用,读取初始化参数并设置字符编码;
doFilter()
方法用于实现过滤功能,设置请求和响应的字符编码,并调用后续的过滤器或Servlet/JSP处理请求;
destroy()
方法在过滤器销毁时被调用,释放资源。
需要注意的是,过滤器配置除了注解的这种方式也可以在Web应用程序的
web.xml
文件中,通过过滤器链(Filter Chain)的方式实现多个过滤器的协同工作。过滤器的顺序可以通过
<filter-mapping>
元素中的
<url-pattern>
子元素来指定。
8.JPA中实体类、以及实体关系映射,一对一、一对多
在 JPA 中,实体类是指映射到数据库表的 Java 类。实体类通常具有以下特点:
- 实体类使用
@Entity
注解进行标记。 - 实体类的每个实例对应数据库表中的一行数据。
- 实体类的属性对应数据库表中的列。
JPA 中的实体关系映射用于描述实体类之间的关联关系,包括一对一、一对多、多对一和多对多关系。其中,一对一和一对多是较为常见的关系类型。
一对一关系映射示例:
@EntitypublicclassPerson{@IdprivateLong id;privateString name;@OneToOne(cascade =CascadeType.ALL)privateAddress address;}@EntitypublicclassAddress{@IdprivateLong id;privateString street;privateString city;privateString country;@OneToOne(mappedBy ="address")privatePerson person;}
上述代码中,
Person
和
Address
分别是两个实体类。它们之间的关系是一对一,通过
@OneToOne
注解进行映射。
Person
实体类中的
address
属性使用
@OneToOne
注解,表示它与
Address
实体类是一对一关系。
Address
实体类中的
person
属性也使用了
@OneToOne
注解,但是它的
mappedBy
属性指向了
Person
实体类的
address
属性,表示这是一个双向关联,并且由
Person
实体类来维护关系。
一对多关系映射示例:
@EntitypublicclassDepartment{@IdprivateLong id;privateString name;@OneToMany(mappedBy ="department", cascade =CascadeType.ALL)privateList<Employee> employees;}@EntitypublicclassEmployee{@IdprivateLong id;privateString name;privateString email;@ManyToOneprivateDepartment department;}
上述代码中,
Department
和
Employee
分别是两个实体类。它们之间的关系是一对多,通过
@OneToMany
和
@ManyToOne
注解进行映射。
Department
实体类中的
employees
属性使用了
@OneToMany
注解,表示它与
Employee
实体类是一对多关系。
Employee
实体类中的
department
属性使用了
@ManyToOne
注解,表示它与
Department
实体类是多对一关系,并且它的
department
属性指向了
Department
实体类的
employees
属性,表示这是一个双向关联,并且由
Department
实体类来维护关系。
需要注意的是,上述示例中使用了 JPA 中的级联操作(
CascadeType.ALL
),表示当父实体被删除时,子实体也将被删除。这种级联操作可能会对数据产生不可逆的影响,因此需要谨慎使用。
9.Spring控制器的类的编写、路径的配置、注入组件、返回Json数据
在 Spring 中,控制器是指负责处理请求和响应的组件,通常由一个 Java 类实现。以下是 Spring 控制器类的编写、路径配置、注入组件和返回 JSON 数据的示例:
@Controller@RequestMapping("/api/users")publicclassUserController{@AutowiredprivateUserService userService;@GetMapping("/{id}")@ResponseBodypublicUsergetUserById(@PathVariableLong id){return userService.getUserById(id);}@PostMapping("/")@ResponseBodypublicUsercreateUser(@RequestBodyUser user){return userService.createUser(user);}@PutMapping("/{id}")@ResponseBodypublicUserupdateUser(@PathVariableLong id,@RequestBodyUser user){return userService.updateUser(id, user);}@DeleteMapping("/{id}")@ResponseBodypublicvoiddeleteUser(@PathVariableLong id){
userService.deleteUser(id);}}
在上述示例中,我们定义了一个名为
UserController
的控制器类,并使用
@Controller
注解标记它。
@RequestMapping
注解用于配置控制器类的路径前缀,即
/api/users
。这意味着,当请求的路径以
/api/users
开头时,Spring 将会把请求交给该控制器类来处理。
在控制器类中,我们使用了
@Autowired
注解来自动注入一个名为
userService
的组件。这里假设
UserService
是一个已经定义好的服务组件,可以使用
@Service
注解标记它。
控制器类中的方法使用了不同的 HTTP 方法注解,包括
@GetMapping
、
@PostMapping
、
@PutMapping
和
@DeleteMapping
,用于定义请求的 HTTP 方法类型。这些注解后面跟随的路径参数用于定义具体的请求路径。例如,
@GetMapping("/{id}")
表示可以处理
/api/users/{id}
这样的 GET 请求。
在方法中,我们使用了
@ResponseBody
注解来表示将方法的返回值直接作为响应内容返回给客户端。这里,我们返回的是一个 User 类型的对象,Spring 会将它自动转换为 JSON 格式并返回给客户端。需要注意的是,为了能够让 Spring 自动完成 JSON 转换,我们需要在项目中引入相应的 JSON 库,例如 Jackson。
总的来说,Spring 控制器类提供了方便的方式来处理 HTTP 请求和响应,可以通过注解配置路径和 HTTP 方法,并且支持自动注入组件和返回 JSON 数据等常用功能。
二、编程题4个题,共60分
1.题目给出了数据库、表等信息,要求使用JDBC完成增删改查这些操作,可能需要事务
使用 JDBC 完成增删改查操作通常需要以下步骤:
- 加载数据库驱动。
- 建立数据库连接。
- 创建 Statement 或 PreparedStatement 对象。
- 执行 SQL 语句。
- 处理查询结果。
- 释放资源。
以下是一个使用 JDBC 实现增删改查操作的示例:
publicclassUserDao{privateConnection conn;publicUserDao(Connection conn){this.conn = conn;}publicvoidcreateUser(User user)throwsSQLException{String sql ="INSERT INTO users(name, email, password) VALUES (?, ?, ?)";PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, user.getName());
stmt.setString(2, user.getEmail());
stmt.setString(3, user.getPassword());
stmt.executeUpdate();
stmt.close();}publicvoidupdateUser(User user)throwsSQLException{String sql ="UPDATE users SET name=?, email=?, password=? WHERE id=?";PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, user.getName());
stmt.setString(2, user.getEmail());
stmt.setString(3, user.getPassword());
stmt.setLong(4, user.getId());
stmt.executeUpdate();
stmt.close();}publicvoiddeleteUser(long id)throwsSQLException{String sql ="DELETE FROM users WHERE id=?";PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setLong(1, id);
stmt.executeUpdate();
stmt.close();}publicUsergetUserById(long id)throwsSQLException{String sql ="SELECT id, name, email, password FROM users WHERE id=?";PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setLong(1, id);ResultSet rs = stmt.executeQuery();User user =null;if(rs.next()){
user =newUser();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
user.setPassword(rs.getString("password"));}
rs.close();
stmt.close();return user;}}
上述代码中,我们定义了一个
UserDao
类,用于操作名为
users
的数据库表。其中的四个方法分别实现了创建用户、更新用户、删除用户和根据用户 ID 查询用户的功能。在这些方法中,我们使用了
PreparedStatement
对象来执行 SQL 语句,并通过设置占位符的方式传递参数。通过这种方式,可以有效避免 SQL 注入等安全问题。
如果需要使用事务,可以将上述方法放到一个事务中执行。以下是一个示例:
publicvoidcreateUserWithTransaction(User user)throwsSQLException{
conn.setAutoCommit(false);try{createUser(user);
conn.commit();}catch(SQLException e){
conn.rollback();throw e;}finally{
conn.setAutoCommit(true);}}
在这个方法中,我们通过将
autoCommit
属性设置为
false
,来启用手动事务。在执行完所有操作后,我们可以选择提交或回滚事务。同时,为了保证代码的健壮性,需要在
finally
块中将
autoCommit
属性设置回
true
。
2.编写Servlet接收请求参数,并保存到某个作用域
@WebServlet("/example")publicclassExampleServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{String name = request.getParameter("name");String email = request.getParameter("email");String password = request.getParameter("password");// 将参数保存到 session 作用域HttpSession session = request.getSession();
session.setAttribute("name", name);
session.setAttribute("email", email);
session.setAttribute("password", password);// 将参数保存到 request 作用域
request.setAttribute("name", name);
request.setAttribute("email", email);
request.setAttribute("password", password);// 将参数保存到 application 作用域ServletContext context =getServletContext();
context.setAttribute("name", name);
context.setAttribute("email", email);
context.setAttribute("password", password);// 重定向到结果页面
response.sendRedirect(request.getContextPath()+"/result.jsp");}}
在上述代码中,我们在
doPost
方法中,分别将参数保存到 session、request 或 application 作用域中。在
session
中保存参数的方式与之前的示例类似,使用
request.getSession()
方法获取
HttpSession
对象,并调用其
setAttribute
方法将参数保存到 session 作用域中。
在
request
作用域中保存参数的方式也很类似,只需要使用
request.setAttribute
方法将参数保存到 request 作用域中即可。
在
application
作用域中保存参数也非常简单,只需要使用
getServletContext()
方法获取
ServletContext
对象,并调用其
setAttribute
方法将参数保存到 application 作用域中即可。
需要注意的是,在将参数保存到不同作用域中时,需要使用不同的对象来调用
setAttribute
方法。除此之外,其他代码与之前的示例相同,最终通过
response.sendRedirect
方法重定向到结果页面。
3.JPA的编程题,题目给出数据库和表,让大家使用JPA完成实体类及使用EntityManager完成增删改查操作
假设有一个表名为
user
,包含以下字段:
FieldTypeidINTnameVARCHAR(100)ageINTemailVARCHAR(100)passwordVARCHAR(100)
接下来,我们需要使用 JPA 完成实体类及使用
EntityManager
完成增删改查操作。
首先,我们需要定义一个实体类
User
,对应
user
表中的一条记录:
@Entity@Table(name ="user")publicclassUser{@Id@GeneratedValue(strategy =GenerationType.IDENTITY)privateInteger id;privateString name;privateInteger age;privateString email;privateString password;// getters and setters}
在上述代码中,我们使用
@Entity
注解表示这是一个实体类,使用
@Table
注解指定了实体对应的表名为
user
。同时,我们在类中定义了实体对应的属性,并使用
@Id
和
@GeneratedValue
注解表示该属性为实体的唯一标识,并指定了该属性的生成策略为自增长。
接下来,我们可以使用
EntityManager
对实体进行增删改查操作。以下是一个示例:
publicclassUserDao{@PersistenceContextprivateEntityManager entityManager;// 添加用户publicvoidaddUser(User user){
entityManager.persist(user);}// 根据 id 查询用户publicUsergetUserById(Integer id){return entityManager.find(User.class, id);}// 更新用户信息publicvoidupdateUser(User user){
entityManager.merge(user);}// 根据 id 删除用户publicvoiddeleteUserById(Integer id){User user = entityManager.find(User.class, id);
entityManager.remove(user);}}
在上述代码中,我们使用
@PersistenceContext
注解将
EntityManager
注入到
UserDao
类中。接着,我们定义了几个方法,分别用于添加、查询、更新和删除用户。
在
addUser
方法中,我们使用
EntityManager
的
persist
方法将用户对象保存到数据库中。
在
getUserById
方法中,我们使用
EntityManager
的
find
方法根据用户的唯一标识
id
查询用户信息,并将查询结果返回。
在
updateUser
方法中,我们使用
EntityManager
的
merge
方法将修改后的用户对象保存到数据库中。
在
deleteUserById
方法中,我们使用
EntityManager
的
remove
方法将根据用户的唯一标识
id
查询到的用户对象从数据库中删除。
需要注意的是,为了使用
EntityManager
,我们需要将 JPA 的实现框架(如 Hibernate)配置到项目中,并在
persistence.xml
配置文件中配置数据源等信息。
4.JSP+Servet+JavaBean开发模式完成系统功能
JSP + Servlet + JavaBean 开发模式是一种经典的 Web 开发模式,它的核心是将前端页面(JSP)与后端业务逻辑(JavaBean)分离开来,通过 Servlet 充当中间层,完成两者之间的交互和协作。
以下是一个简单的示例:
1.首先,创建一个JavaBean来表示系统中的一个实体。例如,我们创建一个名为User的JavaBean来表示系统中的用户:
publicclassUser{privateString username;privateString password;// getter and setter methods}
2.接下来,创建一个Servlet来处理用户提交的数据。例如,我们创建一个名为LoginServlet的Servlet来处理用户登录请求:
@WebServlet("/login")publicclassLoginServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{String username = request.getParameter("username");String password = request.getParameter("password");User user =newUser();
user.setUsername(username);
user.setPassword(password);// 将User对象保存到Session作用域中
request.getSession().setAttribute("user", user);// 转发到登录成功页面
request.getRequestDispatcher("/success.jsp").forward(request, response);}}
在Servlet中,我们首先获取用户提交的用户名和密码,然后创建一个User对象,并将其保存到Session作用域中。最后,我们使用请求转发将用户重定向到登录成功页面。
3.在Servlet中,我们首先获取用户提交的用户名和密码,然后创建一个User对象,并将其保存到Session作用域中。最后,我们使用请求转发将用户重定向到登录成功页面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body>
<h1>欢迎您,${user.username}!</h1>
</body>
</html>
在JSP页面中,我们使用EL表达式来显示用户登录成功后的信息,例如用户的用户名。
4.最后,我们可以在Web应用程序中部署和运行这个示例,访问/login路径,提交用户名和密码,然后会被重定向到success.jsp页面,页面中显示登录成功后的信息。
这就是使用JSP+Servlet+JavaBean开发模式完成系统功能的基本流程。开发人员可以根据具体的业务需求进行修改和扩展。
三、附加一些常用配置
1.JDBC-DBConnection
packagecom.sun.util;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassDBConnection{privatestaticfinalString driverName ="com.mysql.cj.jdbc.Driver";privatestaticfinalString url ="jdbc:mysql://localhost:3306/testdb?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true";privatestaticfinalString user ="root";privatestaticfinalString password ="sm1208";privateDBConnection(){}static{try{Class.forName("com.mysql.cj.jdbc.Driver");}catch(ClassNotFoundException e){
e.printStackTrace();}}publicstaticConnectiongetConnection()throwsSQLException{returnDriverManager.getConnection(url, user, password);}publicstaticvoidclose(ResultSet rs,Statement st,Connection conn){try{if(rs !=null){
rs.close();}}catch(SQLException e){
e.printStackTrace();}finally{try{if(st !=null){
st.close();}}catch(SQLException e){
e.printStackTrace();}finally{if(conn !=null){try{
conn.close();}catch(SQLException e){
e.printStackTrace();}}}}}}
2.直接连接方式
try{//1.数据库连接的4个基本要素:String url ="jdbc:mysql://localhost:3306/test";String user ="root";String password ="sm1208";String driverName ="com.mysql.cj.jdbc.Driver";//2.加载驱动 Class.forName(driverName);//3.获取连接Connection conn =DriverManager.getConnection(url, user, password);}catch(Exception e){
e.printStackTrace();}
3.JDBC-CRUD
创建类StudentCRUD实现对student表的CRUD操作(使用DBConnection类):该类具有main()方法和使用PreparedStatement实现增加记录的方法add()、实现查询全部记录的方法listAll()、实现根据id更新数据的方法update()、实现根据id删除记录的方法delete()。
add()publicstaticbooleanadd(String name,int age,String hobby)throwsSQLException{Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;boolean successflag =false;try{
conn =DBConnection.getConnection();String sql ="insert into student values(null,?,?,?)";// 预编译SQL语句,得到PrepareStatement对象
ps = conn.prepareStatement(sql);// 填充占位符
ps.setObject(1,name);
ps.setObject(2,age);
ps.setObject(3,hobby);
ps.execute();}finally{// 关闭资源对象DBConnection.close(rs, ps, conn);
successflag =true;}return successflag;}listAll()publicstaticList<Student>listAll()throwsSQLException{Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;List<Student> list =newArrayList<Student>();try{
conn =DBConnection.getConnection();String sql ="select * from student";
ps = conn.prepareStatement(sql);// 执行executeQuery(),得到结果集:ResultSet
rs = ps.executeQuery();// 通过ResultSet得到列值while(rs.next()){
list.add(newStudent(rs.getInt(1),rs.getString(2),rs.getInt(3),rs.getString(4)));}}finally{DBConnection.close(rs, ps, conn);}return list;}update()publicstaticbooleanupdate(Student student)throwsSQLException{Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;boolean successflag =false;try{
conn =DBConnection.getConnection();String sql ="update student set name = ?,age = ?,hobby = ? where studentId = ?";
ps = conn.prepareStatement(sql);
ps.setObject(1, student.getName());
ps.setObject(2, student.getAge());
ps.setObject(3, student.getHobby());
ps.setObject(4, student.getStudentId());
ps.execute();}finally{DBConnection.close(rs, ps, conn);
successflag =true;}return successflag;}delete()publicstaticbooleandelete(int id)throwsSQLException{Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;boolean successflag =false;try{
conn =DBConnection.getConnection();String sql ="delete from student where studentId = ?";
ps = conn.prepareStatement(sql);
ps.setObject(1, id);
ps.execute();}finally{DBConnection.close(rs, ps, conn);
successflag =true;}return successflag;}
在数据库testDB中创建存储过程,名为getSnameAndClassBySno,其可以通过学号查询学生的姓名和班级信息。
createprocedure getSnameAndClassBySno(in id VARCHAR(25))BEGINSELECT*FROM student WHERE studentId=id;ENDCALL getSnameAndClassBySno(1);
在类StudentCRUD中定义方法,调用存储过程getSnameAndClassBySno。
// 调用存储过程publicstaticStudentgetStudentByid(int id)throwsSQLException{Connection conn =null;CallableStatement cs =null;ResultSet rs =null;Student stu =null;try{
conn =DBConnection.getConnection();String sql ="CALL getSnameAndClassBySno(?);";
cs =(CallableStatement) conn.prepareCall(sql);
cs.setInt(1, id);// 执行execute()
cs.execute();// 存储过程结果集
rs = cs.getResultSet();if(rs.next()){
stu =newStudent(rs.getInt(1),rs.getString(2),rs.getInt(3),rs.getString(4));}}finally{try{if(rs !=null){
rs.close();}}catch(SQLException e){
e.printStackTrace();}finally{try{if(cs !=null){
cs.close();}}catch(SQLException e){
e.printStackTrace();}finally{if(conn !=null){try{
conn.close();}catch(SQLException e){
e.printStackTrace();}}}}}return stu;}
创建TransactionTest类,使用JDBC事务管理实现用户转账功能。(注意,user表需要有float类型的字段money,并存在用于测试的2条用户记录)
// 使用JDBC事务管理实现用户转账功能publicclassTransactionTest{publicstaticvoidmain(String args[])throwsSQLException{transferAccounts(1,2,1000);}// 实现id1向id2转账money元publicstaticbooleantransferAccounts(int id1,int id2,float money)throwsSQLException{Connection conn =null;PreparedStatement ps1 =null;PreparedStatement ps2=null;ResultSet rs =null;boolean successflag =false;try{
conn =DBConnection.getConnection();
conn.setAutoCommit(false);//开启事务// id1 扣钱String sql1 ="update user set money = money - ? where userId = ?";
ps1 = conn.prepareStatement(sql1);
ps1.setObject(1,money);
ps1.setObject(2,id1);
ps1.executeUpdate();// 程序出问题了// int i = 10 / 0 ;// id2 加钱String sql2 ="update user set money = money + ? where userId = ?";
ps2 = conn.prepareStatement(sql2);
ps2.setObject(1,money);
ps2.setObject(2,id2);
ps2.executeUpdate();
conn.commit();//提交事务}finally{DBConnection.close(rs, ps, conn);
successflag =true;}return successflag;}}
4. Session 校验 (用户登录)
// 方式一: <%String username=(String)(session.getAttribute("username"));if(username==null|| username.equals("")){
response.sendRedirect("index.jsp");}%>// 方式二: <%@ include file="/LoginCheck.jsp"%><%
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");String path=request.getContextPath();//部署的应用程序名"/www" %><%String username=user.getUsername();if(username==null|| username.equals("")){
response.sendRedirect(path+"/index.jsp");}%>
5.JPA
User实体类
@EntitypublicclassUser{@Idprivateint id;privateString name;privateString password;privateint age;publicintgetId(){return id;}publicvoidsetId(int id){this.id = id;}// get set}
userDao
importentity.User;publicinterfaceUserDao{publicvoidadd(String name,String password,int age);publicvoiddelete(int id);publicvoidupdate(User user);publicUserget(int id);}
userDaoImplement
importjavax.persistence.EntityManager;publicclassUserDaoImplimplementsUserDao{EntityManagerFactory factory;EntityManager em;publicUserDaoImpl(){
factory =Persistence.createEntityManagerFactory(persistenceUnitName);
em = factory .createEntityManager();}publicvoidadd(String name ,String password,int age){User user =newUser();
user.setName( name);
user.setAge( age);
user.setPassword(password);
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit();}publicvoiddelete(int id){
em.getTransaction().begin();User user = em.find(User.class, id);if(user !=null){
em.remove(user);}
em.getTransaction().commit();}publicUserget(int id){User user = em.find(User.class,id);return user;}publicvoidupdate(User user){
em.getTransaction().begin();User user2= em.merge(user);
em.getTransaction().commit();}}
6.JavaBean
packagecom.sun.bean;importcom.sun.util.DBConnection;importcom.sun.util.Date_String;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;publicclassUserBean{privateint userid;privateString username;privateString password;privateString sex;privateint age;privateString birthday;publicintgetUserid(){return userid;}publicvoidsetUserid(int userid){this.userid = userid;}publicStringgetUsername(){return username;}publicvoidsetUsername(String username){this.username = username;}publicStringgetPassword(){return password;}publicvoidsetPassword(String password){this.password = password;}publicStringgetSex(){return sex;}publicvoidsetSex(String sex){this.sex = sex;}publicintgetAge(){return age;}publicvoidsetAge(int age){this.age = age;}publicStringgetBirthday(){return birthday;}publicvoidsetBirthday(String birthday){this.birthday = birthday;}// 验证用户登录信息publicbooleanvalidlogin()throwsSQLException{Connection conn =null;Statement st =null;ResultSet rs =null;boolean successflag=false;try{
conn =DBConnection.getConnection();String sql ="select * from user where name='"+this.username+"' and password='"+this.password+"'";
st = conn.createStatement();
rs=st.executeQuery(sql);if(rs.next()==true){successflag=true;}}finally{DBConnection.close(rs, st, conn);}return successflag;}publicList<UserBean>getUsersPage()throwsSQLException{List<UserBean> users=newArrayList<UserBean>();Connection conn =null;Statement st =null;ResultSet rs =null;try{
conn =DBConnection.getConnection();String sql ="select * from user limit 0,3";
st = conn.createStatement();
rs=st.executeQuery(sql);while(rs.next()==true){UserBean tmp=newUserBean();
tmp.setUserid(rs.getInt("id"));
tmp.setUsername(rs.getString("name"));
tmp.setPassword(rs.getString("password"));
tmp.setSex(rs.getString("sex"));
tmp.setAge(rs.getInt("age"));String birthday=Date_String.getStringDate1(rs.getDate("birthday"));
tmp.setBirthday(birthday);
users.add(tmp);}}finally{DBConnection.close(rs, st, conn);}return users;}// 条件查询 没用到publicList<UserBean>getUsers(String username,String sex)throwsSQLException{if(username==null) username="";if(sex==null) sex="";List<UserBean> users=newArrayList<UserBean>();Connection conn =null;Statement st =null;ResultSet rs =null;try{
conn =DBConnection.getConnection();String sql ="select * from user where name like '%"+username+"%' and ifnull(sex,'') like '%"+sex+"%'";
st = conn.createStatement();
rs=st.executeQuery(sql);while(rs.next()==true){UserBean tmp=newUserBean();
tmp.setUserid(rs.getInt("id"));
tmp.setUsername(rs.getString("name"));
tmp.setPassword(rs.getString("password"));
tmp.setSex(rs.getString("sex"));String birthday=Date_String.getStringDate1(rs.getDate("birthday"));
tmp.setBirthday(birthday);
users.add(tmp);}}finally{DBConnection.close(rs, st, conn);}return users;}// 查询用户信息publicstaticList<UserBean>getUsers()throwsSQLException{List<UserBean> users=newArrayList<UserBean>();Connection conn =null;Statement st =null;ResultSet rs =null;try{
conn =DBConnection.getConnection();String sql ="select * from user limit 0,3";
st = conn.createStatement();
rs=st.executeQuery(sql);while(rs.next()==true){UserBean tmp=newUserBean();
tmp.setUserid(rs.getInt("id"));
tmp.setUsername(rs.getString("name"));
tmp.setPassword(rs.getString("password"));
tmp.setSex(rs.getString("sex"));
tmp.setAge(rs.getInt("age"));String birthday=Date_String.getStringDate1(rs.getDate("birthday"));
tmp.setBirthday(birthday);
users.add(tmp);}}finally{DBConnection.close(rs, st, conn);}return users;}// 查询单个用户信息publicUserBeangetUserById(String userid)throwsSQLException{Connection conn =null;Statement st =null;ResultSet rs =null;UserBean user=null;try{
conn =DBConnection.getConnection();String sql ="select * from user where id="+userid;
st = conn.createStatement();
rs=st.executeQuery(sql);if(rs.next()==true){
user=newUserBean();
user.setUserid(Integer.valueOf(userid));
user.setUsername(rs.getString("name"));;
user.setPassword(rs.getString("password"));
user.setSex(rs.getString("sex"));
user.setAge(rs.getInt("age"));this.birthday=Date_String.getStringDate1(rs.getDate("birthday"));
user.setBirthday(birthday);}}finally{DBConnection.close(rs, st, conn);}return user;}// 修改用户个人信息publicvoidupdateUser()throwsException{Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;try{
conn =DBConnection.getConnection();String sql ="update user set name=?,sex=?,age=?,birthday=? where id="+this.userid;
ps = conn.prepareStatement(sql);
ps.setString(1,this.username);
ps.setString(2,this.sex);
ps.setInt(3,this.age);
ps.setTimestamp(4,Date_String.toTimestamp(this.birthday));
ps.executeUpdate();}finally{DBConnection.close(rs, ps, conn);}}// 删除用户个人信息publicvoiddelUserById(String userid)throwsException{Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;try{
conn =DBConnection.getConnection();String sql ="delete from user where id="+userid;
ps = conn.prepareStatement(sql);
ps.executeUpdate();}finally{DBConnection.close(rs, ps, conn);}}// 注册用户信息publicbooleanregisterUser(){Connection conn =null;PreparedStatement ps =null;try{
conn =DBConnection.getConnection();String sql ="insert into user(name,password) values( '"+this.username +"' , '"+this.password
+"')";
ps = conn.prepareStatement(sql);
ps.execute();returntrue;}catch(Exception e){}finally{DBConnection.close(null,ps, conn);}returnfalse;}// 增加用户信息publicvoidaddUser()throwsException{Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;try{
conn =DBConnection.getConnection();String sql ="insert into user(id,name,password,sex,age,birthday) values(?,?,?,?,?,?)";
ps = conn.prepareStatement(sql);
ps.setInt(1,this.userid);
ps.setString(2,this.username);
ps.setString(3,this.password);
ps.setString(4,this.sex);
ps.setInt(5,this.age);
ps.setTimestamp(6,Date_String.toTimestamp(this.birthday));
ps.executeUpdate();}finally{DBConnection.close(rs, ps, conn);}}// 校验输入的数据是否符合要求 add update 使用publicMap<String,String>checkUser()throwsException{Map<String,String> errors =newHashMap<String,String>();if(username==null||username.equals("")) errors.put("username","用户名不能为空!");if(password==null||password.equals("")) errors.put("password","密码不能为空!");return errors;}}
7.JSP展示层代码
error.jsp
<%@ page contentType="text/html; charset=utf-8" language="java" isErrorPage="true"%>
<html>
<head>
<title>错误页面</title>
</head>
<body>
<div id="error">发生了以下错误:</div><br><hr>
<%=exception.getMessage()%><br><hr>
<br>
</body>
</html>
exit.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" errorPage="error.jsp" %>
<%
session.invalidate();
response.sendRedirect("index.jsp");
%>
header.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ page import="java.util.*" %>
<%
String pathHeader=request.getContextPath();
%>
<div align="center" style="margin-top: 25px"><h3>学生管理系统</h3></div>
<div align="left">
<jsp:useBean id="LoginUser" class="com.sun.bean.UserBean" scope="session"/>
当前用户:<jsp:getProperty name="LoginUser" property="username"/>
当前时间:<%=(new java.util.Date()).toString() %>
<a href="<%=pathHeader%>/exit.jsp">退出系统</a>
</div>
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" %>
<%
String pathHeader = request.getContextPath();
String error = (String) request.getAttribute("error");
if (error == null) error = "";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Student Manager Login</title>
</head>
<body>
<h3>Student Manager Login</h3>
<form action="loginValid.jsp" method="post">
<table border=0>
<tr>
<td>用户名:</td>
<td><input name='name' type='text' value=''/></td>
</tr>
<tr>
<td>密码:</td>
<td><input name='password' type='password' value=''/></td>
</tr>
<tr>
<td colspan=2 align=right>
<input type="button" οnclick='location.href=("register.jsp")' value="注册账号" class="btn">
<input type="reset" value="重置" class="btn">
<input type='submit' value='登录'/></td>
</tr>
<tr>
<td colspan=2 align=right><%=error%>
</td>
</tr>
</table>
</form>
</body>
</html>
loginCheck.jsp
<%
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");String path=request.getContextPath();%><jsp:useBean id="user"class="com.sun.bean.UserBean" scope="session"/><%String username=user.getUsername();if(username ==null){
response.sendRedirect(path+"/index.jsp");}else{
session.setAttribute("LoginUser",user);}%>
loginValid.jsp
<%@ page import="java.sql.SQLException" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<body>
<jsp:useBean id="user" class="com.sun.bean.UserBean"/>
<jsp:useBean id="pageBeanUser" class="com.sun.bean.PageBean" scope="page"/>
<jsp:setProperty name="user" property="username" param="name"/>
<jsp:setProperty name="user" property="password"/>
<%
boolean successflag=user.validlogin();
if(successflag==true){
session.setAttribute("user", user);
response.sendRedirect("/test4/getUserListByPage");
}else{
request.setAttribute("error", "用户名或密码不正确,登陆失败!");
request.getRequestDispatcher("index.jsp").forward(request, response);
}
%>
</body>
Main.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><%@ include file="/loginCheck.jsp"%><!DOCTYPE html><html><head><title>StudentManager</title><link rel="stylesheet" type="text/css" href="css/style.css"/></head><body><div id="root"><div class="header"><%@include file="header.jsp"%></div><div class="menu"><%@include file="user/leftMenu.jsp"%></div><div class="listStudent"><%@include file="user/listStudent.jsp"%></div><div class="footer"><%@include file="footer.jsp"%></div></div></body></html>
8.JSTL
- 引入标签库语句:
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
- 导包语句
<%@page import="entity.User"%>
版权归原作者 请你喝杯Java. 所有, 如有侵权,请联系我们删除。