Struts視頻筆記:html
Struts是一個開源的web框架,框架提升了程序的規範的同時也約束了程序員的自由java
爲何會有struts:程序員
由於咱們隊mvc理解的不一樣,可能形成不一樣公司寫程序的時候,規範不統一,這樣不利於程序的維護和擴展,因此咱們有必要用一個統一的規範來開發項目(struts)web
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響應給瀏覽器apache
,登陸小項目過程步驟: 新建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默認是sessiontomcat
配置過濾器
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="images/chadu.png"></html:image>這是一個圖片按鈕
<html:img src="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中能夠查看文件的類型
如何防止用戶名重複?