JavaWeb学习笔记(三)

目录

1、Filter过滤器

1.1、什么是Filter过滤器

1.2、Filter使用步骤及示例

1.3、Filter生命周期

1.4、FilterConfig类

1.5、FilterChain过滤器链

1.6、Filter的拦截路径

1.6.1、精确匹配

1.6.2、目录匹配

1.6.3、后缀名匹配

2、ThreadLocal

3、JSON

3.1、什么是JSON

3.2、JSON在JavaScript中的使用

3.2.1、JSON的定义

3.2.2、JSON的访问

3.2.3、json的两个常用方法

3.3、JSON在java中的使用

3.3.0、准备工作

3.3.1、JavaBean 和 json 的互转

3.3.2、List 和 json 互转

3.3.3、map 和 json 的互转

4、AJAX请求

4.1、什么是AJAX请求

4.2、原生AJAX请求的示例

4.3、jQuery 中的 ajax 请求

4.3.1、$ajax 方法 

4.3.2、$.get 方法和$.post 方法

4.3.3、$getJSON 方法

4.3.4、表单序列化 serialize()

4.3.5、完整代码

5、i18n国际化(了解)

5.1、什么是i18n国际化

5.2、i18n国际化相关要素

 5.3、i18n国际化properties测试

5.4、通过请求头国际化页面

5.5、通过JSTL标签库实现国际化


1、Filter过滤器

1.1、什么是Filter过滤器

1、Filter 过滤器它是 JavaWeb 的三大组件之一。三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器 
2、Filter 过滤器它是 JavaEE 的规范。也就是接口 
3、Filter 过滤器它的作用是:拦截请求,过滤响应。

拦截请求常见的应用场景有: 1、权限检查 2、日记操作 3、事务管理 ……等等

1.2、Filter使用步骤及示例

Filter 过滤器的使用步骤: 
1、编写一个类去实现 Filter 接口 
2、实现过滤方法 doFilter() 
3、到 web.xml 中去配置 Filter 的拦截路径

注意:实现的Filter接口是javax.servlet下的

要求:在你的 web 工程下,有一个 admin 目录。这个 admin 目录下的所有资源(html 页面、jpg 图片、jsp 文件、等等)都必 须是用户登录之后才允许访问。

思考:根据之前我们学过内容。我们知道,用户登录之后都会把用户登录的信息保存到 Session 域中。所以要检查用户是否 登录,可以判断 Session 中否包含有用户登录的信息即可!!!

AdminFilter.java

package filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.logging.LogRecord;

/**
 * @Author zhang
 * @Date 2022/1/7 16:45
 * @Version 1.0
 */
public class AdminFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /**
     * 专门用于拦截请求,可以做权限检查
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession();
        Object user = session.getAttribute("user");
        if (user == null) {
            servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest, servletResponse);
            return;
        }else{
            //让程序继续往下访问用户的目标资源
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

web.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

    <!--filter标签用于配置一个Filter过滤器-->
    <filter>
        <!--给filter起一个别名-->
        <filter-name>AdminFilter</filter-name>
        <!--配置全类名-->
        <filter-class>filter.AdminFilter</filter-class>
    </filter>
    <!--filter-mapping配置Filter过滤器的拦截路径-->
    <filter-mapping>
        <!--filter-name表示当前的拦截路径给哪个Filter使用-->
        <filter-name>AdminFilter</filter-name>
        <!--
            url-pattern配置拦截路径
                /   表示请求地址为:http://ip.port/工程路径/    映射到IDEA的web目录
                /admin/*    表示请求地址为:http://ip.port/工程路径/admin/*
        -->
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>


</web-app>

login.jsp页面

<%--
  Created by IntelliJ IDEA.
  User: zhang
  Date: 2022/1/7
  Time: 15:47
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    这是登录页面login.jsp
    <form action="http://localhost:8080/14_Filter/loginServlet" method="get">
        用户名:<input type="text" name="username"> <br/>
        密 码:<input type="password" name="password"> <br/>
        <input type="submit">
    </form>
</body>
</html>

LoginServlet.java

package servlet; /**
 * @Author zhang
 * @Date 2022/1/7 20:25
 * @Version 1.0
 */

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "Servlet", value = "/Servlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码
        resp.setContentType("text/html;charset=UTF-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");

        if ("admin".equals(username) && "admin".equals(password)) {
            req.getSession().setAttribute("user", username);
            resp.getWriter().write("登录成功!!");
        } else {
            req.getRequestDispatcher("/login.jsp");
        }
    }
}

1.3、Filter生命周期

Filter 的生命周期包含几个方法 
        1、构造器方法 

        2、init 初始化方法 
    
                    第 1,2 步,在 web 工程启动的时候执行(Filter 已经创建) 

        3、doFilter 过滤方法 
                    第 3 步,每次拦截到请求,就会执行 

        4、destroy 销毁 
                    第 4 步,停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)

1.4、FilterConfig类

FilterConfig 类见名知义,它是 Filter 过滤器的配置文件类。 Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息。 

FilterConfig 类的作用是获取 filter 过滤器的配置内容 
1、获取 Filter 的名称 filter-name 的内容 
2、获取在 web.xml 中配置的 init-param 初始化参数 
3、获取 ServletContext 对象

web.xml中AdminFilter的初始化参数

<!--filter标签用于配置一个Filter过滤器-->
    <filter>
        <!--给filter起一个别名-->
        <filter-name>AdminFilter</filter-name>
        <!--配置全类名-->
        <filter-class>filter.AdminFilter</filter-class>
        <!--配置初始化参数-->
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:13306/test</param-value>
        </init-param>
    </filter>
    <!--filter-mapping配置Filter过滤器的拦截路径-->
    <filter-mapping>
        <!--filter-name表示当前的拦截路径给哪个Filter使用-->
        <filter-name>AdminFilter</filter-name>
        <!--
            url-pattern配置拦截路径
                /   表示请求地址为:http://ip.port/工程路径/    映射到IDEA的web目录
                /admin/*    表示请求地址为:http://ip.port/工程路径/admin/*
        -->
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>

AdminFilter中的init方法内容

@Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init(FilterConfig filterConfig)方法");
        //1、获取 Filter 的名称 filter-name 的内容
        System.out.println("filter-name :" + filterConfig.getFilterName());
        //2、获取在 wen.xml 中配置的 init-param 初始化参数
        System.out.println("初始化参数username的值是:" + filterConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值是:" + filterConfig.getInitParameter("url"));
        //3、获取 ServletContext 对象
        System.out.println("ServletContext的值是:" + filterConfig.getServletContext());
    }

1.5、FilterChain过滤器链

 注:多个Filter执行的顺序是按照web.xml中从上到下的顺序

Filter1:

package filter;

import javax.servlet.*;
import java.io.IOException;

/**
 * @Author zhang
 * @Date 2022/1/9 17:51
 * @Version 1.0
 */
public class Filter1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter1 前置代码");
        System.out.println("Filter1线程:"  + Thread.currentThread().getName());
        System.out.println("Filter1     " + servletRequest.getParameter("username"));
        servletRequest.setAttribute("key1","value1");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("Filter1线程:"  + Thread.currentThread().getName());
        System.out.println("Filter1 后置代码");
    }

    @Override
    public void destroy() {

    }
}

Filter2:

package filter;

import javax.servlet.*;
import javax.xml.transform.Source;
import java.io.IOException;

/**
 * @Author zhang
 * @Date 2022/1/9 17:51
 * @Version 1.0
 */
public class Filter2 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter2 前置代码");
        System.out.println("Filter2线程:"  + Thread.currentThread().getName());
        System.out.println("Filter2     " + servletRequest.getParameter("username"));
        System.out.println("Filter2取出Filter1保存的数据是:" + servletRequest.getAttribute("key1"));
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("Filter2线程:"  + Thread.currentThread().getName());
        System.out.println("Filter2 后置代码");
    }

    @Override
    public void destroy() {

    }
}

target.jsp:

<%--
  Created by IntelliJ IDEA.
  User: zhang
  Date: 2022/1/9
  Time: 17:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        System.out.println("进入了target.jsp页面");
        System.out.println("target.jsp线程:"  + Thread.currentThread().getName());
        System.out.println("target.jsp      " + request.getParameter("username"));
    %>
</body>
</html>

1.6、Filter的拦截路径

1.6.1、精确匹配

<url-pattern>/target.jsp</url-pattern>         表示请求地址为:http://ip:port/工程路径/target.jsp

1.6.2、目录匹配

<url-pattern>/admin/*</url-pattern>        表示请求地址必须为:http://ip:port/工程路径/admin/*

1.6.3、后缀名匹配

<url-pattern>*.html</url-pattern>        表示请求地址必须以.html结尾才会拦截到

注意:

① 后缀名可以自己设定,例如:<url-pattern>*.abc</url-pattern> 

② 后缀名不要以斜杠  /   开头,若以斜杠开头会报错

        java.lang.IllegalArgumentException: 过滤器映射中的<url-pattern> [/*.abc] 无效

③ Filter过滤器值关心请求的地址受否匹配,不关心请求的资源是否存在

2、ThreadLocal

ThreadLocal 的作用,它可以解决多线程的数据安全问题。 

ThreadLocal 它可以给当前线程关联一个数据(可以是普通变量,可以是对象,也可以是数组,集合) 

ThreadLocal 的特点: 
1、ThreadLocal 可以为当前线程关联一个数据。(它可以像 Map 一样存取数据,key 为当前线程) 
2、每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个 ThreadLocal 对象实例。 
3、每个 ThreadLocal 对象实例定义的时候,一般都是 static 类型 
4、ThreadLocal 中保存数据,在线程销毁后。会由 JVM 虚拟自动释放。

ThreadLocalTest.java

package threadlocal;

import java.util.Hashtable;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author zhang
 * @Date 2022/1/9 23:42
 * @Version 1.0
 */
public class ThreadLocalTest {

    public final static Map<String, Object> data = new Hashtable<>();
    public static ThreadLocal<Object> threadLocal = new ThreadLocal<>();
    public static ThreadLocal<Object> threadLocal2 = new ThreadLocal<>();

    private static Random random = new Random();

    public static class Task implements Runnable {
        @Override
        public void run() {

            /*
            //在Run方法中,随机生成一个变量(线程要关联的数据),然后以当前线程名为key保存到map中
            Integer i = random.nextInt(1000);

            //获取当前线程名
            String name = Thread.currentThread().getName();

            System.out.println("线程【" + name + "】生成的随机数是" + i);

            //data.put(name, i);
            threadLocal.set(i);

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            new OrderService().createOrder();

            //在Run方法结束之前,以当前线程名获取出数据并打印,查看是否可以取出操作
            //Object o = data.get(name);
            Object o = threadLocal.get();
            System.out.println("线程【" + name + "】取出关联的数据是" + o);
*/


            //每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个 ThreadLocal 对象实例。
            threadLocal.set("abc");
            threadLocal2.set("bbj");
            System.out.println("threadLocal的值为"  + threadLocal.get());
            System.out.println("threadLocal2的值为" + threadLocal2.get());
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Task()).start();
        }
    }

}

OrderService.java

package threadlocal;

/**
 * @Author zhang
 * @Date 2022/1/10 18:03
 * @Version 1.0
 */
public class OrderService {

    public void createOrder(){
        String name = Thread.currentThread().getName();
        //System.out.println("线程OrderService【" + name + "】中保存的数据是:" + ThreadLocalTest.data.get(name));
        System.out.println("线程OrderService【" + name + "】中保存的数据是:" + ThreadLocalTest.threadLocal.get());
        new OrderDao().saveOrder();
    }

}

OrderDao.java

package threadlocal;

/**
 * @Author zhang
 * @Date 2022/1/10 18:07
 * @Version 1.0
 */
public class OrderDao {

    public void saveOrder(){
        String name = Thread.currentThread().getName();
        System.out.println("线程OrderDao【" + name + "】中保存的数据是:" + ThreadLocalTest.threadLocal.get());
    }

}

3、JSON

3.1、什么是JSON

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON 采用完全独立于语言的文本格式,而且很多语言都提供了对 json 的支持(包括 C, C++, C#, Java, JavaScript, Perl, Python 等)。 这样就使得 JSON 成为理想的数据交换格式。 

json 是一种轻量级的数据交换格式。 

轻量级指的是跟 xml 做比较。 
数据交换指的是客户端服务器之间业务数据的传递格式。

3.2、JSON在JavaScript中的使用

3.2.1、JSON的定义

json 是由键值对组成,并且由花括号(大括号)包围。每个键由引号引起来,键和值之间使用冒号进行分隔, 多组键值对之间进行逗号进行分隔。

// json的定义
			var jsonObj = {
				"key1":12,
				"key2":"abc",
				"key3":true,
				"key4":[11,"arr",false],
				"key5":{
					"key5_1" : 551,
					"key5_2" : "key5_2_value"
				},
				"key6":[{
					"key6_1_1":6611,
					"key6_1_2":"key6_1_2_value"
				},{
					"key6_2_1":6621,
					"key6_2_2":"key6_2_2_value"
				}]
			};

			alert(typeof(jsonObj));	//Object

3.2.2、JSON的访问

json 本身是一个对象。 
json 中的 key 我们可以理解为是对象中的一个属性。 
json 中的 key 访问就跟访问对象的属性一样: json 对象.key

// json的访问
			// alert(jsonObj.key1);	//12
			// alert(jsonObj.key2);	//abc
			// alert(jsonObj.key3);	//true

			// alert(jsonObj.key4);	//得到数组 [11,arr,false]
			// for(var i = 0; i < jsonObj.key4.length; i++){
			// 	alert(jsonObj.key4[i]);
			// }

			// alert(jsonObj.key5);	//[object Object]
			// alert(jsonObj.key5.key5_1);	//551
			// alert(jsonObj.key5.key5_2);	//key5_2_value

			// alert(jsonObj.key6);	//[object Object],[object Object]
			//取出来的每一个元素都是json对象
			// var jsonItem = jsonObj.key6[0];
			// alert(jsonItem.key6_1_1);	//6611
			// alert(jsonItem.key6_1_2);	//key6_1_2_value

3.2.3、json的两个常用方法

json 的存在有两种形式。 
一种是:对象的形式存在,我们叫它 json 对象。 
一种是:字符串的形式存在,我们叫它 json 字符串。 
一般我们要操作 json 中的数据的时候,需要 json 对象的格式。 
一般我们要在客户端和服务器之间进行数据交换的时候,使用 json 字符串。 

JSON.stringify() 把 json 对象转换成为 json 字符串 

JSON.parse() 把 json 字符串转换成为 json 对象

// alert(jsonObj);	//[object Object]
			var jsonObjString = JSON.stringify(jsonObj);	//把json对象转化为字符串类似toString
			// alert(jsonObjString);
			var jsonObj2 = JSON.parse(jsonObjString);	//把json字符串转化为json对象
			alert(jsonObj2.key1);	//12

3.3、JSON在java中的使用

3.3.0、准备工作

使用前需要先进行导包:gson-2.2.4.jar

Person.java

package pojo;

/**
 * @Author zhang
 * @Date 2022/1/13 0:22
 * @Version 1.0
 */
public class Person {

    private Integer id;
    private String name;

    public Person(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Person() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

3.3.1、JavaBean 和 json 的互转

//JavaBean 和 json 的互转
    @Test
    public void test1(){
        Person person = new Person(1,"zyj");
        //创建Gson对象实例
        Gson gson = new Gson();
        //toJson方法可以把java对象转换成json字符串
        String personJsonString = gson.toJson(person);
        System.out.println(personJsonString);   //{"id":1,"name":"zyj"}
        //fromJson方法可以把json字符串转换为java对象,第一个参数是json字符串,第二个参数是转换回去的java对象类型
        Person person1 = gson.fromJson(personJsonString, Person.class);
        System.out.println(person1);    //Person{id=1, name='zyj'}
    }

3.3.2、List 和 json 互转

PersonListType.java

package json;

import com.google.gson.reflect.TypeToken;
import pojo.Person;

import java.util.ArrayList;

/**
 * @Author zhang
 * @Date 2022/1/13 0:46
 * @Version 1.0
 */


// TypeToken<> 中的括号放的是要将字符串转换回去的类型
public class PersonListType extends TypeToken<ArrayList<Person>> {
}

测试类: 

//List 和 json 互转
    @Test
    public void test2() {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person(1, "zyj"));
        personList.add(new Person(2, "xzf"));

        Gson gson = new Gson();

        //把List转换为Json字符串
        String personListJsonString = gson.toJson(personList);
        System.out.println(personListJsonString);   //[{"id":1,"name":"zyj"},{"id":2,"name":"xzf"}]


        List<Person> list = gson.fromJson(personListJsonString, new PersonListType().getType());
        System.out.println(list);   //[{id=1.0, name=zyj}, {id=2.0, name=xzf}]
        Person person = list.get(0);
        System.out.println(person); //Person{id=1, name='zyj'}
    }

3.3.3、map 和 json 的互转

//map 和 json 互转
    @Test
    public void test3() {
        Map<Integer, Person> personMap = new HashMap<>();
        personMap.put(1, new Person(1, "zyj"));
        personMap.put(2, new Person(2, "xzf"));

        Gson gson = new Gson();

        //把map集合转换为json字符串
        String personMapJsonString = gson.toJson(personMap);
        System.out.println(personMapJsonString);    //{"1":{"id":1,"name":"zyj"},"2":{"id":2,"name":"xzf"}}

        //把json字符转换为map集合
        //Map<Integer, Person> personMap2 = gson.fromJson(personMapJsonString, new PersonMapType().getType());
        Map<Integer, Person> personMap2 = gson.fromJson(personMapJsonString, new TypeToken<Map<Integer, Person>>() {}.getType());
        System.out.println(personMap2);
        Person person = personMap2.get(1);
        System.out.println(person); //Person{id=1, name='zyj'}
    }

4、AJAX请求

相关文档:

4.1、什么是AJAX请求

AJAX 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
ajax 是一种浏览器通过 js 异步发起请求,局部更新页面的技术。 
Ajax 请求的局部更新,浏览器地址栏不会发生变化 
局部更新不会舍弃原来页面的内容 

4.2、原生AJAX请求的示例

 

同步和异步的区别:

同步: 提交请求 ->服务器进行处理->等待结果(这个期间,你不能做任何事,只有收到服务器的结果后,才可进行其他操作)

异步: 提交请求->服务器处理(这个期间你不用等待服务器的结果,你可去干自己的事情了)->处理完毕

 示例:

BaseServlet.java:

package servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Author zhang
 * @Date 2021/12/27 9:41
 * @Version 1.0
 */
public abstract class BaseServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决post请求中文乱码问题,一定要在获取请求参数之前调用才有效
        req.setCharacterEncoding("UTF-8");
        //解决响应中文乱码问题
        resp.setContentType("text/html;charset=UTF-8");

        String action = req.getParameter("action");
        try {
            //反射
            //鉴别action字符串,获取相应的方法
            Method method = this.getClass().getDeclaredMethod(action,HttpServletRequest.class, HttpServletResponse.class);
            //调用方法
            method.invoke(this,req,resp);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }

    }


}

AjaxServlet.java:

package servlet;

import com.google.gson.Gson;
import pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author zhang
 * @Date 2022/1/13 14:16
 * @Version 1.0
 */
public class AjaxServlet extends BaseServlet{

    protected void javaScriptAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是Ajax请求");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);

    }

}

ajax.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="pragma" content="no-cache" />
		<meta http-equiv="cache-control" content="no-cache" />
		<meta http-equiv="Expires" content="0" />
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title here</title>
		<script type="text/javascript">
			//使用javaScript语言发起Ajax请求,访问服务器AjaxServlet中的javaScriptAjax方法
			function ajaxRequest() {
// 				1、我们首先要创建XMLHttpRequest
				var xmlhttprequest = new XMLHttpRequest();

// 				2、调用open方法设置请求参数
				xmlhttprequest.open("GET","http://localhost:8080/16_json_ajax_i18n/ajaxServlet?action=javaScriptAjax",true);

// 				4、在send方法前绑定onreadystatechange事件,处理请求完成后的操作。
				xmlhttprequest.onreadystatechange = function (){
					if(xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200){
						// alert(xmlhttprequest.responseText);

						var jsonObj = JSON.parse(xmlhttprequest.responseText);

						//把响应的数据显示在页面上
						document.getElementById("div01").innerText = "编号:" + jsonObj.id + ", 姓名:" + jsonObj.name + "\n";
					}
				}

// 				3、调用send方法发送请求
				xmlhttprequest.send();
			}
		</script>
	</head>
	<body>
		<button onclick="ajaxRequest()">ajax request</button>
		<div id="div01">
		</div>
	</body>
</html>

4.3、jQuery 中的 ajax 请求

帮助文档:

4.3.1、$ajax 方法 

url 表示请求的地址 

type 表示请求的类型 GET 或 POST 请求 

data 表示发送给服务器的数据 
    格式有两种: 
        一:name=value&name=value 
        二:{key:value} 

success 请求成功,响应的回调函数 

dataType 响应的数据类型 
    常用的数据类型有:
        text 表示纯文本 
        xml 表示 xml 数据 
        json 表示 json 对象

AjaxServlet.java 添加方法

protected void jqueryAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jqueryAjax方法");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);

    }
// ajax请求
				$("#ajaxBtn").click(function(){
					$.ajax({
						/*url:"http://localhost:8080/16_json_ajax_i18n/ajaxServlet",
						// data:"action=jqueryAjax",
						data:{action:"jqueryAjax"},
						type:"GET",
						success:function (data){
							// alert("服务器返回的数据是:" + data);
							var jsonObj = JSON.parse(data);
							$("#msg").html("编号:" + jsonObj.id + ",姓名:" + jsonObj.name);
						},
						dataType:"text"*/

						url:"http://localhost:8080/16_json_ajax_i18n/ajaxServlet",
						// data:"action=jqueryAjax",
						data:{action:"jqueryAjax"},
						type:"GET",
						success:function (data){
							// alert("服务器返回的数据是:" + data);
							$("#msg").html("编号:" + data.id + ",姓名:" + data.name);
						},
						dataType:"json"
					})
				});

4.3.2、$.get 方法和$.post 方法

url 请求的 url 地址 

data 发送的数据 

callback 成功的回调函数 

type 返回的数据类型

AjaxServlet.java 添加方法

protected void jqueryGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jqueryGet方法");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }

    protected void jqueryPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jqueryPost方法");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }
// ajax--post请求
				$("#postBtn").click(function(){
					$.post("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jqueryPost",function (data){
						$("#msg").html("post:编号:" + data.id + ",姓名:" + data.name);
					},"json");
				});

				// ajax--getJson请求
				$("#getJSONBtn").click(function(){
					// 调用
					alert("getJSON btn");

				});

4.3.3、$getJSON 方法

url 请求的 url 地址 

data 发送给服务器的数据 

callback 成功的回调函数

AjaxServlet.java 添加方法

protected void jqueryGetJSON(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jqueryGetJSON方法");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }
// ajax--getJson请求
				$("#getJSONBtn").click(function(){
					$.getJSON("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jqueryGetJSON",function (data){
						$("#msg").html("getJSON:编号:" + data.id + ",姓名:" + data.name);
					});
				});

4.3.4、表单序列化 serialize()

serialize()可以把表单中所有表单项的内容都获取到,并以 name=value&name=value 的形式进行拼接。

AjaxServlet.java 添加方法

protected void jquerySerialize(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jquerySerialize方法");
        Person person = new Person(1 , "帅哥");

        System.out.println("用户名:" + req.getParameter("username"));
        System.out.println("密码:" + req.getParameter("password"));

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }
// ajax请求
				$("#submit").click(function(){
					// 把参数序列化
					// alert( $("#form01").serialize() );

					$.getJSON("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jquerySerialize&" + $("#form01").serialize(),function (data){
						// $("#msg").html("jquerySerialize:编号:" + data.id + ",姓名:" + data.name);

					});
				});

4.3.5、完整代码

AjaxServlet.java:

package servlet;

import com.google.gson.Gson;
import pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author zhang
 * @Date 2022/1/13 14:16
 * @Version 1.0
 */
public class AjaxServlet extends BaseServlet{

    protected void javaScriptAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是Ajax请求");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);

    }


    protected void jqueryAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jqueryAjax方法");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }

    protected void jqueryGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jqueryGet方法");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }

    protected void jqueryPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jqueryPost方法");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }

    protected void jqueryGetJSON(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jqueryGetJSON方法");
        Person person = new Person(1 , "帅哥");

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }

    protected void jquerySerialize(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是jquerySerialize方法");
        Person person = new Person(1 , "帅哥");

        System.out.println("用户名:" + req.getParameter("username"));
        System.out.println("密码:" + req.getParameter("password"));

        //转为Json格式的字符串
        Gson gson = new Gson();
        String personJsonString = gson.toJson(person);

        resp.getWriter().write(personJsonString);
    }

}

页面代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="pragma" content="no-cache" />
		<meta http-equiv="cache-control" content="no-cache" />
		<meta http-equiv="Expires" content="0" />
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title here</title>
		<script type="text/javascript" src="script/jquery-1.7.2.js"></script>
		<script type="text/javascript">
			$(function(){
				// ajax请求
				$("#ajaxBtn").click(function(){
					$.ajax({
						/*url:"http://localhost:8080/16_json_ajax_i18n/ajaxServlet",
						// data:"action=jqueryAjax",
						data:{action:"jqueryAjax"},
						type:"GET",
						success:function (data){
							// alert("服务器返回的数据是:" + data);
							var jsonObj = JSON.parse(data);
							$("#msg").html("编号:" + jsonObj.id + ",姓名:" + jsonObj.name);
						},
						dataType:"text"*/

						url:"http://localhost:8080/16_json_ajax_i18n/ajaxServlet",
						// data:"action=jqueryAjax",
						data:{action:"jqueryAjax"},
						type:"GET",
						success:function (data){
							// alert("服务器返回的数据是:" + data);
							$("#msg").html("ajax:编号:" + data.id + ",姓名:" + data.name);
						},
						dataType:"json"
					})
				});

				// ajax--get请求
				$("#getBtn").click(function(){
					$.get("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jqueryGet",function (data){
						$("#msg").html("get:编号:" + data.id + ",姓名:" + data.name);
					},"json");
				});
				
				// ajax--post请求
				$("#postBtn").click(function(){
					$.post("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jqueryPost",function (data){
						$("#msg").html("post:编号:" + data.id + ",姓名:" + data.name);
					},"json");
				});

				// ajax--getJson请求
				$("#getJSONBtn").click(function(){
					$.getJSON("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jqueryGetJSON",function (data){
						$("#msg").html("getJSON:编号:" + data.id + ",姓名:" + data.name);
					});
				});

				// ajax请求
				$("#submit").click(function(){
					// 把参数序列化
					// alert( $("#form01").serialize() );

					$.getJSON("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jquerySerialize&" + $("#form01").serialize(),function (data){
						// $("#msg").html("jquerySerialize:编号:" + data.id + ",姓名:" + data.name);

					});
				});
				
			});
		</script>
	</head>
	<body>
		<div>
			<button id="ajaxBtn">$.ajax请求</button>
			<button id="getBtn">$.get请求</button>
			<button id="postBtn">$.post请求</button>
			<button id="getJSONBtn">$.getJSON请求</button>
		</div>

		<div id="msg">

		</div>

		<br/><br/>
		<form id="form01" >
			用户名:<input name="username" type="text" /><br/>
			密码:<input name="password" type="password" /><br/>
			下拉单选:<select name="single">
			  	<option value="Single">Single</option>
			  	<option value="Single2">Single2</option>
			</select><br/>
		  	下拉多选:
		  	<select name="multiple" multiple="multiple">
		    	<option selected="selected" value="Multiple">Multiple</option>
		    	<option value="Multiple2">Multiple2</option>
		    	<option selected="selected" value="Multiple3">Multiple3</option>
		  	</select><br/>
		  	复选:
		 	<input type="checkbox" name="check" value="check1"/> check1
		 	<input type="checkbox" name="check" value="check2" checked="checked"/> check2<br/>
		 	单选:
		 	<input type="radio" name="radio" value="radio1" checked="checked"/> radio1
		 	<input type="radio" name="radio" value="radio2"/> radio2<br/>
		</form>			
		<button id="submit">提交--serialize()</button>
	</body>
</html>

5、i18n国际化(了解)

5.1、什么是i18n国际化

国际化(Internationalization)指的是同一个网站可以支持多种不同的语言,以方便不同国家,不同语种的用户访问。  

关于国际化我们想到的最简单的方案就是为不同的国家创建不同的网站,比如苹果公司,他的英文官网是: http://www.apple.com 而中国官网是 http://www.apple.com/cn  

苹果公司这种方案并不适合全部公司,而我们希望相同的一个网站,而不同人访问的时候可以根据用户所在的区域显示 不同的语言文字,而网站的布局样式等不发生改变。于是就有了我们说的国际化,国际化总的来说就是同一个网站不同国家的人来访问可以显示出不同的语言。但实际上这 种需求并不强烈,一般真的有国际化需求的公司,主流采用的依然是苹果公司的那种方案,为不同的国家创建不同的页面。所以国际化的内容我们了解一下即可。  

国际化的英文 Internationalization,但是由于拼写过长,老外想了一个简单的写法叫做 I18N,代表的是 Internationalization 这个单词,以 I 开头,以 N 结尾,而中间是 18 个字母,所以简写为 I18N。以后我们说 I18N 和国际化是一个意思。

5.2、i18n国际化相关要素

 5.3、i18n国际化properties测试

i18n_en_US.properties 英文

username=username
password=password
sex=sex
age=age
regist=regist
boy=boy
email=email
girl=girl
reset=rese
submit=submit

i18n_zh_CN.properties 中文

username=用户名
password=密码
sex=性别
age=年龄
regist=注册
boy=男
girl=女
email=邮箱
reset=重置
submit=提交

测试代码:

@Test
    public void testLocale() {  //locale:场所
        //获取系统默认的语言、国家信息
        //Locale locale = Locale.getDefault();
        //System.out.println(locale); //zh_CN

        //查看所有语言和国家信息
        //for (Locale availableLocale : Locale.getAvailableLocales()) {
        //    System.out.println(availableLocale);
        //}

        //获取中文,中国常量的Locale对象
        System.out.println(Locale.CHINA);

        //获取英文,美国常量的Locale对象
        System.out.println(Locale.US);
    }

    @Test
    public void testI18n() {
        //得到需要的locale对象
        Locale locale_cn = Locale.CHINA;
        Locale locale_en = Locale.US;

        //通过指定的basename和Locale对象读取响应的配置文件
        ResourceBundle bundle1 = ResourceBundle.getBundle("i18n", locale_cn);
        ResourceBundle bundle2 = ResourceBundle.getBundle("i18n", locale_en);

        System.out.println("用户名:" + bundle1.getString("username"));
        System.out.println("密码:" + bundle1.getString("password"));
        System.out.println("age:" + bundle2.getString("age"));
        System.out.println("sex:" + bundle2.getString("sex"));


    }

问题:

若读取中文乱码,需要在IDEA的设置——编辑器——文件编码中设置properties的默认编码

5.4、通过请求头国际化页面

<%@ page import="java.util.Locale" %>
<%@ page import="java.util.ResourceBundle" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
		 pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		//从请求头获取Locale信息(语言)
		Locale locale = null;
		String country = request.getParameter("country");
		if("cn".equals(country)){
			locale = Locale.CHINA;
		}else if("usa".equals(country)){
			locale = Locale.US;
		}else{
			locale = request.getLocale();
		}
		System.out.println(locale); //zh_CN
		//获取资源包(根据指定的basename和Locale语言信息)
		ResourceBundle resourceBundle = ResourceBundle.getBundle("i18n", locale);
	%>
	<a href="i18n.jsp?country=cn">中文</a>|
	<a href="i18n.jsp?country=usa">english</a>
	<center>
		<h1><%=resourceBundle.getString("regist")%></h1>
		<table>
		<form>
			<tr>
				<td><%=resourceBundle.getString("username")%></td>
				<td><input name="username" type="text" /></td>
			</tr>
			<tr>
				<td><%=resourceBundle.getString("password")%></td>
				<td><input type="password" /></td>
			</tr>
			<tr>
				<td><%=resourceBundle.getString("sex")%></td>
				<td><input type="radio" /><%=resourceBundle.getString("boy")%>
					<input type="radio" /><%=resourceBundle.getString("girl")%>
				</td>
			</tr>
			<tr>
				<td><%=resourceBundle.getString("email")%></td>
				<td><input type="text" /></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
				<input type="reset" value="<%=resourceBundle.getString("reset")%>" />&nbsp;&nbsp;
				<input type="submit" value="<%=resourceBundle.getString("submit")%>" /></td>
			</tr>
			</form>
		</table>
		<br /> <br /> <br /> <br />
	</center>
	国际化测试:
	<br /> 1、访问页面,通过浏览器设置,请求头信息确定国际化语言。
	<br /> 2、通过左上角,手动切换语言
</body>
</html>

5.5、通过JSTL标签库实现国际化

需要先引入标签库

<%--引入标签库--%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<%--引入标签库--%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>


<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

	<%--1、使用标签设置Locale信息--%>
	<fmt:setLocale value="${param.locale}"/>

	<%--2、使用标签设置basename--%>
	<fmt:setBundle basename="i18n"/>

	<%--3、使用标签输出国际化信息--%>
	<%--<fmt:message key="username"/>--%>

	<a href="i18n_fmt.jsp?locale=zh_CN">中文</a>|
	<a href="i18n_fmt.jsp?locale=en_US">english</a>
	<center>
		<h1><fmt:message key="regist"/></h1>
		<table>
		<form>
			<tr>
				<td><fmt:message key="username"/></td>
				<td><input name="username" type="text" /></td>
			</tr>
			<tr>
				<td><fmt:message key="password"/></td>
				<td><input type="password" /></td>
			</tr>
			<tr>
				<td><fmt:message key="sex"/></td>
				<td><input type="radio" /><fmt:message key="boy"/>
					<input type="radio" /><fmt:message key="girl"/>
				</td>
			</tr>
			<tr>
				<td><fmt:message key="email"/></td>
				<td><input type="text" /></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
				<input type="reset" value="<fmt:message key="reset"/>" />&nbsp;&nbsp;
				<input type="submit" value="<fmt:message key="submit"/>" /></td>
			</tr>
			</form>
		</table>
		<br /> <br /> <br /> <br />
	</center>
</body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值