文章目录
一、基础
参考:https://mp.weixin.qq.com/s/6Mln9NOR2vg0p7u4Sc7kxQ
1.1 含义
含义:相当于Servlet的框架,Servlet的升级版。web请求与处理方法的映射。
作用:
1、框架帮我们封装了很多常用的功能。
——把Web带过来的参数自动封装到JavaBean中。
2、更加灵活。
——不用把路径等信息写死在程序上,使用配置文件来管理路径。若目录发生变化,不用一个一个去修改每个程序的路径。
3、更加简洁。
——每个Servlet中都有doGet和doPost这样的方法,没必要的。抽取出来,通过配置文件来把这两个方法替换掉,程序就会更加简洁、优雅。
1.2 用户登陆注册
1.2.1 DAO层和Service层
UserDao.java
public class UserDao {
public User login(User user) {
if ("admin".equals(user.getUsername()) && "123456".equals(user.getPsd())){
System.out.println("登陆成功!");
return user;
} else {
System.out.println("登陆失败!");
return null;
}
}
public void register(User user) {
System.out.println("注册成功!" + user.getUsername());
}
}
UserService.java
public class UserService {
private UserDao userDao = new UserDao();
public User longin(User user) {
return userDao.login(user);
}
public void register(User user) {
userDao.register(user);
}
}
1.2.2 JSP层
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="post">
用户名:<input type="text " name="username">
密码:<input type="password " name="psd">
<input type="submit" value="登陆">
</form>
</body>
</html>
register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">
用户名:<input type="text " name="username">
密码:<input type="password " name="psd">
<input type="submit" value="注册">
</form>
</body>
</html>
1.2.3 传统方法——Servlet层
说明
前端控制器:Servlet。
1、直接使web请求的url与Servlet的方法进行映射
2、然后进行页面的内部转发或请求重定向,到相应的页面。
LoginServlet.java
// 此处使用了注解,也可以使用web.xml设置web请求与Servlet的映射。
@javax.servlet.annotation.WebServlet(name = "LoginServlet",urlPatterns = "/servlet/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 第一步:得到用户带过来的数据,并封装到Bean对象中
String username = request.getParameter("username");
String psd = request.getParameter("psd");
User user = new User();
user.setPsd(psd);
user.setUsername(username);
try {
// 第二步:调用Service层方法
UserService userService = new UserService();
userService.longin(user);
// 第三步:跳转到相应页面
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
//登陆失败,跳转到相关的提示页面
request.setAttribute("message","登陆失败了!!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
RegisterServlet.java
@javax.servlet.annotation.WebServlet(name = "RegisterServlet",urlPatterns = "/servlet/RegisterServlet")
public class RegisterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String psd = request.getParameter("psd");
User user = new User();
user.setPsd(psd);
user.setUsername(username);
try {
UserService userService = new UserService();
userService.register(user);
request.getRequestDispatcher("/login.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
request.setAttribute("message","注册失败了!!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
web.xml
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/servlet/LoginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RegisterServlet</servlet-name>
<servlet-class>servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RegisterServlet</servlet-name>
<url-pattern>/servlet/RegisterServlet</url-pattern>
</servlet-mapping>
缺点:
1、一个功能对应一个Servlet,太麻烦了。
2、跳转页面的路径是写死的。在注册成功了以后,可以跳转到首页上,也可以跳转到登陆的界面上。如果我要选择其中的一个,就必须修改源代码。
1.2.4 新型方法——Servlet层
使用Struts2框架进行管理,提高开发效率。
Action作用:代替Servlet的作用,同时将url与方法、页面映射单独写在一个xml文件中,目的简洁明了,便于维护。
Struts2框架预先实现了一些功能:
——请求数据自动封装
——文件上传的功能
——对国际化功能的简化
——数据效验功能等
二、Struts2开发步骤
2.1 配置环境
2.1.1 引入jar文件
常用jar包 | 作用 |
---|---|
commons-fileupload-1.2.2.jar | 文件上传相关包 |
commons-io-2.0.1.jar | 文件上传相关包 |
struts2-core-2.3.4.1.jar | struts2核心功能包 |
xwork-core-2.3.4.1.jar | Xwork核心包 |
ognl-3.0.5.jar | Ognl表达式功能支持表 |
commons-lang3-3.1.jar | struts对java.lang包的扩展 |
freemarker-2.3.19.jar | struts的标签模板库jar文件 |
javassist-3.11.0.GA.jar | struts对字节码的处理相关jar |
2.1.2 配置web.xml
配置Struts2核心过滤器.
注意:若web.xml配置了多个fileter,那么struts的filter需要在最后面!
<!-- 引入struts核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- struts过滤器映射。过滤的URL类型。 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.2 开发Action
Action类也叫动作类,处理请求的类。
1、extends ActionSupport类。
2、重写execute()方法,当然也可以不重写。
public class HelloAction extends ActionSupport {
@Override
public String execute() throws Exception {
System.out.println("helloworld");
return "success";
}
}
2.3 配置struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="hello" extends="struts-default">
<action name="hello" class="action.HelloAction" method="execute">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
三、Struts2执行流程
3.1 服务器启动
加载顺序:
1、加载web.xml文件。
2、找到我们配置的filter中的StrutsPrepareAndExecuteFilter
3、StrutsPrepareAndExecuteFilter在里边执行init()方法。
4、一直到Dispatcher dispatcher = init.initDispatcher(config);,初始化dispatcher
5、在初始化dispatcher的时候加载struts-default.xml和我们配置的struts.xml
struts-default.xml:
1、< bean>标签: 指定了struts在运行的时候需要创建的对象类型。
——在运行struts的时候,可能需要创建一些对象,那么就通过Bean来指定。
2、< interceptor>标签: 是struts定义的拦截器,一共有32个。
——Struts为我们实现了一些功能,就是通过拦截器来实现的。
3、< result-type>标签: 跳转结果的类型。
——Action业务方法中的返回值。redirect【重定向】、dispatcher【转发】、redirectAction【重定向到Action资源】、stream【文件下载的时候用】。
4、< interceptor-stack>标签:拦截器的栈。
——拦截器有32个,我们可能会使用很多的拦截器,不可能一个一个来调用,于是提供了拦截器栈…其实可以简单看成**文件夹和文件之间的关系 **。
5、< default-interceptor-ref>标签:默认执行的拦截器栈,默认的拦截器栈有18个拦截器。
6、< default-class-ref>标签:默认的执行Action类。
拦截器和过滤器
1、拦截器和过滤器都是拦截资源的。
2、拦截器只拦截Action请求,是struts的概念。
3、过滤器拦截web的所有资源,是Servlet的概念。
小总结
1、服务器启动的时候,其实就是加载了web.xml文件,然后调用init()方法去加载struts.xml和struts-default.xml之类的文件……
2、此时的拦截器是还没有被调用的。
3.2 访问阶段
在服务器启动的阶段,仅仅是加载了各种的xml文件。
访问Action时的执行流程:
1、它会创建我们在struts.xml中配置的Action对象。
2、它会按照默认的顺序执行18个拦截器【也就是调用默认拦截器栈】。
3、它会执行Action的业务方法【也就是execute(),我们在struts.xml文件中配置了什么,就执行什么业务方法】。
注意:每访问Action一次,它就会创建一个对象。它并不是和Servlet一样只有一个对象。因此它是线程安全的。
四、struts.xml
<struts>
<package name="hello" extends="struts-default">
<action name="hello" class="action.HelloAction" method="execute">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
4.1 package标签
含义:package其实就是包。包就是用来管理Action。
注意:通常,一个业务模版对应一个package。
属性:
name:包的名字。包的名称是不能重复的。
extends:当前包继承着哪个包。在struts中,包一定要继承着struts-default。
abstract:当前包被其他的包继承…并且,在package下不能有action,否则会出错!
namespace:作为路径的一部分的,默认是"/"。
4.2 actoin标签
含义:置请求路径与Action类的映射关系
属性:
name:请求路径的名字
class:处理action类的全名。
method:调用的方法名称
4.3 result标签
含义:是Action中业务方法返回的值
属性:
name:action处理返回的值。
type:跳转的类型。redirect【重定向】、dispatcher【转发】、redirectAction【重定向到Action资源】、stream【文件下载的时候用】。
文本值:跳转的路径。
4.4 子xml文件
1、一个package应该对应一个业务模块,目的就是把职能细分出来
2、struts为了让我们更好地管理xml文件,它还可以这样做:在不同的模块中用不同的xml文件进行描述…
3、在struts.xml文件中将其引入即可。
<!--struts在运行的时候总会加载这个文件-->
<!--总配置文件总引入其他的文件-->
<struts>
<include file="privilegeaction/privilege.xml"/>
<include file="useraction/hello.xml"/>
</struts>