如若您想付出三个利用

图片 1

Servlet: 当然,在servlet中,一般跳转都发生在doGet, doPost等方法里面。
1) redirect 方式 response.sendRedirect(“/a.jsp”);
页面的路径是相对路径。sendRedirect可以将页面跳转到任何页面,不一定局限于本web应用中,如:
response.sendRedirect(“http://www.ycul.com”);
跳转后浏览器地址栏变化。这种方式要传值出去的话,只能在url中带parameter或者放在session中,无法使用request.setAttribute来传递。

人如果没有梦想,那么和一只咸鱼有什么分别。作为一个程序员,哪怕我们不能改变世界,也会有让更多的,更多的人使用我们应用的梦想。那么现在回到我们的jTodos应用,我们当然会想要更多的人使用我们的应用。假设现在,如果有多个人使用我们的应用会是什么情况呢?

  1. forward方式 RequestDispatcher dispatcher =
    request.getRequestDispatcher(“/a.jsp”); dispatcher .forward(request,
    response);
    页面的路径是相对路径。forward方式只能跳转到本web应用中的页面上。
    跳转后浏览器地址栏不会变化。
    使用这种方式跳转,传值可以使用三种方法:url中带parameter,session,request.setAttribute

首先我们使用两个浏览器来模拟多用户测试,首先在一个浏览器内输入张三–下午三点钟看书。

1.从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

2.从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.redirect:不能共享数据.

3.从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.

4.从效率来说
forward:高.
地址栏不变,客户端服务器交互2次,可以读到前一个页面里request里存的值
redirect:低.

地址栏改变,客户端服务器交互4次,读不到前一个页面里request里存的值

这里我们要首先清理数据库,不能让历史上的垃圾数据干扰现在的操作这样做既不方便又容易出错,更好的方法是使用单元测试技术并创立一个测试库,每次进行测试的时候都进行一次初始化,现在暂时采用手动方式清理数据。

然后假设另一个使用另一个浏览器(在jsp中一个会话即为一个浏览器的打开到关闭,即可以用不同的浏览器来模拟不同的用户)进入这个页面
“哇偶 张三是谁,他在下我三点看书管我啥事”

这时候,想想我们想要实现的功能,最后在pc操作系统的左上角弄个便签记录一下:

  1. 每个用户都有自己的todo列表
  2. 各个用户的todo列表不能互相干扰
  3. 每个用户可以方便的访问自己的列表

现在要想想怎么实现这个功能了。

软件的开发不同于建设一个建筑,比如盖一栋大楼之类的,虽然他们通常这样的类比。软件的开发过程中总是充斥中不停的变化,变化如此之频繁,以至于很可能你的需求分析,基本设计刚刚出炉,就已经过时。

但是,注意,这里强调一下,并不是说要完全放弃分析和设计,有时候不经思考的反复试错,穷举方式,可能也可以找到答案,但适当的思考可以达到事半功倍的效果,关于现在,我们就所需要的功能来思考一下:

  • 每一个todo都与用户相关联
  • 每个用户都能保存自己的清单(目前来说不考虑清单分组,即至少能保存一个清单)
  • 用户要方便的找到自己的列表,以便多次访问
  • ……

头脑风暴一经展开,貌似就再也停不下了。这时候我们会有各种各样的想法,比如,为每个用户来一个炫目的登录页面,每个todo是不是要加一个标题和内容?是不是要给清单进行分组,给每个分组增加一个说明?等等,一旦发生这种情况,我们就要注意了,这种蔓延会一发不可收拾,这时,要牢记敏捷开发的一个信条:YAGNI,他是You
aint gonna need
it的首字母,意思就是你不需要他!!作为一个软件开发者,要知道很多项目失败的原因之一就是开始的计划过于宏大了,有个能工作的简陋的应用,总比一个超炫但不能工作的应用强,所以,就现在这个应用目前来说,经过削繁就简后,决定用下面的方式实现:

  • 用户信息很简单,只有一个用户名和id
  • 将用户名嵌入到url中,已进行区分
  • todo与用户id进行关联

接下来就要想这个实现所需的技术了。

jsp很灵活方便,但在页面嵌入代码这是一个硬伤,他不容易开发,测试,尤其是进行复杂的逻辑时,更需要在代码中进行结构化的开发。老规矩,首先进行一个hello
world进行一下测试。

首先还是需要引入所需的包,在pom.xml添加节点:

<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope></dependency>

注意这里多了一个scope节点,在maven中,这个节点可以有四个值,分别为:1
compile 默认值,适用所有阶段,并会随项目一起发布2 provided
与compile类似,但不发布,由容器会提供此库3 runtime 只在运行时适用4
test 只在测试时使用
如junit包这里tomcat会提供servlet库,所以使用provided选项

既然是代码文件,就要放到一个包中,首先创建servlet包:com.niufennan.jtodos.servlet,并创建TodoServlet,然后让其继承HttpServlet
,一个最简的servlet类就完成了。

在servlet中,需要覆盖实现doGet方法完成get操作,doPost方法完成Post操作,这里只是为了展示一下helloworld,所以最终代码如下:

@WebServletpublic class TodoServlet extends HttpServlet{ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); out.println("hello world"); }}

Servlet
3.0版本中提供了WebServlet注解,可以以注解方式提供url,从而避免了在web.xml中又臭又长的xml配置

让我们看看浏览器的源代码发送了什么:

图片 2image

换句话说,也就是PrintWriter打印出什么,就像客户端发送什么,那么如果想输出html怎么办呢?很简单,打印html即可:

 PrintWriter out = response.getWriter(); out.println("<b>hello world<b>");

这样,就可以让浏览器将hello world 加粗

可以看到,servlet与jsp很相似,连对象名都是同样的request和response,那么他们之间有什么关系呢?答案很简单,jsp是servlet的进化版,如果说servlet是妙蛙种子,那么jsp就是妙蛙草妙蛙花(仅仅是形态,不代表能力),在tomcat根目录下的workCatalinalocalhostROOTorgapachejsp目录中的文件,可以看到他们关系的证据:

图片 3image

这个是index.jsp生成的文件,其中index_jsp.java中的部分代码为:

 List<Todo> todos=todoDao.getAll(); pageContext.setAttribute("todos",todos); out.write; out.write("<div class="ui two column centered relaxed grid">rn"); out.write(" <div class="column row"></div>rn"); out.write(" <div class="column ">rn"); out.write(" <h2 class="ui huge header center violet aligned">jTodos!</h2>rn"); out.write(" <div class="ui raised segment">rn"); out.write(" <form action="index.jsp" method="post" class="ui fluid action input">rn"); out.write(" <input type="text" name="todo" placeholder="请输入一个备忘录项目">rn"); out.write(" <button type="submit" class="ui button">OK</button>rn"); out.write(" </form>rn"); out.write(" <div class="ui aligned huge selection divided list">rn"); out.write; if (_jspx_meth_c_005fforEach_005f0(_jspx_page_context)) return; out.write; out.write(" </div>rn"); out.write(" </div>rn"); out.write(" </div>rn"); out.write("</div>rn"); out.write; out.write("<script src="https://cdn.bootcss.com/semantic-ui/2.2.13/semantic.min.js"></script>rn"); out.write("</body>rn"); out.write("</html>rn");

很明显,就是把jsp内的html进行格式化输出,其中_jspx_meth_c_005fforEach_005f0是另一个方法,方法体内循环输出todos的各项。

也就是说,jsp把繁琐易错的字符串拼接处理进行了封装,由系统自己处理

这样就解释了为什么jsp页面第一次访问会慢一些,以为最开始的时候要生成.java文件,并且编译为.class文件。

你可能很奇怪,嘀嘀咕咕的讲了一大堆,和我们的需求有什么关系?这是因为servlet有一项非常重要的功能,就是可以使用通配符,进行动态的url创建。举个例子,下面修改WebServlet注解的参数@WebServlet("/todos/*"),其中*就表示通配符,运行起来在浏览器中输入地址:

http://localhost:8080/todos/zhangsanhttp://localhost:8080/todos/lisihttp://localhost:8080/todos/aaahttp://localhost:8080/todos/nihaohttp://localhost:8080/todos/hello

发表评论

电子邮件地址不会被公开。 必填项已用*标注