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. 委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别

    在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式.委托与事件的方式实现过观察者模式.本篇体验使用Action实现此模式,并从中体验委托与事件 ...

  2. Android:intent的基础

    只有一个活动的应用也太简单了吧?没错,你的追求应该更高一点.不管你想创建多少 个活动,方法都和上一节中介绍的是一样的.唯一的问题在于,你在启动器中点击应用的图 标只会进入到该应用的主活动,那么怎样才能 ...

  3. IIS7.5标识介绍

    应用程序池的标识是运行应用程序池的工作进程所使用的服务帐户名称.默认情况下,应用程序池以 Network Service 用户帐户运行,该帐户拥有低级别的用户权限.您可以将应用程序池配置为以 Wind ...

  4. JQuery的父、子、兄弟节点查找,节点的子节点循环

    jQuery.parent(expr)           //找父元素 jQuery.parents(expr)          //找到所有祖先元素,不限于父元素 jQuery.children ...

  5. ASP.NET MVC:4 Ways To Prevent Duplicate Form Submission(转载)

    原文地址:http://technoesis.net/prevent-double-form-submission/. Double form submission in a multi-user w ...

  6. java转义符和正则表达式转义符

    举例来说,连续相同的3位数字的正则表达式的标准语法是: ([\d])\1{2} 但是如果在java代码中这么写,就会出现语法错误,如下: String regEx = "([\d])\1{2 ...

  7. spring mvc 接受前台json @RequestBody json 属性 空 使用 JsonProperty spring mvc 获取json转乘bean

    请给json序列序列化成的javabean 属性加上   @JsonProperty(value = "real_name")   否则 springmvc 可能接受不到数据 ja ...

  8. Sutherland-Hodgeman多边形裁剪

    原文地址:http://course.cug.edu.cn/cugFirst/computer_graphics/class/course/3-3-1-a.htm

  9. 第一章 Typescript 介绍

    Typescript 介绍 一.Typescript 简介 Typescript 是微软开发的 Javascript 的超集,Typescript 兼容 Javascript,可以载入 Javascr ...

  10. VS2008 打开 VS2010解决方案及项目(转)

    第一步,修改解决方案后缀为sln的文件 Microsoft Visual Studio Solution File, Format Version 11.00  # Visual Studio 201 ...