精华内容
下载资源
问答
  • 网页设计项目 Web设计编程的无聊课程注册项目。
  • java web 编程课程总结 这次的课程和以往的课程有一些不同一是需要理解的概念专业术语很多比如Java Web里引入了Web体系结构MVC 设计模式等的概念出现了ServletJavaBean ScriptletJSTL等无法替代的术语二是这次学习的...
  • 1、掌握Web服务器软件IIS的安装、配置和测试; 2、熟悉VBScript脚本语言的语法; 3、熟悉JavaScript脚本语言的语法; 4、掌握在网页中使用脚本语言编程、调试的方法。 二、实验内容 1、设置IIS的主目录,并在...
  • 一、团队课程设计博客链接二、个人负责模块或任务说明实体类的设计斗地主规则的实现人机自动出牌的算法实现数据库的DAO模式三、自己的代码提交记录注:这里只有部分提交记录,详细的提交记录在团队课程设计博客里有...

    一、团队课程设计博客链接

    二、个人负责模块或任务说明

    实体类的设计

    斗地主规则的实现

    人机自动出牌的算法

    实现数据库的DAO模式

    三、自己的代码提交记录

    a46f9db1dc816c360fe46c0b19ac418b.png

    注:这里只有部分提交记录,详细的提交记录在团队课程设计博客里有

    四、自己负责模块或任务详细说明

    1、实体类的设计的代码分析

    游戏设计需要用到卡片类(Card)正反面,还有牌型(CardType)的设计,以及各种牌的组合,还要设计在游戏中的抢地主、出牌倒计时、出牌和不出牌等等以及需要判断是否能够出牌和人机自动出牌等。

    整体的设计需要用户类(User)用于存储用户的账号密码,以及用户信息类(UserInformation)用于存储用户的账号、昵称、积分等等个人信息。

    2、斗地主规则的实现的代码分析

    既然是一个游戏,那就要有规则,其中最主要的就是,判断所选的牌型是否正确,即是否符合规则。在牌型符合规则时,需要判断是否能够出牌。

    在判断所选的牌型是否符合规则的设计中,因为规则中的牌型是固定的,所以设计了一个常量CardType类,这个常量类中包括了符合斗地主规则的所有可选牌型以及不允许出牌的常量。

    d2273014bd195b3301f59363c5ccc92d.png

    判断牌型的时候,需要根据所选的牌的数量,以及各个牌型的特征,如:连对的基本特征为,需要连续3对,并且这三对的数值是连续的等等,来判断用户所选的牌是否为规则内的牌型,是的话返回相应的牌型,供后面的算法判断,如果不是则返回c0,服务器就会给客户端相应的反馈,禁止用户出所选的牌。

    542e8fe16d200f72d39f44bbff016a83.png

    判断完牌型后,如果返回的不是c0,则需要判断用户是否能够出所选的牌。在这个判断中,首先就需要判断用户是主动出牌还是跟牌,如果为主动出牌,则服务器就会给客户端相应的反馈,同意用户出牌;如果为被动出牌,则需要判断当前用户所选的牌,与前面的用户出的最大的牌进行比较。

    当前面出的牌不是炸弹,而用户选的牌型为炸弹时,既可以出牌。当用户选的牌型不为炸弹时,需要判断该用户所选的牌是否与前面用户所出的牌型相符合,若符合,则判断该用户所选的牌是否比前面用户所出的牌大,若符合则允许出牌,否则禁止用户出牌。

    648069c14b62994030dc3fcbbb0d866d.png

    3、人机自动出牌的算法的代码分析

    本次课程设计实现的是单人单机游戏,则需要电脑自动判断除用户外的另外两幅牌该如何出。

    判断人机如何出牌时,首先先判断人机为主动出牌还是被动出牌,若为主动出牌,则把人机的牌进行拆分,拆分成符合规则的相关牌型,然后按先出单牌,再出对子,在出连对等等的顺序,按序选择该轮人机所要出的牌。

    7b3f00cdd24a6370c1a3cb751ebbcd5e.png

    如果为被动出牌,则将人机的牌进行拆分,拆分成符合规则的相关牌型,然后通过判断目前所出的最大的牌的牌型,根据该牌型判断目前该人机手中是否拥有符合条件的牌,若有,再判断该人机的下一个出牌人是否为地主,如果是,则选择最大的出,如果不是则选择最小的出。如果没有符合条件的牌,则该人机就不出牌。

    a645b4394dc76e4369a84f2ce8a82086.png

    由于两个操作都涉及到对人机牌的拆分,在拆分的过程中,按照炸弹优先,拆分三带,拆分飞机等等的顺序,将人机的手牌拆分成符合规则的各个种类的手牌,防止拆了规则中的大牌,如炸弹等等。

    c89d926dbdc936626d53aef64bab87b6.png

    最后就是,一开始的抢地主环节,当用户抢地主时,则地主就为用户,当用户不抢地主时,需要根据人机当前手牌的权重大小,来判断是那个人机要抢地主。该权重的计算方法为,统计两幅人机手牌中大小王、A以及2的多少来计算,权重大的获得地主牌。

    45e775dd717034b9bfb9deb3605610ec.png

    4、数据存储DAO模式代码分析

    DAO(Data Access Object)顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象,在不暴露底层持久化方案实现细节的前提下提供了各种数据访问操作。

    本次课程设计的底层数据存储为数据库,为了以防以后使用文件等其他形式存储数据,为了方便日后修改小量代码,使用了DAO模式设计数据存储。

    在本次课程设计的DAO模式的设计中,使用了两个DAO接口类,UserDAO以及UserInformationDAO类,里面分别包括对User以及UserInformation的操作的相关方法。

    fbda11805c7d2b63d02e365773517015.png

    e4c849dbfa54bbe15a6729b6f4a432f0.png

    因为使用了数据库实现数据的存储,所以在数据库的操作类分别实现了上面的两个接口。由于在对数据库的每次操作中,均需要链接数据库以及断开与数据库的链接,所以将链接数据库以及断开与数据的链接的操作拿出来,另外写了一个JDBCUtil工具类。

    d1c8e858193dc6cca4312410e88599db.png

    5、多人同时访问并进行游戏(多线程)的代码分析

    本次课程设计要实现的最终目标即为该斗地主游戏可以实现多人同时进行游戏。

    则涉及到了多线程,当多人同时向服务器发出请求时,服务器需要判断该请求来自哪位玩家,该玩家所属的牌局当前的状态,并进行相关的计算,给浏览器返回相应的计算结果。

    所以,我们写了一个InitServlet,用于当Tomcat服务器启动时,就将一个牌局组对象(CardGames)写入application中,则这牌局组对象就会一直存在,直到Tomcat服务器关闭。

    e28732e22ef6f4eebc46d189252d1889.png

    这个牌局组(CardGames)对象,包括了一个Map类型的牌局组,一个Integer类型的标志(sign),并且包括一个新建牌局的对象,在新建牌局的时候,将标志,以及新建的牌局放入Map中,并且将改标志赋值给相应的用户中的牌局标识,在后期的数据传输中,后台只要从客户端获取该请求的用户,即可通过该用户对应的牌局标识来从application中获取的牌局组的对象中,获得相应的牌局,从而得到正确的结果。为了防止多个用户同时向服务器发送新家牌局的请求,导致出现了错误,所以为创建牌局的方法添加了互斥锁。

    62db15cd908b3016ef54a06b09ac61ca.png

    牌局的对象中定义了初始牌对象,地主标识符,对应角色是否出牌标识,当前的出牌,3个玩家的所分到的牌,以及地主牌。

    d863aab4f07b789c22bc7e1acd5249fe.png

    五、课程设计感想

    在本次课程设计中,我主要负责的模块为后端的代码。最为难忘的便是在实体类的设计中,使用了public属性,并且最初的设计中,基本没有涉及到对象,导致后期在实现多人同时访问时出现了各种各样的错误,最后只好对已有的代码进行重构,花费了更多的时间,特别是在对牌型判断的公共方法中,进行了大修改。

    本次课程设计,实现了网络web版的单人斗地主,无法支持多人同时进行游戏,可以在次基础上进行迭代,进而实现多人游戏。在对人机自动出的牌较为简单,对人机出牌的判断方法较为笨拙,可以进行优化,如添加人工智能算法等使得人机更加的“聪明”。

    通过本次课程设计,让我对JAVA的面向对象设计有了更加深刻的理解,平时上课讲的比较基础,再加上有时候可能没有认真听课,PTA上的题目较为简单,未能对面向对象编程有更加深入的了解,虽然花费了大量的时间(将近两周吧),但是收获多多。

    展开全文
  • web编程课程小结

    千次阅读 2016-12-21 21:31:24
    本学期学习了网络编程课程,但是并没有涉及到socket等内容,所以准确来说应该算是web编程课,以下是对本学期课程学习要点的一些总结: html/css (1)学习了常用的一些简单标签,然后制作了单列布局(仅使用了html...

    本学期学习了网络编程课程,但是并没有涉及到socket等内容,所以准确来说应该算是web编程课,以下是对本学期课程学习要点的一些总结:

    html/css

    (1)学习了常用的一些简单标签,然后制作了单列布局(仅使用了html)的网页。
    (2)学习CSS,引入了DOM的概念,学习设置元素的属性。
    (3)在前两步的前提下,开始学习网页布局,设计网页。
    学习要点:1.DOM 2.盒模型 3.布局模型


    js
    (4)通过ID或class获取DOM元素,并进行css属性的修改。
    (5)引入事件,通过事件触发函数,来实现动态效果。
    学习要点:1.函数 2.事件 4.修改DOM的CSS属性


    jsp
    (6)服务器的基本工作原理。
    (7)jsp获取表单内容,并存入session,来实现不同页面间数据的传递。
    (8)jsp连接数据库,并且实现执行SQL语句,完成对数据库的增删查改功能。
    学习要点:1.数据库语句 2.jsp语法 3.服务器
    展开全文
  • 开发Web服务器项目中的编程实现 1在线帮助的设计与实现 1.chm的帮助文件 在帮助菜单的事件响应中加载帮助文件 Runtime currentRunTime=Runtime.getRuntime; Process newProcess=null; try { //c:\winnt\hh.exe 为....
  • 本次课程设计使用MyEclipse编译器,使用的编程语言为HTML5、CSS、JavaScript,本次的课程设计适用于初学者,比较适合本科阶段的结课设计。本次的设计内容包括:各个网页的链接、锚点、注册表、问卷调查、有序列表和...
  • 网页下载系统 课程设计报告 姓名:周帅强,杨梦媛 班级:10软工java2班 指导老师:张磊 一.需求分析 1.前言 1.1目的 本文为网页下载系统的需求说明,该文档需要使使用者能够清楚明白的使用系统和了解系统 1.2产品范围 ...
  • 该存储库包含在挪威奥斯陆的大学学院教授的PG6301 Web开发和API设计课程中使用的所有材料。 本课程的目的是教授单页应用程序(SPA)的原理,Web服务(例如REST API )和Web套接字的基础。 本课程中使用的编程语言...
  • 相信很多人在socket编程学习过程中,都会遇到类似的web服务器的设计案例,可是对于刚接触socket的新手来说,往往难以迈出第一步,于是在此分享一个多线程的web服务器代码(参考计算机网络课程的代码框架),便于各位...

    相信很多人在socket编程学习过程中,都会遇到类似的web服务器的设计案例,可是对于刚接触socket的新手来说,往往难以迈出第一步,于是在此分享一个多线程的web服务器代码(参考计算机网络课程的代码框架),便于各位网友参考学习使用!

     

    一、理解多线程

    多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。

    线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。

    多个线程的执行是并发的,也就是在逻辑上同时,而不管是否是物理上的同时。如果系统只有一个单核CPU,那么真正的同时是不可能的。不过,由于CPU的处理速度非常快,用户感觉好像自己的程序连续运行一样。

    多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的

    二、案例需求

    以JDK为开发工具,利用Socket通信机制实现一个多线程的WEB服务器,该服务器具有以下功能:

    1. 能够并行服务于多个请求。
    2. 对于每个请求,显示接收到的HTTP请求报文的内容,并产生适当的响应(若找到用户请求对象,则返回该对象。否则发送一个包含适当提示信息的响应消息,从而可以在浏览器窗口中显示差错信息。

    三、代码部分

    
    
    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public final class WebServer {
    	public static void main(String argv[]) throws Exception {
    		int port = 6666;//定义端口号
    		ServerSocket welcomeSocket = new ServerSocket(port);
    		while (true) {
    			Socket connectionSocket = welcomeSocket.accept();
    			HttpRequest request = new HttpRequest(connectionSocket);
    			Thread thread = new Thread(request);
    			thread.start();
    		}
    	}
    }
    
    final class HttpRequest implements Runnable {
    	final static String CRLF = "\r\n";
    	Socket socket;
    
    	public HttpRequest(Socket socket) throws Exception {
    		this.socket = socket;
    	}
    
    	public void run() {
    		try {
    			processRequest();
    
    		} catch (Exception e) {
    			System.out.println(e);
    		}
    	}
    
    	private void processRequest() throws Exception {
    		InputStream is = socket.getInputStream();
    		DataOutputStream os = new DataOutputStream(socket.getOutputStream());
    
    		BufferedReader br = new BufferedReader(new InputStreamReader(is));
    		String requestLine = br.readLine();
    		System.out.println();
    		System.out.println(requestLine);
    		String headerLine = null;
    		while ((headerLine = br.readLine()).length() != 0) {
    			System.out.println(headerLine);
    		}
    		
    		// 从请求行中提取出文件名
    		StringTokenizer tokens = new StringTokenizer(requestLine);
    		tokens.nextToken(); // 跳过method
    		String fileName = tokens.nextToken();
    		fileName = "." + fileName;//构造请求文件名
    		
    
    		FileInputStream fis = null;
    		boolean fileExists = true;
    		// 判断请求对象是否存在
    		try {
    			fis = new FileInputStream(fileName);
    		} catch (FileNotFoundException e) {
    			fileExists = false;
    		}
    		String statusLine = null;
    		String contentTypeLine = null;
    		String entityBody = null;
    
    		if (fileExists) {// 请求文件存在构造响应的status 和 contentType
    			statusLine = "HTTP/1.1 200 OK" + CRLF;
    			contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
    		} else {// 请求文件不存在
    			statusLine = "HTTP/1.1 404" + CRLF;
    			contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
    			entityBody = "<!DOCTYPE html><HTML>" + "<HEAD><TITLE>Not Found</TITLE></HEAD>" + "<BODY>Not Found</BODY></HTML>";
    		}
    		os.writeBytes(statusLine);
    		os.writeBytes(contentTypeLine);
    		os.writeBytes(CRLF);
    		if (fileExists) {
    			sendBytes(fis, os);
    			fis.close();
    		} else {
    			os.writeBytes(entityBody);
    		}
    		os.close();
    		br.close();
    		socket.close();
    	}
    
    	private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception {
    		byte[] buffer = new byte[1024];
    		int bytes = 0;
    		while ((bytes = fis.read(buffer)) != -1) {
    			os.write(buffer, 0, bytes);
    		}
    
    	}
    
    	private static String contentType(String fileName)
    
    	{
                    //根据文件名返回相应的contentType
    		if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
    			return "text/html";
    		}
    		if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
    			return "image/jpeg";
    		}
    		if (fileName.endsWith(".png")) {
    			return "image/png";
    		}
    		if (fileName.endsWith(".css")) {
    			return "text/css";
    		}
    		if (fileName.endsWith(".gif")) {
    			return "image/gif";
    		}
    		if (fileName.endsWith(".png")) {
    			return "image/png";
    		}
    		return "application/octet-stream";
    	}
    
    }

    四、代码测试

    测试时使用浏览器访问localhost:port,本例为127.0.0.1:6666,测试用的文件放在项目根目录即可,如使用eclipse编写的项目则需要将文件放在项目名称的目录下(有bin和src的那个目录)

    测试截图如下

    请求成功时正确返回请求文件

    请求失败时给出提示

    展开全文
  • Spring Web 编程详解

    2018-04-12 10:41:41
    课程基于最畅销《Spring 实战》图书介绍了 Java Web 领域相关的技术,同时,深入剖析了 Spring 5 带来的最新 Reactive 理念,让读者既能学到当前最流行的技术,又能把握未来技术发展的方向和潮流。 作者介绍 张...

    课程简介

    本课程基于最畅销《Spring 实战》图书介绍了 Java Web 领域相关的技术,同时,深入剖析了 Spring 5 带来的最新 Reactive 理念,让读者既能学到当前最流行的技术,又能把握未来技术发展的方向和潮流。

    作者介绍

    张卫滨,资深软件工程师,十年的软件开发与设计经验,精通 Java 技术栈相关的开源框架,InfoQ 技术网站社区编辑,译有多本畅销的技术图书。

    课程内容

    第01课:Spring MVC 简介与环境搭建

    作为企业级 Java 开发者,可能开发过一些基于 Web 的应用程序,但对于大部分 Java 开发人员来说,基于 Web 的应用程序是他们主要的关注点。如果有这方面经验的话,就能意识到这种系统所面临的挑战。具体来讲,状态管理、工作流以及验证都是需要解决的重要特性。HTTP 协议的无状态性决定了这些问题都没那么容易解决。

    Spring 的 Web 框架就是为了解决这些关注点而设计的。Spring MVC 基于模型—视图—控制器(Model-View-Controller,MVC)模式实现,它能够构建像 Spring 框架那样灵活和松耦合的 Web 应用程序。

    在本文中将会概要介绍 Spring MVC Web 框架以及初始化环境的搭建。

    Spring MVC 起步

    大家知道捕鼠器游戏吗?这是一个疯狂的游戏,它的目标是发送一个小钢球,让它经过一系列稀奇古怪的装置,最后触发捕鼠器。小钢球穿过各种复杂的配件,从一个斜坡上滚下来,被跷跷板弹起,绕过一个微型摩天轮,然后被橡胶靴从桶中踢出去。经过这些后,小钢球会对那只可怜又无辜的橡胶老鼠进行捕获。

    乍看上去,Spring MVC 框架与捕鼠器有些类似。Spring 将请求在调度 Servlet、处理器映射(handler mapping)、控制器以及视图解析器(view resolver)之间移动,而捕鼠器中的钢球则会在各种斜坡、跷跷板以及摩天轮之间滚动。但是,不要将 Spring MVC 与 Rube Goldberg-esque 捕鼠器游戏做过多比较。每一个 Spring MVC 中的组件都有特定的目的,并且它也没有那么复杂。

    让我们看一下请求是如何从客户端发起,经过 Spring MVC 中的组件,最终再返回到客户端。

    跟踪 Spring MVC 的请求

    每当用户在 Web 浏览器中单击链接或提交表单的时候,请求就开始工作了,对请求的工作描述就像是快递投送员。与邮局投递员或 FedEx 投送员一样,请求会将信息从一个地方带到另一个地方。

    请求是一个十分繁忙的家伙,从离开浏览器开始到获取响应返回,它会经历好多站,在每站都会留下一些信息同时也会带上其他信息。下图展示了请求使用 Spring MVC 所经历的所有站点。

    在请求离开浏览器时,会带有用户所请求内容的信息,至少会包含请求的 URL。但是还可能带有其他的信息,例如用户提交的表单信息。

    请求旅程的第一站是 Spring 的 DispatcherServlet。与大多数基于 Java 的 Web 框架一样,Spring MVC 所有的请求都会通过一个前端控制器(front controller)Servlet。前端控制器是常用的 Web 应用程序模式,在这里一个单实例的 Servlet 将请求委托给应用程序的其他组件来执行实际的处理。在 Spring MVC 中,DispatcherServlet 就是前端控制器。

    DispatcherServlet 的任务是将请求发送给 Spring MVC 控制器(controller)。控制器是一个用于处理请求的 Spring 组件。在典型的应用程序中可能会有多个控制器,DispatcherServlet 需要知道应该将请求发送给哪个控制器。所以 DispatcherServlet 会查询一个或多个处理器映射(handler mapping)来确定请求的下一站在哪里。处理器映射会根据请求所携带的 URL 信息来进行决策。

    一旦选择了合适的控制器,DispatcherServlet 会将请求发送给选中的控制器,到了控制器,请求会卸下其负载(用户提交的信息)并耐心等待控制器处理这些信息。(实际上,设计良好的控制器本身只处理很少甚至不处理工作,而是将业务逻辑委托给一个或多个服务对象进行处理)。

    控制器在完成逻辑处理后,通常会产生一些信息,这些信息需要返回给用户并在浏览器上显示。这些信息被称为模型(model)。不过仅仅给用户返回原始的信息是不够的——这些信息需要以用户友好的方式进行格式化,一般会是 HTML。所以,信息需要发送给一个视图(view),通常会是 JSP。

    控制器所做的最后一件事就是将模型数据打包,并且标示出用于渲染输出的视图名。它接下来会将请求连同模型和视图名发送回 DispatcherServlet。

    这样,控制器就不会与特定的视图相耦合,传递给 DispatcherServlet 的视图名并不直接表示某个特定的 JSP。实际上,它甚至并不能确定视图就是 JSP。相反,它仅仅传递了一个逻辑名称,这个名字将会用来查找产生结果的真正视图。DispatcherServlet 将会使用视图解析器(view resolver)来将逻辑视图名匹配为一个特定的视图实现,它可能是也可能不是 JSP。

    既然 DispatcherServlet 已经知道由哪个视图渲染结果,那请求的任务基本上也就完成了。它的最后一站是视图的实现(可能是 JSP),在这里它交付模型数据,请求的任务就完成了。视图将使用模型数据渲染输出,这个输出会通过响应对象传递给客户端(不会像听上去那样硬编码)。

    可以看到,请求要经过很多的步骤,最终才能形成返回给客户端的响应。大多数的步骤都是在 Spring 框架内部完成的,也就是上图所示的组件中。我们首先看一下如何搭建 Spring MVC 的基础组件。

    搭建 Spring MVC

    基于前面的图片,看上去我们需要配置很多的组成部分。幸好,借助于最近几个 Spring 新版本的功能增强,开始使用 Spring MVC 变得非常简单了。现在,需使用最简单的方式来配置 Spring MVC:所要实现的功能仅限于运行我们所创建的控制器。

    配置 DispatcherServlet

    DispatcherServlet 是 Spring MVC 的核心。在这里请求会第一次接触到框架,它要负责将请求路由到其他的组件之中。

    按照传统的方式,像 DispatcherServlet 这样的 Servlet 会配置在 web.xml 文件中,这个文件会放到应用的 War 包里面。当然,这是配置 DispatcherServlet 的方法之一。但是,借助于 Servlet 3 规范和 Spring 3.1 的功能增强,这种方式已经不是唯一的方案了,这也不是这里所使用的配置方法。

    我们会使用 Java 将 DispatcherServlet 配置在 Servlet 容器中,而不会再使用 web.xml 文件。如下的程序清单展示了所需的 Java 类。

    程序清单1 配置 DispatcherServlet

    在我们深入介绍上面的程序之前,你可能想知道 spittr 到底是什么意思。这个类的名字是 SpittrWebAppInitializer,它位于名为 spittr.config 的包中。稍后会对其进行介绍,但现在只需要知道所要创建的应用名为 Spittr。

    要理解程序是如何工作的,我们可能只需要知道扩展 AbstractAnnotationConfigDispatcherServletInitializer 的任意类都会自动地配置 DispatcherServlet 和 Spring 应用上下文,Spring 的应用上下文会位于应用程序的 Servlet 上下文之中。

    AbstractAnnotationConfigDispatcherServletInitializer 剖析

    如果你坚持要了解更多细节的话,那就看这里吧。在 Servlet 3.0 环境中,容器会在类路径中查找实现 javax.servlet.ServletContainerInitializer 接口的类,如果能发现的话,就会用它来配置 Servlet 容器。

    Spring 提供了这个接口的实现,名为 SpringServletContainerInitializer,这个类反过来又会查找实现 WebApplicationInitializer 的类并将配置的任务交给它们来完成。Spring 3.2 引入了一个便利的 WebApplicationInitializer 基础实现,也就是 AbstractAnnotationConfigDispatcherServletInitializer。因为我们的 SpittrWebAppInitializer 扩展了 AbstractAnnotationConfigDispatcherServletInitializer(同时也就实现了 WebApplicationInitializer),因此当部署到 Servlet 3.0 容器中的时候,容器会自动发现它,并用它来配置 Servlet 上下文。

    尽管它的名字很长,但是 AbstractAnnotationConfigDispatcherServletInitializer 使用起来很简便。在上面的程序中,SpittrWebAppInitializer 重写了三个方法。

    第一个方法是 getServletMappings(),它会将一个或多个路径映射到 DispatcherServlet 上。在本例中,它映射的是“/”,这表示它会是应用的默认 Servlet。它会处理进入应用的所有请求。

    为了理解其他的两个方法,我们首先要理解 DispatcherServlet 和一个 Servlet 监听器(也就是 ContextLoaderListener)的关系。

    两个应用上下文之间的故事

    当 DispatcherServlet 启动的时候,它会创建 Spring 应用上下文,并加载配置文件或配置类中所声明的 bean。在上面程序的 getServletConfigClasses() 方法中,我们要求 DispatcherServlet 加载应用上下文时,使用定义在 WebConfig 配置类(使用 Java 配置)中的 bean。

    但是在 Spring Web 应用中,通常还会有另外一个应用上下文。另外的这个应用上下文是由 ContextLoaderListener 创建的。

    我们希望 DispatcherServlet 加载包含 Web 组件的 bean,如控制器、视图解析器以及处理器映射,而 ContextLoaderListener 要加载应用中的其他 bean。这些 bean 通常是驱动应用后端的中间层和数据层组件。

    实际上,AbstractAnnotationConfigDispatcherServletInitializer 会同时创建 DispatcherServlet和ContextLoaderListener。getServletConfigClasses() 方法返回的带有 @Configuration 注解的类将会用来定义 DispatcherServlet 应用上下文中的 bean。getRootConfigClasses() 方法返回的带有 @Configuration 注解的类将会用来配置 ContextLoaderListener 创建的应用上下文中的 bean,

    在本例中,根配置定义在 RootConfig 中,DispatcherServlet 的配置声明在 WebConfig 中。稍后我们将会看到这两个类的内容。

    需要注意的是,通过 AbstractAnnotationConfigDispatcherServletInitializer 来配置 DispatcherServlet 是传统 web.xml 方式的替代方案。如果你愿意的话,可以同时包含 web.xml 和 AbstractAnnotationConfigDispatcherServletInitializer,但这其实并没有必要。

    如果按照这种方式配置 DispatcherServlet,而不是使用 web.xml 的话,那唯一问题在于它只能部署到支持 Servlet 3.0 的服务器中才能正常工作,如 Tomcat 7 或更高版本。Servlet 3.0 规范在 2009 年 12 月份就发布了,因此很有可能你会将应用部署到支持 Servlet 3.0 的 Servlet 容器之中。

    如果你还没有使用支持 Servlet 3.0 的服务器,那么在 AbstractAnnotationConfigDispatcherServletInitializer 子类中配置 DispatcherServlet 的方法就不适合你了。你别无选择,只能使用 web.xml 了。我们稍后会学习 web.xml 和其他配置选项。但现在先看一下程序清单中所引用的 WebConfig 和 RootConfig,了解一下如何启用 Spring MVC。

    启用 Spring MVC

    我们有多种方式来配置 DispatcherServlet,与之类似,启用 Spring MVC 组件的方法也不仅一种。以前,Spring 是使用 XML 进行配置的,你可以使用&lt;mvc:annotation-driven&gt;启用注解驱动的 Spring MVC。

    我们随后会讨论&lt;mvc:annotation-driven&gt;。不过,现在我们会让 Spring MVC 的搭建过程尽可能简单并基于 Java 进行配置。

    我们所能创建的最简单的 Spring MVC 配置就是一个带有 @EnableWebMvc 注解的类:

    这可以运行起来,它的确能够启用 Spring MVC,但还有不少问题要解决:

    • 没有配置视图解析器。如果这样的话,Spring 默认会使用 BeanNameViewResolver,这个视图解析器会查找 ID 与视图名称匹配的 bean,并且查找的 bean 要实现 View 接口,它以这样的方式来解析视图。
    • 没有启用组件扫描。这样的结果就是 Spring 只能找到显式声明在配置类中的控制器。
    • 这样配置的话,DispatcherServlet 会映射为应用的默认 Servlet,所以它会处理所有的请求,包括对静态资源的请求,如图片和样式表(在大多数情况下,这可能并不是你想要的效果)。

    因此,我们需要在 WebConfig 这个最小的 Spring MVC 配置上再加一些内容,从而让它变得真正有用。如下程序清单中的 WebConfig 解决了上面所述的问题。

    在上面的程序中第一件需要注意的事情是 WebConfig 现在添加了 @ComponentScan 注解,因此将会扫描 spitter.web 包来查找组件。稍后就会看到,我们所编写的控制器将会带有 @Controller 注解,这会使其成为组件扫描时的候选 bean。因此,不需要在配置类中显式声明任何的控制器。

    接下来,添加了一个 ViewResolver bean。更具体来讲,是 InternalResourceViewResolver,它会查找 JSP 文件,在查找的时候,它会在视图名称上加一个特定的前缀和后缀(例如,名为 home 的视图将会解析为 /WEB-INF/views/home.jsp)。

    最后,新的 WebConfig 类还扩展了 WebMvcConfigurerAdapter 并重写了其 configureDefaultServletHandling() 方法。通过调用 DefaultServletHandlerConfigurer 的 enable()方法,我们要求 DispatcherServlet 将对静态资源的请求转发到 Servlet 容器中默认的 Servlet 上,而不是使用 DispatcherServlet 本身来处理此类请求。

    WebConfig 已经就绪,那 RootConfig 呢?因为本章聚焦于 Web 开发,而 Web 相关的配置通过 DispatcherServlet 创建的应用上下文都已经配置好了,因此现在的 RootConfig 相对很简单:

    唯一需要注意的是 RootConfig 使用了 @ComponentScan 注解。这样的话,我们就有很多机会用非 Web 的组件来充实完善 RootConfig。

    Spring MVC 的高级配置

    前面我们通过扩展 AbstractAnnotationConfigDispatcherServletInitializer 快速搭建了 Spring MVC 环境。在这个便利的基础类中,假设需要基本的 DispatcherServlet 和 ContextLoaderListener 环境,并且 Spring 配置是使用 Java 的,而不是 XML。

    尽管对很多 Spring 应用来说,这是一种安全的假设,但是并不一定总能满足我们的要求。除了 DispatcherServlet 以外,可能还需要额外的 Servlet 和 Filter;可能还需要对 DispatcherServlet 本身做一些额外的配置;或者,如果需要将应用部署到 Servlet 3.0 之前的容器中,那么还需要将 DispatcherServlet 配置到传统的 web.xml 中。

    自定义 DispatcherServlet 配置

    虽然从程序清单1的外观上不一定能够看得出来,但是 Abstract-AnnotationConfigDispatcherServletInitializer 所完成的事情其实比看上去要多。在 SpittrWebAppInitializer 中所编写的三个方法仅仅是必须要重载的 abstract 方法。但实际上还有更多的方法可以进行重载,从而实现额外的配置。

    此类的方法之一就是 customizeRegistration()。在 AbstractAnnotation-ConfigDispatcherServletInitializer 将 DispatcherServlet 注册到 Servlet 容器中之后,就会调用 customizeRegistration(),并将 Servlet 注册后得到的 Registration.Dynamic 传递进来。通过重载 customizeRegistration() 方法,可以对 DispatcherServlet 进行额外的配置。

    借助 customizeRegistration() 方法中的 ServletRegistration.Dynamic,我们能够完成多项任务,包括通过调用 setLoadOnStartup() 设置 load-on-startup 优先级,通过 setInitParameter() 设置初始化参数,通过调用 setMultipartConfig() 配置 Servlet 3.0 对 multipart 的支持。

    添加其他的 Servlet 和 Filter

    按照 AbstractAnnotationConfigDispatcherServletInitializer 的定义,它会创建 DispatcherServlet 和 ContextLoaderListener。但是,如果你想注册其他的 Servlet、Filter 或 Listener 的话,那该怎么办呢?

    基于 Java 的初始化器(initializer)的一个好处就在于我们可以定义任意数量的初始化器类。因此,如果我们想往 Web 容器中注册其他组件的话,只需创建一个新的初始化器就可以了。最简单的方式就是实现 Spring 的 WebApplicationInitializer 接口。

    例如,如下的程序清单展现了如何创建 WebApplicationInitializer 实现并注册一个 Servlet。

    程序清单3 通过实现 WebApplicationInitializer 来注册 Servlet

    程序清单3是相当基础的 Servlet 注册初始化器类。它注册了一个 Servlet 并将其映射到一个路径上。我们也可以通过这种方式来手动注册 DispatcherServlet。(但这并没有必要,因为 AbstractAnnotationConfigDispatcherServletInitializer 没用太多代码就将这项任务完成得很漂亮。)

    类似地,我们还可以创建新的 WebApplicationInitializer 实现来注册 Listener 和 Filter。例如,如下的程序清单展现了如何注册 Filter。

    程序清单4 注册 Filter 的 WebApplicationInitializer

    如果要将应用部署到支持 Servlet 3.0 的容器中,那么 WebApplicationInitializer 提供了一种通用的方式,实现在 Java 中注册 Servlet、Filter 和 Listener。不过,如果你只是注册 Filter,并且该 Filter 只会映射到 DispatcherServlet 上的话,那么在 AbstractAnnotationConfigDispatcherServletInitializer 中还有一种快捷方式。

    为了注册 Filter 并将其映射到 DispatcherServlet,所需要做的仅仅是重载 AbstractAnnotationConfigDispatcherServletInitializer 的 getServletFilters() 方法。例如,在如下的代码中,重载了 AbstractAnnotationConfig-DispatcherServletInitializer 的 getServletFilters() 方法以注册 Filter:

    我们可以看到,这个方法返回的是一个 javax.servlet.Filter 的数组。在这里它只返回了一个 Filter,但它实际上可以返回任意数量的 Filter。在这里没有必要声明它的映射路径,getServletFilters() 方法返回的所有 Filter 都会映射到 DispatcherServlet 上。

    如果要将应用部署到 Servlet 3.0 容器中,那么 Spring 提供了多种方式来注册 Servlet(包括DispatcherServlet)、Filter和Listener,而不必创建 web.xml 文件。但是,如果你不想采取以上所述方案的话,也是可以的。假设需要将应用部署到不支持 Servlet 3.0 的容器中(或者你只是希望使用 web.xml 文件),那么我们完全可以按照传统的方式,通过 web.xml 配置 Spring MVC。让我们看一下该怎么做。

    在 web.xml 中声明 DispatcherServlet

    在典型的 Spring MVC 应用中,我们会需要 DispatcherServlet 和 ContextLoaderListener。AbstractAnnotationConfigDispatcherServlet-Initializer 会自动注册它们,但是如果需要在 web.xml 中注册的话,那就需要我们自己来完成这项任务了。

    如下是一个基本的 web.xml 文件,它按照传统的方式搭建了 DispatcherServlet 和 ContextLoaderListener。

    程序清单5 在 web.xml 中搭建 Spring MVC

    就像曾经介绍过的,ContextLoaderListener 和 DispatcherServlet 各自都会加载一个 Spring 应用上下文。上下文参数 contextConfigLocation 指定了一个 XML 文件的地址,这个文件定义了根应用上下文,它会被 ContextLoaderListener 加载。如程序清单5所示,根上下文会从“/WEB-INF/spring/root-context.xml”中加载 bean 定义。

    DispatcherServlet 会根据 Servlet 的名字找到一个文件,并基于该文件加载应用上下文。在程序清单5中,Servlet 的名字是 appServlet,因此 DispatcherServlet 会从“/WEB-INF/appServlet-context.xml”文件中加载其应用上下文。

    如果你希望指定 DispatcherServlet 配置文件的位置的话,那么可以在 Servlet 上指定一个 contextConfigLocation 初始化参数。例如,如下的配置中,DispatcherServlet 会从“/WEB-INF/spring/appServlet/servlet-context.xml”加载它的 bean:

    现在,我们基本上已经可以开始使用 Spring MVC 构建 Web 应用了。此时,最大的问题在于,我们要构建的应用到底是什么。

    Spittr 应用简介

    为了实现在线社交的功能,我们将要构建一个简单的微博(microblogging)应用。在很多方面,我们所构建的应用与最早的微博应用 Twitter 很类似。在这个过程中,我们会添加一些小的变化。当然,我们要使用 Spring 技术来构建这个应用。

    因为从 Twitter 借鉴了灵感并且通过 Spring 来进行实现,所以它就有了一个名字:Spitter。再进一步,应用网站命名中流行的模式,如 Flickr,我们去掉字母 e,这样的话,我们就将这个应用称为 Spittr。这个名称也有助于区分应用名称和领域类型,因为我们将会创建一个名为 Spitter 的领域类。

    Spittr 应用有两个基本的领域概念:Spitter(应用的用户)和 Spittle(用户发布的简短状态更新)。当我们完善 Spittr 应用的功能时,将会介绍这两个领域概念。接下来,我们会构建应用的 Web 层,创建展现 Spittle 的控制器以及处理用户注册成为 Spitter 的表单。

    舞台已经搭建完成了。我们已经配置了 DispatcherServlet,启用了基本的 Spring MVC 组件并确定了目标应用,接下来我们将会阐述如何编写并测试一个基本的控制器。

    第02课:编写基本的控制器
    第03课:参数输入与表单处理
    第04课:文件上传功能实现
    第05课:使用 Spring MVC 创建 REST API
    第06课:Spring 5 中 WebFlux 的简介
    第07课:Spring WebFlux 使用详解
    第08课:Spring MVC 源码剖析——请求处理
    第09课:Spring MVC 源码剖析——数据绑定与参数转换
    第10课:WebFlux 源码剖析

    阅读全文: http://gitbook.cn/gitchat/column/5a2f3a93626a7a2421b9551c

    展开全文
  • HTML5基础教程第2版 授课教师 职务 第13章支持多线程编程Web Workers 课程描述 提到多线程大多数会想到 Visual C++Visual C#和 Java等高级程序设计语言 传统的Web应用程序都是单 线程的完成一项任务才去 执行下面...
  • 针对儿童的 ios编程开发课程探索 近日Html5 时代的Web 应用开发一书作者原 Intel 软件学院课程研发导师秦亮先 生在北京京西国际学校 WAB 开启了未来属于编程者面向青少年开发者的编程教学设计 的主题分享会系列公开...
  • 作为Java程序设计、网页设计与制作、数据库原理与应用等课程的后续课程,主要在于培养学生应用JSP技术进行Web应用程序开发的能力,并培养其良好的编程规范和职业习惯。主讲教师刘志成,副教授,系统分析师,湖南铁道...
  • 一、实验内容 练习 1 使用循环输出等腰三角形图案 ...(1) 问题:在 JavaScript 中模拟实现二维数组的功能,用于存储各个学期 的所有课程名称,请根据运行结果在 JS 中自行构建数组并输出运行 结果如图上机 1.6(当需要
  • web程序设计

    千次阅读 2017-11-01 20:01:33
    Web程序设计这门课是一个综述课程,总体介绍了web 应用用到的技术。如HTML、 CSS、JavaScript。   2.HTML HTML 是用来描述网页的一种语言。 HTML 指的是超文本标记语言 (Hyper Text Markup Language) ...
  • 实现一个简单但功能完整的商城项目,从设计到实现,规范化完成该项目,锻炼javaweb项目的编写能力,理解软件工程的软件设计思想 1.2编程技术简介 本次课程主要使用的软件有Intellij IDEA、Navicate for MySql、...
  • 专业基础能力程序设计基 专业基础能力 程序设计基础 Java 面向对象程 ...JAVA Web应用开发 软件项目开发与 管理 * 基于框架的应 用系统开发 *综合项目实战 客户端编程 *JAVA Web 应用 开发项目实训 用系统开发项目 实训
  • 课程可以从Python基础入门到网站开发实战,体系化的课程设计,全面囊括Python学习中所有技能。麻瓜编程致力于帮助初学者快速上手编程实战。图灵电子书《编程小白的第一本Python入门书》已经获得了超过20000名读者...
  • Web课程总结

    2020-06-09 21:28:04
    2019-2020-2学期《Web程序设计课程总结 1 课程知识点总结 1.1页面布局编程单元 CSS背景设置: 可以使用 background-color 属性为元素设置背景色。这个属性接受任何合法的颜色值。背景不能被继承。 图像背景: 要把...
  • 课程设计循序渐进、特色讲法、非常适合自主学习: 1、ASP.NET动态网站核心技能系统讲解。 2、教学过程贯穿实战案例,边学边用。 3、独立项目在技能学完后专门讲解,巩固前面所学全部内容! 4、所有代码和项目...
  • java课程设计

    2012-07-02 12:34:16
    课程设计是《JAVA 高级应用》课堂教学的重要组成部分,可以加深学生对课堂讲授内容的理解,提高学生对JAVA语言各部分内容特别是数据库编程和网络编程的综合使用能力,帮助学生初步掌握JAVA语言在web程序开发中的...
  • 期可以为每页日历选择背景图片以下是小编为大家整理 分享的Java课程设计实验报告欢迎阅读参考 1 加深对课堂讲授内容的理解掌握解决实际应用问 题时所应具有的查阅资料技术标准和规范以及软件编程 调试等能力掌握面向...
  • 所以现在的web前端培训课程都是按照全栈工程师的内容进行设计的,具体的学习内容如下: 阶段1.前端核心基础 HTML +_CSS核心、JavaScript基础语法、JavaScript面向对象、JavaScript DOM和BOM编程、jQuery框架 阶段...
  • 1、学会各类开发软件安装、项目导入以及项目发布,含项目源码,需求文档,配套软件等 ... 2、该项目主要功能完善,主要用于简历项目...其他素材版(毕业设计或课程设计)项目:点击老师头像进行相关课程学习
  • Java Web开发技术教学大纲课程名称JavaWeb开发技术课程编号9051019适用专业计算机科学与技术、软件工程、物联网工程课程类别专业选修课学时58(34理论/24实验)学分3考核方式考查先修课Java程序设计Web技术基础、...
  • 1、学会各类开发软件安装、项目导入以及项目发布,含项目源码,需求文档,配套软件等 ... 2、该项目主要功能完善,主要用于简历项目...其他素材版(毕业设计或课程设计)项目:点击老师头像进行相关课程学习
  • 1、学会各类开发软件安装、项目导入以及项目发布,含项目源码,需求文档,配套软件等 ... 2、该项目主要功能完善,主要用于简历项目...其他素材版(毕业设计或课程设计)项目:点击老师头像进行相关课程学习
  • 第1章 课程设计详细说明 1.1 课程设计目的 1.2 课程设计对象 1.3 课程设计内容说明 1.4 课程设计要求 1.4.1 文档要求 1.4.2 程序开发过程要求 1.4.3 程序设计代码规范 1.5 课程设计计划 1.5.1 项目计划 1.5.2 配置...
  • 该压缩包是计算机网络课程的实验——多线程Web服务器的设计与实现,里面内容很全,也有文档描述怎样操作,代码的注释很清晰,傻瓜式的,有java编程基础的一看就会

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 633
精华内容 253
关键字:

web编程设计课程设计