自动装配
1.根据属性的getter和setter获取值
index.jsp
<s:form action="hello" method="POST">
用户名:<s:textfield name="username"/><br>
密码<s:password name="password"/>
<s:submit value="登录"/>
</s:form>
在后台我们需要封装两个字段,字段的名字就跟文本框的name值一样即可,注意要有getter和setter方法,否则映射不到,就获取不到值
HelloAction:
public class HelloAction implements Action {
private String username;
private String password;
@Override
public String execute() throws Exception {
if (username.equals("1")&&password.equals("1")){
//获取session,将username保存在session
ActionContext context = ActionContext.getContext();
Map<String, Object> session = context.getSession();
session.put("username",username);
return SUCCESS;
}else{
return "index";
}
}
//getter和setter方法
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
struts.xml
<action name="hello" class="cn.struts.action.HelloAction">
<result name="index" >/index.jsp</result>
<result name="success">/main.jsp</result>
</action>
这样就可以回去前台传过来的值,输出结果
${username}
如果一个bean中的字段有很多不可能用这样的方式,所以我们将字段封装成一个bean传到后台
2.将属性封装bean传到后台
实体类:
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
HelloAction:
在HelloAction中,将Use实体类封装gettersetter方法,在页面中用对象.属性
private User user;
//1.封装成bean对象 在页面用user.属性
@Override
public String execute() throws Exception {
if (user.getUsername().equals("1")&&user.getPassword().equals("1")){
//将name值存在session中
ActionContext context = ActionContext.getContext();
Map<String, Object> session = context.getSession();
session.put("username",user.getUsername());
return SUCCESS;
}else{
return "index";
}
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
struts.xml文件不变
index.jsp
<s:form action="hello" method="POST">
用户名:<s:textfield name="user.username"/><br>
密码<s:password name="user.password"/>
<s:submit value="登录"/>
</s:form>
3.实现ModelDriven<T>
在Struts2中,提供了另外一种直接使用域对象的方式,就是让action实现ModelDriven接口。
ModelDriven让你可以直接操作程序中的领域对象,允许你在Web层和业务逻辑层使用相同的对象
index.jsp
<s:form action="hello" method="POST">
用户名:<s:textfield name="username"/><br>
密码<s:password name="password"/>
<s:submit value="登录"/>
</s:form>
HelloAction2:
要实现ModelDriven就要重写getModel方法,在getModel方法中直接返回实体类对象
但是实体类对象要实体化
public class HelloAction2 implements Action,ModelDriven<User> {
private User user=new User();
//2.实现ModelDriven 要把对象实例化 页面就不用点属性 直接与实体类名字即可
@Override
public String execute() throws Exception {
if (user.getUsername().equals("2")&&user.getPassword().equals("2")){
ActionContext context = ActionContext.getContext();
Map<String, Object> session = context.getSession();
session.put("username",user.getUsername());
return SUCCESS;
}else{
return "index";
}
}
@Override
public User getModel() {
return user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
struts.xml
<!--使用实现ModelModelDriven自动装配bean-->
<action name="hello2" class="cn.struts.action.HelloAction2">
<result name="index" >/index.jsp</result>
<result name="success">/main.jsp</result>
</action>
访问Servlet API
在登录的时候,我们都要讲用户存入session中,struts中没有session怎么办,所以我们要借助servlet API来创建session和request等作用域
什么是ServletAPI呢? 就是用来接收请求或发送请求使用的一些类或接口
两种方式分为解耦和耦合
一.与Servlet API解耦的访问方式
1.对Servlet API进行封装 ,借助ActionContext
提供了三个Map对象访问request、session、application作用域
通过ActionContext类获取这三个Map对象
Object get("request") //获取request
Map getSession() //获取session
Map getApplication() //获取application
案例:登陆后将名称存在session
private User user;
//1.封装成bean对象 在页面用user.属性
@Override
public String execute() throws Exception {
if (user.getUsername().equals("1")&&user.getPassword().equals("1")){
//解耦方式1 通过ActionContext获取session
ActionContext context = ActionContext.getContext();
//在底层session也是一个map集合
Map<String, Object> session = context.getSession();
session.put("username",user.getUsername());
return SUCCESS;
}else{
return "index";
}
}
获取username
欢迎${username}
2.实现SessionAware
向Action中注入ServletAPI对象对应的Map对象
public class Action1 implements Action,SessionAware {
//实现SessionAware 获取session
private Map<String, Object> map;
@Override
public String execute() throws Exception {
map.put("uname","小花");
return SUCCESS;
}
@Override
public void setSession(Map<String, Object> map) {
this.map=map;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
获取结果方式
欢迎${uname}
二.与Servlet API耦合的访问方式
1.通过ActionContext的子类ServletActionContext实现
//耦合方式1 使用ServletActionContext
@Override
public String execute() throws Exception {
HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute("uname","小明");
return SUCCESS;
}
2.向Action实例注入Servlet API对象
实现ServletRequestAware获取request在获取session
public class Action3 implements Action,ServletRequestAware {
//耦合方式2 实现
private HttpServletRequest request;
@Override
public String execute() throws Exception {
HttpSession session = request.getSession();
session.setAttribute("uname","小绿");
return SUCCESS;
}
@Override
public void setServletRequest(HttpServletRequest httpServletRequest) {
this.request=httpServletRequest;
}
public HttpServletRequest getRequest() {
return request;
}
public void setRequest(HttpServletRequest request) {
this.request = request;
}
获取结果方式:欢迎${uname}
继承ActionSupport
实现Action必须重写Excute方法,默认执行excute方法,如果想要添加或执行别的方法怎么办,那就继承ActionSupport可以不必须重写excute方法
public class DmiAction extends ActionSupport {
public String add(){
return "add";
}
public String update(){
return "update";
}
}
struts.xml
<!--一个类中有多个方法 使用method指定要指定的方法-->
<action name="dmiAction" class="cn.struts.action.DmiAction" method="add" >
<result name="add">/add.jsp</result>
</action>
<action name="dmiAction" class="cn.struts.action.DmiAction" method="update">
<result name="update">/update.jsp</result>
</action>
在struts.xml中有很多action节点,即不美观又不容易理解,怎么办??
我们知道底层只能解析到struts.xml名字是固定的,想要创建多个XML文件也是可以的,需要用到 include,将其他名字的文件包含到struts.xml中,这样就可以配置多个XML文件了
1.创建其他的XML文件
2.在struts.xml中添加include节点,这样就可以配合多个文件了,但是注意的时,每个XML文件中的package的名字不一样否则会报错
<include file="struts2.xml"/>
struts.xml
<package name="default" namespace="/" extends="struts-default">
struts.xml2
<package name="dmi" namespace="/" extends="struts-default">
当继承ActionSupport的时候,我们就要配置相对的action节点,方法越多,action越多,怎么办??
这时可以动态加载页面
配置一个action,将返回的值返回不同的页面
<!--但是一个类中有n个方法 不能配置多个action 所以使用动态访问页面-->
<!--路径加上!方法名 dmiAction!add 进入add页面 -->
<action name="dmiAction" class="cn.struts.action.DmiAction" >
<result name="add">/add.jsp</result>
<result name="update">/update.jsp</result>
</action>
在页面中使用 访问路径!方法名 就会进入不同的页面