<body>
<a href="${pageContext.request.contextPath}/customer/addCustomer.action">增加用户</a>
<a href="${pageContext.request.contextPath}/customer/editCustomer.action">修改用户</a>
<a href="${pageContext.request.contextPath}/customer/findCustomer.action">查询用户</a>
<a href="${pageContext.request.contextPath}/customer/delCustomer.action">删除用户</a>
</body>
2、在struts.xml中配置
如下图所示:
<struts>
<constant name="struts.devMode" value="true" />
<package name="p1" extends="struts-default" namespace="/customer">
<action name="addCustomer" class="xgp.struts.actions.CustomerAction" method="add">
<result name="success" type="dispatcher">/addCustomer.jsp</result>
<result name="error" type="dispatcher">/error.jsp</result>
</action>
<action name="editCustomer" class="xgp.struts.actions.CustomerAction" method="edit">
<result name="success" type="dispatcher">/editCustomer.jsp</result>
</action>
<action name="findCustomer" class="xgp.struts.actions.CustomerAction" method="find">
<result name="success" type="dispatcher">/findCustomer.jsp</result>
</action>
<action name="delCustomer" class="xgp.struts.actions.CustomerAction" method="del">
<result name="success" type="dispatcher">/delCustomer.jsp</result>
</action>
</package>
</struts>
3、建立动作处理类CustomerAction
package xgp.struts.actions;
import xgp.struts.service.BusinessService;
import xgp.struts.serviceImpl.BusinessServiceImpl;
import com.opensymphony.xwork2.ActionSupport;
public class CustomerAction extends ActionSupport{
private BusinessService bs = new BusinessServiceImpl();
public String add(){
//调用Service添加方法
try {
bs.add();
return SUCCESS;
} catch (Exception e) {
return ERROR;
}
}
public String edit(){
bs.edit();
return SUCCESS;
}
public String find(){
bs.find();
return SUCCESS;
}
public String del(){
bs.del();
return SUCCESS;
}
}
4、建立相应的业务接口BusinessService和实现类BusinessServiceImpl
BusinessService
package xgp.struts.service;
public interface BusinessService {
public void add();
public void edit();
public void del();
public Object find();
}
BusinessServiceImpl
package xgp.struts.serviceImpl;
import xgp.struts.service.BusinessService;
public class BusinessServiceImpl implements BusinessService{
@Override
public void add() {
System.out.println("Serviece的add方法执行成功!");
}
@Override
public void edit() {
System.out.println("Serviece的edit方法执行成功!");
}
@Override
public void del() {
System.out.println("Serviece的del方法执行成功!");
}
@Override
public Object find() {
System.out.println("Serviece的find方法执行成功!");
return null;
}
}
结果如下:
1、使用通配符配置Action
在配置<action...>
元素时,允许在指定name属性时,使用模式字符串(用"*"
代表一个或多个任意字符)
在class、method属性及<result>
子元素中通过 {N} 形式代表前面地N个*
匹配子串
例如上面的案例中struts.xml我们可以改写如下:
<!-- 使用通配符:\*
{2}:匹配第2个星花的内容
-->
<!-- http://localhost:8080/xgp.struts/customer/add\_Customer.action
第一个\*: add
第二个\*:Customer
-->
<action name="\*\_\*" class="xgp.struts.actions.{2}Action" method="{1}">
<result name="success" type="dispatcher">/{1}{2}.jsp</result>
</action>
2、使用Action的动态方法调用(官方不建议使用)
动态方法调用:DMI
http://localhost:8080/xgp.struts/customer/add_Customer!add
希望执行CustomerAction的add动作方法(动态方法调用)
动态方法调用:Struts2框架默认是禁止的。可以通过配置一个常量打开它:
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
通过url动态指定调用Action哪个方法而无需配置<action>
的method属性, 通过 !方法名 指定调用Action哪个方法
<a href="${pageContext.request.contextPath}/customer/customer!add.action">添加用户</a><br/>
<a href="${pageContext.request.contextPath}/customer/customer!edit.action">修改用户</a><br/>
<a href="${pageContext.request.contextPath}/customer/customer!del.action">删除用户</a><br/>
3、配置默认Action和 配置Action默认处理类
用户可以为每个package定义一个默认的Action,如果访问路径在package没有匹配<action>
就会执行默认action
<default-action-ref name="defaultAction"></default-action-ref>
<action name="defaultAction">
<result name="success" type="dispatcher">/whatareuwant.jsp</result>
</action>
如果配置<action>
没有指定class属性,就会执行Action的默认处理类,在struts-default.xml中.
指定默认的动作处理类
<!-- 指定默认的动作:当用户访问的动作在本包中没有找到时执行的动作 -->
<default-action-ref name="defaultAction"></default-action-ref>
<!-- 指定默认的动作处理类 -->
<default-class-ref class="xgp.struts.actions.DefaultAction"></default-class-ref>
<action name="customer" class="xgp.struts.actions.CustomerAction">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
<action name="defaultAction">
<result name="success" type="dispatcher">/whatareuwant.jsp</result>
</action>
三、在动作类中访问ServletAPI
Struts2的Action没有与任何Servlet API耦合,便于测试.这是他的优点之一.
1、三大实现方法
1、ActionContext
- getContext() 返回ActionContext实例对象
- get(key) 相当于 HttpServletRequest的getAttribute(String name)方法
- put(String,Object) 相当于HttpServletRequest的setAttribute方法
- getApplication() 返回一个Map对象,存取ServletContext属性
- getSession() 返回一个Map对象,存取HttpSession属性
- getParameters() 类似调用HttpServletRequest的getParameterMap()方法
- setApplication(Map) 将该Map实例里key-value保存为ServletContext的属性名、属性值
- setSession(Map) 将该Map实例里key-value保持为HttpSession的属性名、属性值
2、方式二:(简单,推荐使用)使用ServletActionContext
static PageContext getPageContext()
static HttpServletRequest getRequest()
static HttpServletResponse getResponse()
static ServletContext getServletContext()
该方案可避免Action类实现XxxAware接口,但Action依然与Servlet API直接耦合
开发中优先使用ActionContext 这样可以避免耦合
package com.itheima.actions;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class ServletAPIAction1 extends ActionSupport{
//打印当前应用名称到控制台上
//获取ServletAPI有关类的实例
//方式一:
public String execute() throws Exception {
//实际上利用ThreadLocal这个类
//ServletActionContext:记住
HttpServletRequest request = ServletActionContext.getRequest();
System.out.println(request.getContextPath());
PageContext pc = ServletActionContext.getPageContext();
HttpServletResponse response = ServletActionContext.getResponse();
response.getWriter().write(request.getContextPath());//自己输出
ServletContext sc = ServletActionContext.getServletContext();
System.out.println(sc.getRealPath("/"));
return NONE;
}
}
**3、方式三:(麻烦)**实现接口,访问Action时完成注入
ServletContextAware
void setServletContext(javax.servlet.ServletContext context)
ServletRequestAware
void setServletRequest(javax.servlet.http.HttpServletRequest request)
ServletResponseAware
void setServletResponse(javax.servlet.http.HttpServletResponse response)
动作类实现特定的接口。就必须实现特定的方法,调用动作方法前,框架会把响应的对象给注入进来。
package com.itheima.actions;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.opensymphony.xwork2.ActionSupport;
//获取ServletAPI有关类实例的方式二
public class ServletAPIAction2 extends ActionSupport implements ServletRequestAware,ServletResponseAware{
private HttpServletRequest request;
private HttpServletResponse response;
//该方法会在调用动作方法之前先执行:把当前的HttpServletRequest对象给你注入进来
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
@Override
public String execute() throws Exception{
//要使用HttpServletRequest对象
//System.out.println(request.getContextPath());
response.getWriter().write(request.getContextPath());
return NONE;
}
}
**原理:**是一个拦截器给你注入进来的。struts-default.xml
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
一看源码便知。
配置struts.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="p1" extends="struts-default">
<!-- 因为包继承了struts-default,默认使用struts-default.xml中定义的那个默认的拦截器栈:defaultStack
在执行动作方法之前:defaultStack中的组员都会拦截你的动作调用
包含:一个叫做servletConfig的拦截器。
-->
<!-- 演示在动作类中获取Servlet有关的类的实例:HttpServletRequest HttpServletResponse HttpSession ServletContext等
Struts2已经将ServletAPI和动作类进行解耦,这是他的优点之一
-->
<action name="showContextPath1" class="com.itheima.actions.ServletAPIAction1">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
<action name="showContextPath2" class="com.itheima.actions.ServletAPIAction2" method="execute">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
</package>
</struts>
2、局部和全局结果视图
result元素:指定动作类的动作方法执行完后的结果视图.
属性:
- name:字符串,与动作方法返回的值一致。默认是success
- type:指定处理结果的结果类型的别名。(struts-default.xml有定义,共10个)。默认值是dispatcher
Action处理完用户请求后,将返回一个普通字符串整个普通字符串就是一个逻辑视图名,Struts2 根据逻辑视图名,决定响应哪个结果。
Struts2处理结果使用<result>
元素配置
- 局部结果:将
<result>
作为<action>
子元素配置 - 全局结果:将
<result>
作为<global-results>
元素的子元素配置
配置<result>
元素通常需要指定两个属性
- name 该属性指定配置逻辑视图名
- type 该属性指定结果类型
当多个action中都使用到了相同result,这时我们应该把result定义为全局结果。struts1中提供了全局forward,struts2中也提供了相似功能:
<package ....>
<global-results>
<result name="message">/message.jsp</result>
</global-results>
</package>
注:局部的会覆盖全局
Struts1中应用范围内action的实例 action是单实例(执行时,现在缓存中查找实例,有用,没有创建新的实例)Struts2中 应用范围内action的实例,每个请求都会创建一个action实例Servlet属于单实例多线程的应用,实例只在初始化时被加载多实例比单实例的优点,不会产生并发问题,但执行速度不如单实例。
如下:
<struts>
<constant name="struts.devMode" value="true" />
<package name="mydefault" extends="struts-default" abstract="ture">
<global-results>
<result name="success" type="dispatcher">/success.jsp</result>
</global-results>
</package>
<package name="p1" extends="mydefault">
<action name="action1" class="xgp.struts.actions.Demo1Action">
<!-- <result name="success" type="dispatcher">/success.jsp</result> -->
</action>
<action name="action2" class="xgp.struts.actions.Demo2Action">
<!-- <result name="success" type="dispatcher">/success.jsp</result> -->
</action>
</package>
<package name="p2" extends="mydefault">
<action name="action3" class="xgp.struts.actions.Demo3Action">
<!-- <result name="success" type="dispatcher">/success.jsp</result> -->
</action>
</package>
</struts>
3、Struts2提供的结果视图 (共10个)
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
1. chain:从一个动作转发到另外一个动作
同一个包内的动作转发
<package name="p3" namespace="/result" extends="struts-default">
<!-- action1的结果是另外一个Action的请求:一个动作转发到了另外一个动作
演示:同包内的动作转发-->
<action name="action1">
<result name="success" type="chain">action2</result>
</action>
<action name="action2">
<result>/success.jsp</result>
</action>
</package>
不同包之间的动作转发
<package name="p3" namespace="/result" extends="struts-default">
<action name="action1">
<result name="success" type="chain">
<param name="namespace">/user</param> 给chain的实际处理类注入参数
<param name="actionName">action2</param>
</result>
</action>
</package>
2. dispatcher:从一个动作转发到另外一个JSP
dispatcher 结果类型是最常用的结果类型, 也是 struts 框架默认的结果类型
该结果类型有一个 location 参数, 它是一个默认参数
dispatcher 结果类型将把控制权转发给应用程序里的某个资源
3. redirect:从一个动作重定向到一个JSP
最明显的是地址栏发生变化。
<action name="action2">
<result type="redirect">/success.jsp</result>
</action>
4. redirectAction:从一个动作重定向到另外一个动作
action1先将动作重定向到action2,然后action2在转发到success.jsp,地址栏应该显示的是action2.
<action name="action1">
<result name="success" type="redirectAction">action2</result>
</action>
<action name="action2">
<result>/success.jsp</result>
</action>
下面是我在学习HTML和CSS的时候整理的一些笔记,有兴趣的可以看下:
![HTML、CSS部分截图](https://img-blog.csdnimg.cn/img_convert/2bb6b442a4432372fe5b9ccea2ad93d0.png)
### 进阶阶段
进阶阶段,开始攻 JS,对于刚接触 JS 的初学者,确实比学习 HTML 和 CSS 有难度,但是只要肯下功夫,这部分对于你来说,也不是什么大问题。
JS 内容涉及到的知识点较多,看到网上有很多人建议你从头到尾抱着那本《JavaScript高级程序设计》学,我是不建议的,毕竟刚接触 JS 谁能看得下去,当时我也不能,也没那样做。
我这部分的学习技巧是,增加次数,减少单次看的内容。就是说,第一遍学习 JS 走马观花的看,看个大概,去找视频以及网站学习,不建议直接看书。因为看书看不下去的时候很打击你学下去的信心。
然后通过一些网站的小例子,开始动手敲代码,一定要去实践、实践、实践,这一遍是为了更好的去熟悉 JS 的语法。别只顾着来回的看知识点,眼高手低可不是个好习惯,我在这吃过亏,你懂的。
**1、JavaScript 和 ES6**
在这个过程你会发现,有很多 JS 知识点你并不能更好的理解为什么这么设计,以及这样设计的好处是什么,这就逼着让你去学习这单个知识点的来龙去脉,去哪学?第一,书籍,我知道你不喜欢看,我最近通过刷大厂面试题整理了一份前端核心知识笔记,比较书籍更精简,一句废话都没有,这份笔记也让我通过跳槽从8k涨成20k。
![JavaScript部分截图](https://img-blog.csdnimg.cn/img_convert/cac778dc45492a41e2f3e7cd6b0134e5.png)
**2、前端框架**
前端框架太多了,真的学不动了,别慌,其实对于前端的三大马车,Angular、React、Vue 只要把其中一种框架学明白,底层原理实现,其他两个学起来不会很吃力,这也取决于你以后就职的公司要求你会哪一个框架了,当然,会的越多越好,但是往往每个人的时间是有限的,对于自学的学生,或者即将面试找工作的人,当然要选择一门框架深挖原理。
**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**
以 Vue 为例,我整理了如下的面试题。
![Vue部分截图](https://img-blog.csdnimg.cn/img_convert/c6738a80c94640db83f7ffbf487ac5f0.png)