Struts2處理(jQuery)Ajax請求

1. Ajax

    Ajax(Asynchronous JavaScript and XML,異步JavaScript和XML)時一種創建交互式網頁應用的網頁開發技術,它并不是一項新的技術,其產生的目的是用于實現頁面的局部刷新。通過Ajax技術可以使之前的應用程序在每次提交時不用進行頁面的整體刷新,從而提升操作的性能。

2. jQuery

    jQuery是一個JavaScript函數庫,極大的簡化了JavaScript編程,很容易學習。jQuery是目前最流行的開源js框架,并且提供了大量的擴展。

3. Struts2框架

    了解一下MVC模式,MVC 模式代表 Model-View-Controller(模型-視圖-控制器) 模式。MVC是一種軟件設計典范。這種模式用于應用程序的分層開發。

    Model(模型) - 模型代表一個存取數據的對象或 JAVA POJO。它也可以帶有邏輯,在數據變化時更新控制器。

    View(視圖) - 視圖代表模型包含的數據的可視化。

    Controller(控制器) - 控制器作用于模型和視圖上。它控制數據流向模型對象,并在數據變化時更新視圖。它使視圖與模型分離開。

    Apache Struts是一個免費的開源MVC框架,用于創建優雅的現代Java Web應用程序。它支持約定勝于配置(約定大于配置,簡單來說就是簡化我們的開發的,使代碼更加簡潔,并且有很好的可重用性和可擴展性),可以使用插件體系結構進行擴展,并且附帶了支持REST,AJAX和JSON的插件。Struts2是一個基于MVC設計模式的Web應用框架,它本質上相當于一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與視圖的數據交互。Struts2是在Struts1和WebWork的技術基礎上進行全新開發,以WebWork為核心,采用攔截器的機制來處理用戶的請求,這樣的設計也使得業務邏輯控制器能夠與ServletAPI完全脫離開(解耦合),方便了我們進行Java Web開發。

4. Struts2處理(jQuery)Ajax請求((發送key/value數據)/發送json數據)

     開發環境:eclipse+Struts2+jsp+jQuery+Ajax+Jackson+tomcat

4.1 Struts2處理(jQuery)Ajax請求(不發送數據,返回普通文本)

(1) 搭建環境

     在eclipse中新建Java web項目(會自動導入JRE System Library包),比如我把項目名字寫為MyStrutsAjaxDemo,并將項目部署到tomcat服務器上,下面是eclipse中項目的目錄結構:

    

項目結構很簡單。這里我們看一下lib目錄下的jar包,因為我們使用了Struts2框架進行開發,所以必須導入Struts2開發包。Struts2有很多開發包,這里我們導入我們想用的就行了。如上所示。Struts2開發包:asm三個jar包,commons三個,freemarker的jar包,ongl的jar包,strts2-core和核心jar包,Struts2內置的json插件jar包struts2-json(不可以忘記導入哈!),用來處理json數據。javassist的jar包。還有一個xwork-core核心包。日志jar包:log4j(2個)。Jackson開發包:3個。(不懂的話可以看我上篇博客)。好了,jar包就說完了。下面進行開發。

(2)編寫jsp文件

   客戶端不發送數據,服務器端返回一個普通文本。這里我們主要熟悉一下流程,看一下效果,雖然說不發送數據沒多大意義。

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%-- <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> --%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<title>I LOVE YOU</title>
<link rel="stylesheet" type="text/css" href="">
<script type="text/javascript" src="myindex.js"></script>
<script type="text/javascript" src="jquery-3.2.1.min.js"></script>


</head>
<body>

<button id="mybutton1" value="struts2處理(jQuery)Ajax請求" onclick="fun1()" >(jquery)ajax請求(不發送數據)</button>
<spand id="show1" />

<br/>
<hr/>



</body>

index.jsp很簡單,就定義了一個按鈕。調用對應函數。函數名要和js中所寫的對應一致。注意要引入自己編寫的js文件和jQuery的js文件(注意路徑)。

 

(3)編寫myindex.js文件

 

/**
 * 
 */
//(jQuery)Ajax請求不發送數據
function fun1(){
    
    $.ajax({
        
        type:"POST",
        url:"UserAction1",
        data:"",
        success:function(data){
            
            $("#show1").html(data);
            
        }            
    });
        
}

 

定義了fun1()函數,注意jQuery的元素選擇器的id和html定義<span>標簽的id保持一致,主要是為了顯示內容。么啥好說的,就是發送的使key/value數據。

 

(4)新建User實體類

//
package com.entity;

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;
    }

    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }

}

很簡單,有2個屬性(username和password)。注意Ajax傳遞的參數名稱要和User類的屬性保持一致(面向對象。java對象對屬性的封裝)。

(5)編寫Action類

   Action類用來處理請求,響應客戶端。

 

package com.action;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

//不接受參數,打印簡單文本
public class UserAction1 extends ActionSupport {

    // 獲取response對象
    private HttpServletResponse response = ServletActionContext.getResponse();

    // 只是打印一個字符串文本內容(也可以給客戶端返回json數據,處理一下就行了。這里返回文本,主要看一下不同的效果)
    public String myexcute1() {

        response.setContentType("text/html;charset=utf-8");
        String str = "我想你了!哈哈哈!";
        try {
            response.getWriter().print(str);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

 

代碼很簡單,都有注釋。新建一個Action類,繼承了ActionSupport。可以通過ServletActionContext.getResponse()方法獲取到response對象。ServletActionContext(com.opensymphony.webwork.ServletActionContext),該類直接繼承了ActionContext提供直接與Servlet相關對象訪問的功能
ServletActionContext線程安全。這個類主要用于獲取servlet的相關對象。使用response獲取打印輸出流,輸出一個普通文本。說一下ActionSupport類, struts2不要求我們自己設計的action類繼承任何的struts基類或struts接口,但是我們為了方便實現我們自己的action,大多數情況下都會繼承ActionSupport類,并重寫此類里的public String execute() throws Exception方法。因為此類中實現了很多的實用借口,提供了很多默認方法,這些默認方法包括國際化信息的方法、默認的處理用戶請求的方法等,這樣可以大大的簡化Acion的開發。Struts獲取請求,
怎么知道調用那個Action的方法進行處理呢。下面我們配置Struts2的主配置文件struts.xml。

(6)配置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"></constant>    
   <constant name="struts.i18n.encoding" value="UTF-8"></constant>
   
    <package name="default" namespace="/" extends="struts-default,json-default">

        <action name="UserAction1" class="com.action.UserAction1" method="myexcute1">
            <result >
                
            </result>
        </action>  
                  
    </package>
    
</struts>

 

子標簽constant:定義一些常量。struts.devMode啟動開發者模式。struts.i18n.encoding設置請求的編碼。這些常量的定義位于struts2核心開發包的default.proprties資源文件中。子標簽pakage:name="default"包名,可以隨便取,但是不能重復。一個<pakage>可以配置多個<action>。namespace:命名空間。Struts2請求的訪問路徑:http://ip地址:端口號/工程名/命名空間/Action的名稱。extends代表繼承的包,Struts2的默認包“default”是繼承于"Struts-dafault"包的,struts-default包是在struts-default.xml中定義,struts-default.xml也是Struts2默認配置文件,所以Struts2每次都會自動加載 struts-default.xml文件。struts-defalut.xml位于struts2-core核心包下面。注意到還繼承了一個json-default包,json-default是繼承struts-default,json這個result type(返回類型)是在json-default (struts2-json-plugin-2.1.8.1.jar\struts-plugin.xml)里面定義的。<action>標簽。用來調用某個Action類對應的方法進行處理客戶端請求的。我們先來看配置的第一個<action>。name設置action的請求路徑。比如我們設置為name="UserAction1",注意Ajax提交請求的url必須和此時設置的action的name保持一致,不然找不到。class就是Action類的全路徑。method就是Action類中的方法名稱。上面我們的方法名為myexcute1,所以設置為method="myexcute1",不要帶括號以及參數,只書寫方法名稱就行了。<result>表示返回的結果集,有2個屬性,一個是name:對應Action返回邏輯視圖名稱,默認為success。一個是type:返回結果類型,默認為dispatcher。因為我們這個方法只返回普通字符串,所以<result>里面就不用寫了。空空如也。

(7)配置web.xml文件

   web.xml文件還是很重要的,它是tomcat的配置文件,當我們啟動一個web項目容器的時候,它首先會加載web.xml文件。

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>StrutsProject</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  
  <!--配置struts2的核心過濾器  -->
  
       <filter>
           <!-- 核心過濾器名稱 -->
         <filter-name>struts2</filter-name>
         <!-- 費核心過濾器全類路徑(包.類) -->
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
     
     <filter-mapping>
         <filter-name>struts2</filter-name>
         <!-- 攔截路徑 -->
         <url-pattern>/*</url-pattern>
     </filter-mapping>
 
</web-app>

 

配置很簡單,就配置了一個Struts2的核心過濾器StrutsPrapareAndExcuteFilter。FilterDispatcher是早期struts2的過濾器,后期的都用StrutsPrepareAndExecuteFilter了。StrutsPrepareAndExecuteFilter名字可知,prepare與execute,前者表示準備,可以說是指filter中的init方法,即配制的導入;后者表示進行過濾,指doFilter方法,即將request請求,轉發給對應的 action去處理。在使用struts的時候要在web.xml中配置一個過濾器,來攔截用戶發起的請求,并進行一些預處理,根據配置文件把請求分配給對應的action并將請求中的參數與action中的字段進行對應賦值。

(8)運行程序

   啟動tomcat,在瀏覽器地址欄輸入url,點擊按鈕,查看效果。完美運行。

 

4.2 Struts2處理(jQuery)Ajax請求(發送key/value數據,返回json數據)

(1)導入Jackson包

   上面導包已經導好了,這里不多說。jackson所需3個jar包(注意要導全)。

(2)編寫jsp文件

   同理,寫一個按鈕和顯示內容的span標簽。

<button id="mybutton2" value="struts2處理(jQuery)Ajax請求" onclick="fun2()" >發送數據格式為key/value的(jquery)ajax請求</button>
<spand id="show2" /><br/>

 

(3)編寫js文件

   

//使用jquery提交key/value數據(ajax請求)
function fun2(){
    
    $.ajax({
        
        type:"POST",
        url:"UserAction2",
        data:"username=wly&password=1314520",
        success:function(data){
            var value=JSON.parse(data);  //json字符串轉化為js對象
            $("#show2").html(value.username+" "+value.password);
            
        }            
    });
        
}

 

提交路徑要和strutst.xml的action的name保持一致。返回的json字符串要通過JSON.parse(data)方法解析為js對象(準確來說,是js可以操作的json對象)。

 

(4)編寫User實體類

   和上面User類一樣,有2個屬性username和password,提供setter,getter和toSring()方法。

 

(5)編寫Action類

   

package com.action;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.pojo.User;

//接受key/value參數,輸出json數據
public class UserAction2 extends ActionSupport implements ModelDriven<User> {

    // 注意一定要new一個實體對象
    private User user = new User();

    // 獲取response對象
    private HttpServletResponse response = ServletActionContext.getResponse();

    // 返回的結果集,必須提供getter和setter方法
    String result = null;

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    // 返回json數據(利用jackson完成java對象與json的轉化)
    public String myexcute2() {

        response.setContentType("application/json;charset=UTF-8");
        System.out.println(user);
        ObjectMapper json = new ObjectMapper(); // 新建json對象

        try {
            result = json.writeValueAsString(user); // user對象轉化為json字符串
            System.out.println(result);
        } catch (JsonGenerationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return SUCCESS; // 返回SUCCESS標志,主配置文件根據result標簽的name來跳轉頁面或者輸出內容。
                        // Struts2的常量(SUCCESS、NONE、ERROR、INPUT、LOGIN)
    }

    // 實現模型驅動ModelDriven接口的抽象方法
    @Override
    public User getModel() {
        // TODO Auto-generated method stub
        return user;
    }
}

 

這里所以說一下。Struts2接受前臺傳來的數據的方法(2種)。第一種:屬性驅動。(1)使用變量的方式,把字段寫在Action類中,并提供setter和getter方法。(2)使用對象的方式。把user對象當作屬性封裝到Action中,并提供setter和gettter方法。但是要注意前臺傳值。要使用變量.屬性的方式才可以獲得到。第二種:模型驅動。也就是本文所使用到的辦法。Action類通過實現com.opensymphony.xwork2.ModelDriven<T>接口,并實現接口中的抽象方法 public abstract T getModel(),不需要提供getter和setter方法。但是聲名對象的時候一定要實例化。前臺傳遞的參數名稱和實體類中的屬性名稱保持一致即可。這里我們看上面public String myexcute2()個方法,這個方法其實就是獲取到user對象,然后利用jackson將user對象轉化為json字符串輸出。最后返回一個SUCCESS常量,struts2會根據struts.xml配置文件中的<result>的name和type進行頁面的跳轉或者輸出內容。注意這里向客戶端輸出一個json字符串的結果集,我們用result變量保存起來,并且一定要提供result的setter和getter方法。方法很簡單。

 

(6)配置struts.xml文件

   

<action name="UserAction2" class="com.action.UserAction2" method="myexcute2">         
            <!-- 返回json類型數據 -->
                    
            <result name="success" type="json">               
                <param name="root">result</param>
            </result>
 </action> 

 

配置很簡單,把這個<action>放入上面那個<package>標簽中就可以了(也可以重新寫一個<package>),這里為了方便。注意result的name為success,剛才我們返回的是SUCCESS(代表action執行成功),這是一個struts2的常量,它的值為public static final String SUCCESS = "success"。struts2其他幾個常量

NONE(action執行成功,不跳轉頁面)、ERROR(action執行失敗)、INPUT(action為了執行成功需要多次輸入)、LOGIN(action不能執行,因為用戶沒有登錄)。<result>標簽的type="json",表示返回的是json數據格式。這里加上了一個param參數。<param name="root">result</param>中,result就是剛才我們action返回的結果集(有getter和setter方法)。name="root"表示從result結果集的根部進行遍歷。所以就可以正常返回并解析了。

 

(7)配置web.xml文件

   web.xml的配置和上面一樣,就配置一個struts2核心過濾器就ok了。

(8)運行程序

   啟動tomcat容器,輸入地址,完美運行。

    

 

4.3 Struts2處理(jQuery)Ajax請求(發送json數據,返回json數據)

(1)編寫jsp文件

   導入jar包就不說了,就是上面的。

<button id="mybutton3" value="struts2處理(jQuery)Ajax請求" onclick="fun3()" >發送數據格式為json的(jquery)ajax請求</button>
<spand id="show3" /><br/>

   定義了一個按鈕和span標簽,很簡單。

(2)編寫js文件

 

//使用jquery提交json數據(ajax請求)


function fun3(){
    
    var user={
            "username":"wly",
            "password":"1314520"    
    };    
$.ajax({
        
        type:"POST",
        url:"UserAction3",
        contentType:"application/json;charset=UTF-8",
        data:JSON.stringify(user),    //將js對象轉化為json字符串
        dataType:"json",
        success:function(data){
            console.log(data);
            var value=JSON.parse(data);   //將json字符串解析為js對象
            $("#show3").html(value.username+" "+value.password);            
        }            
    });
}

 

   上面沒啥好說的,就是一些熟悉的內容,不懂的話可以看我前2篇博客。console.log(data)是在web瀏覽器的控制臺進行打印(谷歌瀏覽器找開發者工具)。

 

(3)新建User類

   不多說,和上面一樣。其實我們就只寫了一個User類。

(4)新建Action類

   第一步:編寫json工具類

   

package com.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pojo.User;

public class JsonUtil {

    public static User accept(HttpServletRequest request) throws UnsupportedEncodingException, IOException {

        // 讀取請求內容
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));

        String line = null;
        StringBuilder sb = new StringBuilder();

        while ((line = br.readLine()) != null) {
            sb.append(line);
        }

        // 將json字符串轉化為java對象
        ObjectMapper json = new ObjectMapper();
        User user = json.readValue(sb.toString(), User.class);
        return user;
    }

}

 

   這個類沒啥好說的,就是通過BufferedReader類來讀取請求內容,并把請求內容按行添加到StringBuilder(字符串變量,線程不安全,單線程下效率比較高)對象中,然后再利用Jackson的核心操作類ObjectMapper類把json字符串轉化為user對象返回。

  第二步:編寫Action類

package com.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.opensymphony.xwork2.ActionSupport;
import com.pojo.User;
import com.util.JsonUtil;

//接受json數據,打印json數據
public class UserAction3 extends ActionSupport {

    // 獲取response對象
    private HttpServletResponse response = ServletActionContext.getResponse();

    private HttpServletRequest request = ServletActionContext.getRequest();

    // 返回的結果集,必須提供getter和setter方法
    String result = null;

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    // 返回json數據(利用jackson完成java對象與json的轉化)
    public String myexcute3() {

        response.setContentType("application/json;charset=UTF-8");
        try {
            User user = JsonUtil.accept(request);
            System.out.println(user);
            ObjectMapper json = new ObjectMapper(); // 新建json對象
            result = json.writeValueAsString(user); // user對象轉化為json字符串
            System.out.println(result);
        } catch (JsonGenerationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return SUCCESS; // 返回SUCCESS標志,主配置文件根據result標簽的name來跳轉頁面或者輸出內容。
                        // Struts2的常量(SUCCESS、NONE、ERROR、INPUT、LOGIN)
    }

}

   

這里使用ServletActionContext類獲取了response和requset對象,并且結果集result提供相應的getter和setter方法。最后返回一個json字符串。

 

(5)配置struts.xml

   

<action name="UserAction3" class="com.action.UserAction3" method="myexcute3">         
            <!-- 返回json類型數據 -->
                  
            <result name="success" type="json">               
                <param name="root">result</param>
            </result>
</action> 

同理,配置這個Action類。action請求名稱設置為UserAction3(要和ajax提交的路徑一致),全類路徑要書寫正確。<result>表示要返回的內容(或頁面)。相關配置上面已經解釋,這里不多說。

 

(6)配置web.xml

   和上面一樣。配置一個struts2核心過濾器。

(7)運行程序

   

 

5. 總結

(1)從本次開發看出struts的優缺點。優點:支持插件(比如json插件),ajax支持,通過配置文件,就可以掌握整個系統各個部分之間的關系。實現了MVC模式,層次結構清晰。減少配置(有默認值)。

(2)struts的缺點(通過本次開發):缺點:對servlet依賴比較強(我們用到了request和response),Action中取得從jsp中傳過來的參數時還是有點麻煩。

(3)其實本質上我們還是通過Jackson框架進行json與java對象的相互轉化,只不過要依賴于struts-json插件。其實我們只是用符合struts2框架的規范,編寫了一些Action類,來響應客戶端的請求。其實和之前的編寫servlet效果類似。

(4)Jackson類庫其實還蠻好用的,不信你試試!

(5)如果有什么錯誤歡迎各位大佬指出,在下一定洗耳恭聽!哈哈!

 

   本篇博客源碼鏈接:https://pan.baidu.com/s/1zUvZxO_eVahocHcjMsyOPA             提取碼:nn3g 

 

posted @ 2019-10-31 19:08  我想和你拍照片  閱讀(...)  評論(... 編輯 收藏
11选5走势图