Struts视频笔记:

Struts是一个开源的web框架,框架提高了程序的规范的同时也约束了程序员的自由

为什么会有struts:

因为我们队mvc理解的不同,可能造成不同公司写程序的时候,规范不统一,这样不利于程序的维护和扩展,所以我们有必要用一个统一的规范来开发项目(struts)

Struts 的好处: 程序更加规范化,开发效率提高了,可读性增加了,程序的可维护性增加了

运行原理:

一个请求从浏览器发送给web服务器,http://localhost:8080/web应用/action,web服务器首先解析主机à然后解析web应用的名称à在解析出资源名à转发给总司令ActionServlet(该类由struts框架提供给我们的无需编写,只需配置)àActionServlet有一个文件struts-config.xml,该文件配置了表单actionForm(军火库),还配置了action,以及他们之间的对应关系,当ActionServlet拿到命令后它会查询struts-config.xml文件去填充数据,把用户的数据填充到表单里边,à下个动作就是去调用指定的action(小队长),action去从表单中读取数据,à调用某个model(士兵,如service)完成任务,à完成任务把结果返回给ActionServlet总司令(返回一个执行的结果),-->总司令又去查询struts-config.xml文件,决定跳转到哪个jsp页面,à返回一个执行结果(形成静态html文件)à直接返回给web服务器à服务器再把静态页面以http响应给浏览器

,登录小项目过程步骤: 新建web工程à导入struts包à编写login.jspà编写actionForm和actionà配置struts-config.xmlà编写ok.jsp和err.jsp à配置web.xml à测试

点击finish,自动创建web.xml和struts-config.xml。

Struts-config.xml中的<action>中的scope指的是actionform的生命周期范围 struts中<action>的scope默认是session

配置过滤器

public class MyFilter extends HttpServlet implements Filter {

@Override

public void doFilter(ServletRequest arg0, ServletResponse arg1,

FilterChain arg2) throws IOException, ServletException {

arg0.setCharacterEncoding("gb2312");

arg1.setCharacterEncoding("gb2312");

arg2.doFilter(arg0, arg1);

}

配置web.xml

<filter>

<filter-name>MyFilter</filter-name>

<filter-class>com.chao98.services.MyFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>MyFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

上面这次比较浪费资源每次都要去实例化 但是下面这种过滤器不太彻底,往数据库里插入数据时还是会经常出现乱码

public class MyFilter extends HttpServlet implements Filter {

private String encoding;

public void doFilter(ServletRequest arg0, ServletResponse arg1,

FilterChain arg2) throws IOException, ServletException {

// arg0.setCharacterEncoding("gb2312");

//arg1.setCharacterEncoding("gb2312");

arg0.setCharacterEncoding(encoding);

arg2.doFilter(arg0, arg1);

}

public void init(FilterConfig arg0) throws ServletException {

encoding=arg0.getInitParameter("encoding");

}

然后在web.xml中加入

<init-param>

<param-name>encoding</param-name>

<param-value>GB2312</param-value>

</init-param>

配置struts-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5"

xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<servlet>

<servlet-name>action</servlet-name>

<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

<init-param>

<param-name>config</param-name>

<param-value>/WEB-INF/struts-config.xml</param-value>

</init-param>

<init-param>

<param-name>debug</param-name>

<param-value>2</param-value>

</init-param>

<init-param>

<param-name>detail</param-name>

<param-value>2</param-value>

</init-param>

<load-on-startup>2</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>action</servlet-name>

<url-pattern>*.action</url-pattern>

</servlet-mapping>

写一个关于安全性的过滤器,用于过滤一些用户注册使用的关键字

private String keywords[];

public void doFilter(ServletRequest arg0, ServletResponse arg1,

FilterChain arg2) throws IOException, ServletException {

String username=arg0.getParameter("username");

System.out.println("this is safe filter !");

System.out.println(username);

if(username!=null){

for(String key:keywords){

if(key.equals(username)){

arg0.setAttribute("err", username+"被第二个管理安全的过滤器拦截了");

arg0.getRequestDispatcher("/WEB-INF/tishi.jsp").forward(arg0, arg1);

return ;

}

}

}

arg2.doFilter(arg0, arg1);

}

public void init(FilterConfig arg0) throws ServletException {

keywords=arg0.getInitParameter("keywords").split(";");

}

然后在web.xml配置过滤器还有设置要过滤的关键字

<init-param>

<param-name>keywords</param-name>

<param-value>xiaomao;xiaoxiao</param-value>

</init-param>

每个action是单态的,包括actionserver,对网站并发性有影响 若要证明的话在***action.java中声明一个静态变量,每次访问自加

什么是单态: 单态是指在整个运行过程中,始终是一个对象;

struts-config.xml默认放在WEB-INF目录下,也可以放到其他地方,只需要在web.xml中的

<init-param>

<param-name>config</param-name>

<param-value>/WEB-INF/struts-config.xml</param-value>

</init-param>

有多个struts-config.xml只需用","号隔开

java 中插入数据库的语句需要注意标点 st.executeUpdate("insert into user(username,password) values("+"'"+u.getUsername()+"'"+","+"'"+u.getPassword()+"'"+")");

jstl(jsp startand tag liblary) jsp标准标签库: 可以提高开发速度,代码简洁

升级jsp  页面 <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">替换8.5myeclipse:

D:\Program\Files\Myeclipse\Common\plugins\com.genuitec.eclipse.wizards_8.5.0.me201003052220.jar\templates\jsp\jsp.vtl的

6.5myeclipse:D:\ProgramFiles\MyEclipse6.5\myeclipse\eclipse\plugins\com.genuitec.eclipse.wizards_6.5.0.zmyeclipse650200806\templates\jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 这样比较符合现在的开发潮流

各个jstl标签

<c:out>:

<c:out value="hello world"></c:out>

<c:out value="${username}" default="没有值" escapeXml="false" ></c:out>等同于request.getAttribute("user").toString();

escapeXml表示是否安装html样式显示 默认是true:表示以文本显示

如何输出request,session,application, pageContext域对象的数据

<%

request.setAttribute("hello","request你好!");

session.setAttribute("hello","session你好!");

application.setAttribute("hello","application你好");

pageContext.setAttribute("hello","pageContext你们<a href='http://www.baidu.com'>百度</a>");

%>

这里有个优先级的问题,pageContext>request>session>application

<c:out value="${hello}" default="没有值" escapeXml="false" >

如果是在同一个页面,那么这段代码输出pageContext你们好百度 

<%

User u=new User();

u.setUsername("admin");

u.setPassword("admin");

request.setAttribute("user",u);

%>

<c:out value="${user.username}"></c:out> |  |<c:out value="${user.password}"></c:out>

相当于(User) request.setAttribute("user").getUsername();

<c:set>:

<c:set var="abc"  value="中国,北京" scope="request"></c:set>

<c:out value="${abc}"/>

<c:remove var="abc"/> 移除 之后 中国北京将不再显示

<c:catch>:

<c:catch var="err">

<%int i=3/0; %>

</c:catch>

<c:out value="${err.message}"></c:out>

<c:if test="${2<30?true:false}">ok</c:if>

<c:if>:

<%

request.setAttribute("a","hello");

request.setAttribute("age","22"); %>

判断字符串:

<c:if test="${a=='hello'}">

hello

</c:if>

判断数值

<c:if test="${age>12  and age<30 or age==22}">

年龄大于12 小于30 ${age }

</c:if> <%

ArrayList<User> al=new ArrayList<User>();

User u1=new User();

u1.setUsername("陈超");

u1.setPassword("tiger");

User u2=new User();

u2.setUsername("system");

u2.setPassword("manager");

al.add(u1);  al.add(u2);

request.setAttribute("alluser",al);

%>

<c:forEach items="${alluser}" var="u">

${u.username}

${u.password} <br/>

</c:forEach>

第一种迭代  

<c:forEach var="i" begin="1" end="10">${i}  </c:forEach>

<br/>

第二种迭代

<c:forEach var="i" begin="1" end="10" step="3">${i}  </c:forEach><br />

用于分隔字符:<c:forTokens items="11;33;44;52;" delims=";" var="temp">${temp}</c:forTokens>

什么时候用$符,什么时候不用$

如果是从某个域对象中取出值,取的是一个变量就要用$ ,取的是一个固定的值就不要$

第一种:Window.open(); 这种方式比较慢

第二种:window.location.href=”/web应用名/goManager?pageNow=”+pageNow

<c:if test="${pageNow>1}">前一页:<a href=”/web应用名/goManager?pageNow=${pageNow-1}”></c:if>

当前页:<c:forEach><a href="/web应用名/gotoManage?pageNow=${i}">[${i }]</a></c:forEach>

<c:if test="${pageNow<pageCount}">后一页:<a href=”/web应用名/goManager?pageNow=${pageNow+1}”>

</c:if>

当前页${pageNow } /总页数 ${pageCount } 跳转到<input type="button" id="pageNow" name="pageNow" value="跳"/>

<%

Map map=new HashMap();

//map.put("aa","admin");

//  map.put("bb","scott");

User u1=new User();

u1.setUsername("xiaoming");

u1.setPassword("xiaoming");

User u2=new User();

u2.setUsername("xiaoming");

u2.setPassword("xiaoming");

map.put("u1",u1);

map.put("u2",u2);

request.setAttribute("person",map);

%>

<c:forEach items="${person}" var="per">

key:${per.key }值 name: ${per.value.username }值 password:${per.value.password }<br/>

</c:forEach>

<%

Set set=new HashSet();

User u3=new User();

u3.setUsername("scott");

u3.setPassword("tiger");

set.add(u3);

request.setAttribute("setuser" ,set);

%>

<c:forEach items="${setuser}" var="myusers">

值 name: ${myusers.username }值 password:${myusers.password }<br/>

<c:if test="${!empty setuser}">有人</c:if></c:forEach>

重定向:<c:redirect url="http://www.hao123.cn"/>

import标签:

<c:import url="a.jsp">

<c:param name="name" value="admin"/>

</c:import>

Strtus标签:

<html:base ref="http://www.baidu.com"/><a href="#">goto</a>

如果没有给超链接设置则默认跳到百度(如上)

<html:image src="data:images/chadu.png"></html:image>这是一个图片按钮

<html:img src="data:images/chadu.png"/>这是真真正正的一i张图片

bean标签: 用于输出信息

<%

User u1=new User();

u1.setUsername("admin");

u1.setPassword("admin");

request.setAttribute("user",u1);

%>

<bean:write name="user" property="username"></bean:write>

另外还有两种创建bean的方法,但是用的不多

<bean:define id=""/></bean:define>

<jsp:useBean id="u2" class="com.chao98.forms.User"></jsp:useBean>

<jsp:setProperty name="u2" property="username" value="chenchao"/>

Logic 标签:

logic标签使用

<%

User u1=new User();

u1.setUsername("admin");

u1.setPassword("aa");

User u2=new User();

u2.setUsername("tiger");

u2.setPassword("ac");

User u3=new User();

u3.setUsername("scott");

u3.setPassword("ab");

ArrayList<User> al=new ArrayList<User>();

al.add(u1);

al.add(u2);

al.add(u3);

request.setAttribute("users",al);

%>

<logic:iterate id="user" name="users">

<bean:write name="user" property="username"/>

<bean:write name="user" property="password"/><br/>

</logic:iterate>

<logic:empty name="ee">

属性不存在

</logic:empty>

<logic:notEmpty name="users">

users属性存在

</logic:notEmpty>

<logic:iterate id="myusers" name="users">

<logic:greaterThan value="20" property="age" name="myusers">

年龄大于二十

</logic:greaterThan>

</logic:iterate>

标签的选择: 通常会选择el表达式$

op    Struts 第23讲: 开发struts 的用户管理系统

Create  table users (

Id  int  primary key,

Name  varchar(20) not null,

Pwd varchar(30) not null,

Email varchar(30) not null,

Tel varchar(30) not null,

Grade int default 1 not null

)

如果中文不能加入的话 show variables like ‘%char%’;

Set character_set_client=gbk

注销退出登录

request.getSession().invalidate(); //会把所有的session都删除

return mapping.findForward("logout");

动态表单(dynimic form):  当我们表单个数和类型不确定的情况下,我们就可以使用动动态表单来解决
动态表单和普通表单的区别:

1普通表单actionForm 是首先你需要定义这样一个类,然后配置到struts-config中,

2,动态表单完全依赖反射机制创建,所以不要去定义表单类,直接在struts-config.xml中配置即可

<form-bean name=”userForm”

type=”org.apache.struts.action.DynaActionForm”>

<form-property name=”username” type=”java.lang.String/>

</form-bean>

文件的上传与下载

读取文件(inputStream) 写文件(outputStream);

案例项目:

1:

<form enctype="multipart/form-data" action="${pageContext.request.contextPath}/register.do" method="post">

name:<input type="text" name="username"/><br/>

photo:<input type="file"  name="myphoto"/><br/>

<input type="submit" value="regist" />

</form>

2:

public class UserForm extends ActionForm {

private String username;

private FormFile myphoto;

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public FormFile getMyphoto() {

return myphoto;

}

public void setMyphoto(FormFile myphoto) {

this.myphoto = myphoto;

}

3:

public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response) {

UserForm userForm=(UserForm)form;

String username=userForm.getUsername();//取出用户名字

FormFile formFile=userForm.getMyphoto();

// 通过FormFile 我们可以获取关于上次文件的各种信息

String fileName=formFile.getFileName();

int fileSize=formFile.getFileSize();

System.out.println("文件名称:"+fileName);

System.out.println("文件大小:"+fileSize);

InputStream is=null;

OutputStream os=null;

try {//取出输入流

is=formFile.getInputStream();

//得到输出流--文件

// 1 得到file文件夹上传到tomcat服务器后的绝对路径

String  keepFilePath=this.getServlet().getServletContext().getRealPath("file");

System.out.println(keepFilePath);//打印路径

os=new FileOutputStream(keepFilePath+"\\"+fileName);//读取文件并写出到服务器file

int len=0;//缓存

byte []bytes=new byte[1024];

//循环处理

while((len=is.read(bytes))>0){

os.write(bytes,0,len);//读一点写一点

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}finally{

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return null;

}

4: 在webroot下建立一个file文件夹

完善struts文件上传(上面这种如果上传文件名相同的文件的话就会被覆盖

首先了解uuid 的简单使用方法:

String uuids=(java.util.UUID.randomUUID()).toString();

面试题subString(int beginindex,int endindex);是如何截取的 : 获取字符串的一个子串,从beginindex包扩beginindex  取到endindex ,但是不包括endindex 如

String subString="helloworld!";

System.out.println(subString.substring(0,5));

//打出hello beginindex是从0开始的

优化后的代码为

public class RegisterAction extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response) {

UserForm userForm=(UserForm)form;

String username=userForm.getUsername();//取出用户名字

FormFile formFile=userForm.getMyphoto();

// 通过FormFile 我们可以获取关于上次文件的各种信息

String fileName=formFile.getFileName();

String newFileName="";

int beginIndex=fileName.lastIndexOf(".");

String uuid=(java.util.UUID.randomUUID()).toString();

newFileName=uuid+fileName.substring(beginIndex,  fileName.length());

int fileSize=formFile.getFileSize();

System.out.println("uuid:"+uuid);

System.out.println("文件名称:"+fileName);

System.out.println("新文件名称:"+newFileName);

System.out.println("文件大小:"+fileSize);

InputStream is=null;

OutputStream os=null;

try {//取出输入流

is=formFile.getInputStream();

//得到输出流--文件

// 1 得到file文件夹上传到tomcat服务器后的绝对路径

String  keepFilePath=this.getServlet().getServletContext().getRealPath("file");

System.out.println(keepFilePath);//打印路径

os=new FileOutputStream(keepFilePath+"\\"+newFileName);//读取文件并写出到服务器file

int len=0;//缓存

byte []bytes=new byte[1024];

//循环处理

while((len=is.read(bytes))>0){

os.write(bytes,0,len);//读一点写一点

       return mapping.findForward("loginok");

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}finally{

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return mapping.findForward("loginerr");

}

}

注意事项:如果文件名是中文怎么办?

做一个过滤器

    arg0.setCharacterEncoding("UTF-8");

arg1.setCharacterEncoding("UTF-8");

arg2.doFilter(arg0, arg1);

案例: 保存到数据库中

Create database userdb2;

Use userdb2;

Create table t_users

(username varchar(30) unique not null,

myphoto varchar(128) not null,##保存新的文件名

myphoto2 varchar(128) not null ##保存旧的文件名

);

Q:1272307737

文件下载

如果下载的文件时中文名那么我们需要在action中对其进行处理

String filterFilkename=java.net.URLEncoder.encode(u.getMyphoto(),"GB2312");

思考: 如何控制文件的大小?

如何控制文件上传类型?

可以从D:\Program Files\Tomcat 6.0\conf目录下的 web.xml中可以查看文件的类型

如何防止用户名重复?

struts笔记的更多相关文章

  1. Struts 笔记 内部资料 请勿转载 谢谢合作

    Struts 概述 随着MVC 模式的广泛使用,催生了MVC 框架的产生.在所有的MVC 框架中,出现最早,应用最广的就是Struts 框架. Struts 的起源 Struts 是Apache 软件 ...

  2. Struts笔记5

    文件下载 1.写action类 package com.gyf.web.action; import java.io.File; import java.io.FileInputStream; imp ...

  3. Struts笔记4

    Struts2-拦截器-单个拦截器 自定义拦截器 1.创建一个继承AbstractInterceptor的类 package com.gyf.web.interceptor; import com.o ...

  4. Struts笔记3

    struts标签 form表单标签 Action:请求地址.直接写动作名称,不用写contextPath <s:form action="/user/register.action&q ...

  5. Struts笔记2

    Struts2-配置文件result元素 作用:为动作指定结果视图 name属性:逻辑视图的名称,对应着动作方法的返回值.默认值是success type属性:结果类型,指的就是用什么方式转到定义的页 ...

  6. struts笔记1

    框架:所谓框架,就是把一些繁琐的重复性代码封装起来,使程序员在编码中把更多的精力放到业务需求的分析和理解上面 SHH:strust spring hibernate; SSM:springmvc sp ...

  7. Struts笔记二:栈值的内存区域及标签和拦截器

    值栈和ognl表达式 1.只要是一个MVC框架,必须解决数据的存和取的问题 2.struts2利用值栈来存数据,所以值栈是一个存储数据的内存结构 1.  ValueStack是一个接口,在struts ...

  8. Struts笔记一

    Struts 概念: 是一个MVC框架: Servlet的缺点 1.在web.xml中文件中需要配置很多行代码,维护起来很不方便呢,不利于团队合作. 2.一个servlet的入口只有一个doPost或 ...

  9. Struts中的OGNL和EL表达式笔记

    Struts中的OGNL和EL表达式笔记 OGNL(Object-Graph Navigation Language),可以方便的操作对象属性的表达式语言. 1.#符号的用途 一般有三种方式: 1.1 ...

随机推荐

  1. java高新技术

    一.静态导入: import static语句导入一个类中的某个静态方法或所有方法: 例子: 1.import static java.lang.Math.max; 只是导入了Math类中的max方法 ...

  2. SVN的管理方式和git的管理方式

    SVN是集中式的管理方式.大致流程如下: 1.从服务器上将整个项目代码检出到本地电脑硬盘中(一般来说,是从主分支上下载的代码).2.然后在svn服务器中建立新的开发分支,将硬盘中的代码提交到该开发分支 ...

  3. Delphi实例分析:远程传输数据和文件

    在Windows操作系统的平台上,WinSock是首选的网络编程接口,用于在网络上传输数据和交换信息,它构成了Windows操作系统进行网络编程的基础.对于编写网络应用程序来说,WinSock是一门非 ...

  4. Delphi XE5 Android 运行黑屏卡死的解决方法

    1. 确保正确安装Android SDK: 开始菜单 > 所有程序 > Embarcadero RAD Studio XE5 > > Android Tools > 打开 ...

  5. UIView 的旋转和缩放

    原文地址:http://www.cnblogs.com/gaoxiao228/archive/2012/05/04/2483577.html label.transform = CGAffineTra ...

  6. 【工具类】怎么进入阿里云docker仓库

    进入阿里云docker仓库. 1.进入官网 2.选择 开发者  --->点击 阿里开源项目 3.选择  服务 点击代码托管.仓库 下的 容器镜像服务 4.点击进入 管理控制台 5.点击镜像搜索, ...

  7. git 两个中心仓库上的分支 merge

    首先在一个中心仓库里面添加另外一个仓库的所有分支. 命令: git remote add Cangku2 https://github.com/abc/abc.git git fetch 这之后在使用 ...

  8. Java并发编程的艺术(七)——Executors

    Executors框架简介 Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动.执行和关闭,可以简化并发 ...

  9. 【转】从源码来分析ListView

    原文:http://yanmingming.sinaapp.com/?p=1251 原文其实不叫这个名字,本文对于原文有一定的修改,觉得这个名字比较适合本篇. 一.ListView 的工作原理 Ada ...

  10. ListView取消和自定义分割线的方法

    一.不显示分割线 XML android:footerDividersEnabled="false"即可. JAVA mListView.setDivider(null); 二.改 ...