Showing posts with label Java Servlet. Show all posts
Showing posts with label Java Servlet. Show all posts

Thursday, December 27, 2012

Reading Note of Core Servlets and JavaServer Pages

How to deal with requests that take a long time to process?

7.4 Persistent Servlet State and Auto-Reloading Pages
To deal with requests that take a long time to process (or whose results periodically change), you need the following capabilities:

• A way to store data between requests.  For data that is not
specific to any one client, store it in a field (instance variable)
of the servlet. For data that is sp ecific to a user, store it in the
HttpSession  object (see Chapter 9, “Session Tracking”). For data
that needs to be available to other  servlets or JSP pages, store it in
the  ServletContext (see the section on sharing data in Chapter
14, “Using JavaBeans Components in JSP Documents”).

• A way to keep computations running after the response is sent 
to the user. This task is simple: just start a  Thread. The thread
started by the system to answer requests automatically finishes when
the response is finished, but other threads can keep running. The only
subtlety: set the thread priority to a low value so that you do not slow
down the server.

• A way to get the updated results to the browser when they are 
ready.  Unfortunately, because browsers do not maintain an open
connection to the server, there is  no easy way for the server to
proactively send the new results to the browser. Instead, the browser
needs to be told to ask for updates. That is the purpose of the
Refresh response header.


HTTP-Request-headers/HTTP-Response-headers


Servlet Example: Showing Request Headers

Request Method: GET
Request URI: /servlet/ShowRequestHeaders.do
Request Protocol: HTTP/1.1

Header NameHeader Value
hostlocalhost:8080
connectionkeep-alive
user-agentMozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4
accepttext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-encodinggzip,deflate,sdch //Gzip is a text compression scheme that can dramatically reduce the size of HTML

accept-languageen-US,en;q=0.8
accept-charsetISO-8859-1,utf-8;q=0.7,*;q=0.3
cookieemail=charlesxieyupeng%40gmail.com


A typical request look like

E.X.
GET /servlet/Search?keywords=servlets+jsp HTTP/1.1
Accept : image/gif, image/jpg, */*
Accept-Encoding: gzip
Connection: Keep-Alive
Cookie : userID=id456578
POST..

A typical response header


Status Code

• 100–199
Codes in the 100s are informational, indicating that the client should 
respond with some other action. 
• 200–299
Values in the 200s signify that the request was successful. 
• 300–399
Values in the 300s are used for files that have moved and usually 
include a Location  header indicating the new address. 
• 400–499
Values in the 400s indicate an error by the client
• 500–599
Codes in the 500s signify an error by the server





How to use common-beanutils.jar package

Purpose: To store Form-Data into a bean automatically, no matter what data type.
  (myeclipse - servlets project)
1. build your bean. EX: InsuranceInfo  here
2. get propertyMap request.getParameterMap()
3. BeanUtils.populate(bean, propertyMap);



public class SubmitInsuranceInfo extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    InsuranceInfo info = new InsuranceInfo(); //a bean
    BeanUtilities.populateBean(info, request);
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String docType =
      "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
      "Transitional//EN\">\n";
    String title = "Insurance Info for " + info.getName();
    out.println(docType +
                "<HTML>\n" +
                "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" +
                "<BODY BGCOLOR=\"#FDF5E6\">\n" +
                "<CENTER>\n" +
                "<H1>" + title + "</H1>\n" +
                "<UL>\n" +
                "  <LI>Employee ID: " +
                   info.getEmployeeID() + "\n" +
                "  <LI>Number of children: " +
                   info.getNumChildren() + "\n" +
                "  <LI>Married?: " +
                   info.isMarried() + "\n" +
                "</UL></CENTER></BODY></HTML>");
  }
}

-----------------

public class BeanUtilities {
  /** Examines all of the request parameters to see if
   *  any match a bean property (i.e., a setXxx method)
   *  in the object. If so, the request parameter value
   *  is passed to that method. If the method expects
   *  an int, Integer, double, Double, or any of the other
   *  primitive or wrapper types, parsing and conversion
   *  is done automatically. If the request parameter value
   *  is malformed (cannot be converted into the expected
   *  type), numeric properties are assigned zero and boolean
   *  properties are assigned false: no exception is thrown.
   */

  public static void populateBean(Object formBean,
                                  HttpServletRequest request) {
    populateBean(formBean, request.getParameterMap());
  }

  /** Populates a bean based on a Map: Map keys are the
   *  bean property names; Map values are the bean property
   *  values. Type conversion is performed automatically as
   *  described above.
   */

  public static void populateBean(Object bean,
                                  Map propertyMap) {
    try {
      BeanUtils.populate(bean, propertyMap);
    } catch(Exception e) {
      // Empty catch. The two possible exceptions are
      // java.lang.IllegalAccessException and
      // java.lang.reflect.InvocationTargetException.
      // In both cases, just skip the bean operation.
    }
  }
}


将commons-beanutil.jar导入项目

只有jar包可以导入lib并运行,zip,rar都不可以。

WEB项目的导入步骤:- lib引入包

1. 直接将jar文件拖到web-inf下的lib文件夹,Myeclipse在package explorer中会自动生成Referenced Libraries. 而WEB-INF下的lib没有显示出jar包,其实jar包确实存在web-INF/lib这个文件夹下面. 

-----------------------------------------------------------------------------------------------------------------------------------------

关于eclipse中build path与lib引入包的区别,该如何解决

关于eclipse中build path与lib引入包的区别
一个web工程需要导入jar包(比如mysql数据库驱动、struts2.0支持等等)。明明已经右键build path中引入了这些jar包,为什么编译并发布到tomcat时,这些jar包都没有被加过去。老师跟我说需要手动把这些包拷贝到工程的WebContent/WEB-INF/lib文件夹下,却没有给出一些合理的解释,自己上网谷歌、百度未果。所以希望大家能够帮忙解释下这是为什么,是不是可以通过设置使得eclipse在编译发布时自动将这些jar包带到tomcat里。

------解决方案--------------------------------------------------------
build path只不过把路径写入到classPath下面 不会吧包拷到WEB-INF/lib目录下
这种方法本机跑起来是没问题 但是移到别的机子上就会少包
而直接把包拷到WEB-INF/lib目录下面 不写classPath会项目直接就会报少包
只有这2中方法一起做才是最好的
------解决方案--------------------------------------------------------
这是编译器跟tomcat相关的问题,现在的编译器设计的时候你加入build path只是管软件的开发过程,而真正软件发布过程又是另外的过程,并不是开发过程引用到的包一定要在发布阶段用到,所以现阶段web开发部署到容器当中需要手动将包加到web-inf/lib文件夹下。
你明确一点,build path是在开发阶段,而放到tomcat下面则是软件部署。如果你的开发阶段习惯良好,是引用的自己工厂的web-inf/lib文件夹那就好很多,如果是引用其他地方的就需要手动拷贝。


java.lang.NoClassDefFoundError: org/apache/commons/beanutils

       伤心的事,调了一上午,仍然没结果,而最后的原因很吃惊。
       首先介绍一下情况:
       我得要用同事写的jar包里的某个方法,而这个方法里面有这么一句:BeanUtils.setProperty(bean, fieldName, value)。一直报错。而来没办法,直接引用源码,发现测试类不报错,但是web调用报错。即通过url访问action会报错,而写的Test.java静态引用正常。action和test的代码及配置都是一样的,唯一不同的就是一个通过服务器访问,一个直接运行。
       报错信息节选:
      java.lang.ClassNotFoundException: org.apache.commons.beanutils.BeanUtils
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1358)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204)
    at java.lang.ClassLoader.loadClassInternal(Unknown Source)
   ……
     原因找了很久,终于一个激灵,终于想起来了,追究到底还是jar的问题。
     eclipse可以手动地配置jar包路径,这样的jar包Java Application可以正常使用,但是web工程不行,tomcat服务器只认WEB-INF/lib下的jar包。之前曾经使用手工引用的jar 包,服务器根本就跑不起来,而今天讨论的这个问题确实比较隐蔽。
     解决方法相当简单:把之前手工引进的commons-beanutils.jar直接拷到WEB-INF/lib下面。
     总结,报错时,确实应该先看看环境,是不是环境配置不对,很多情况下并非代码问题,环境很重要。



Eclipse - Java Build Path

http://www.tutorialspoint.com/eclipse/eclipse_java_build_path.htm



eclipse部署时候不拷jar包到web-inf上面的lib目录解决方法

www.MyException.Cn   发布于:2012-08-31 12:55:03   浏览:51次
eclipse部署时候不拷jar包到web-inf下面的lib目录解决办法
        前段时间在做项目的时候,用eclipse构建的maven工程部署到tomcat下面去时,发现tomcat的web-inf下面的lib目录是空的,当时弄了好长时间,最后实在没辙了,就手动把所有的依赖拷到web-inf的lib下面去,但是每次重新部署时,eclipse自动部署又将lib目录清空,当时那叫一个郁闷,后来我看了下别人的classpath文件,发现我的classpath跟别人的不同点

图1:

图2:



发现在加了上述attributes;标签后,能正常的部署项目,并且tomcat lib下面也有所需的jar了。



       最近,有人问为什么我的jdbc驱动能在main方法里正常访问数据库,当我部署到tomcat下面时候,老是报ClassNotFoundException,提示找不到驱动类,远程连了一下,发现他的tomcat web-inf下面的没有mysql驱动包,但是他在工程里却是以exteneral jar的形式添加到了classpath下面,当部署时候tomcat下面却没有jar,当时第一感觉是classpath出问题了,倒腾了好长时间,最后终于解决了,先把解决方案详述如下(注:本人用的eclipse版本是eclipse jee 3.7(indigo),tomcat 6.0.29):







eclipse配置的tomcat默认发布项目不会部署到tomcat的安装目录去,而是在你的workspace目录下面的\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps这个文件夹下,这也就是为什么有人会问为什么我明明项目部署成功了,可是我去tomcat下的webapp下面却没有我刚刚发布的项目,其实休该一下配置,当然,在改之前,你的先将tomcat下面自己部署的项目删除,(tomcat自带的几个doc,root之类的不用删),双击server下的tomcat,会弹出tomcat的配置,如上图,在此,我们选择第二项





将wtpwebapps改为tomcat默认的webapps,保存,这样当你在部署项目的时候项目就会自动部署到tomcat安装目录下的webapps下面去了,现在回到发布项目时候tomcat web-inf lib目录为空的情况,右键点击工程,属性(properties),选择deployment assembly选项,单击add按钮,如下图:







在弹出的对话框选择java build path entries

next后会出现你加的external jar包







finish完成以后在启动tomcat,去webapp下面验证看看jar包是否随工程一起部署。

Tuesday, December 25, 2012

Basic Servlet Structure

1. Content Type:

  1. HTML: test/html
  2. XML:test/xml
  3. Spreatsheets: application/vnd.ms-excel
  4. JPEG:image/jpeg

Put the  setContentType line before any of the lines that use the  PrintWriter.

2. public void init()

The init method is called only when the servlet is first loaded, before the first request is processed. 
  1. redeployed servlet
  2. modify web.xml 

3. Note that the use of JavaScript for client-side validation does not remove the need for also doing this type of checking on the server. 
client side (JavaScript) <-> server side

Besides, clients can use  their own HTML forms, can manually edit URLs that contain  GET  data, and can disable JavaScript. 

4. check the empty input on server side





4.7 Automatically Populating Java Objects from Request Parameters

getParameterMap

java.util.Map<java.lang.String,java.lang.String[]> getParameterMap()
Returns a java.util.Map of the parameters of this request.Request parameters are extra information sent with the request. For HTTP servlets, parameters are contained in the query string or posted form data.
Returns:
an immutable java.util.Map containing parameter names as keys and parameter values as map values. The keys in the parameter map are of type String. The values in the parameter map are of type String array.









javax.servlet
Interface ServletResponse

javax.servlet.http
Interface HttpServletResponse

http://docs.oracle.com/javaee/5/api/javax/servlet/ServletResponse.html


Wednesday, November 21, 2012

Hibernate的学习笔记

http://my.oschina.net/larch/blog/57036

DAO, Server (Model), Controller, View


DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置。
Service层:Service层主要负责业务模块的逻辑应用设计。同样是首先设计接口,再设计其实现的类,接着再Spring的配置文件中配置其实现的关联。这样我们就可以在应用中调用Service接口来进行业务处理。Service层的业务实现,具体要调用到已定义的DAO层的接口,封装Service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性,程序显得非常简洁。
Controller层:Controller层负责具体的业务模块流程的控制,在此层里面要调用Serice层的接口来控制业务流程,控制的配置也同样是在Spring的配置文件里面进行,针对具体的业务流程,会有不同的控制器,我们具体的设计过程中可以将流程进行抽象归纳,设计出可以重复利用的子单元流程模块,这样不仅使程序结构变得清晰,也大大减少了代码量。
View层 此层与控制层结合比较紧密,需要二者结合起来协同工发。View层主要负责前台jsp页面的表示,
DAO层,Service层这两个层次都可以单独开发,互相的耦合度很低,完全可以独立进行,这样的一种模式在开发大项目的过程中尤其有优势,Controller,View层因为耦合度比较高,因而要结合在一起开发,但是也可以看作一个整体独立于前两个层进行开发。这样,在层与层之前我们只需要知道接口的定义,调用接口即可完成所需要的逻辑单元应用,一切显得非常清晰简单。
DAO设计的总体规划需要和设计的表,和实现类之间一一对应。
DAO层所定义的接口里的方法都大同小异,这是由我们在DAO层对数据库访问的操作来决定的,对数据库的操作,我们基本要用到的就是新增,更新,删除,查询等方法。因而DAO层里面基本上都应该要涵盖这些方法对应的操作。除此之外,可以定义一些自定义的特殊的对数据库访问的方法。
Service逻辑层设计
Service层是建立在DAO层之上的,建立了DAO层后才可以建立Service层,而Service层又是在Controller层之下的,因而Service层应该既调用DAO层的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的业务处理方法。
在DAO层定义的一些方法,在Service层并没有使用,那为什么还要在DAO层进行定义呢?这是由我们定义的需求逻辑所决定的。DAO层的操作 经过抽象后基本上都是通用的,因而我们在定义DAO层的时候可以将相关的方法定义完毕,这样的好处是在对Service进行扩展的时候不需要再对DAO层进行修改,提高了程序的可扩展性。

Saturday, November 10, 2012

How Servlet works


Container: Tomcat

The three big life-cycle moment


To conclude, override init( ) if you wanna connect to database or do other initialization, and then Override doGet( ) and/or doPost( ) to process request. 


Requst & response
HttpServletRequest  request
.getParameter(String s): String
.getParameterValues(String s): String[ ]
void setAttribute(String name,Object o)
getRequestDispatcher(String s): RequestDispatcher


HttpServletResponse  response
setContentTyoe( )
getOutputStream( )
getWriter( )

MIME:
Multipurpose Internet Mail Extensions (MIME) is an Internet standard that extends the format of email to support.



Two choices fro output: 
characters or bytes


Thursday, November 8, 2012

MVC & J2EE

  • Model- View - Controller
With MVC the business logic is not only separate from the presentation... it doesn't even know what is a presentation.


MVC takes the business logic out of the servlet, and puts it in a "Model" - a reusable plain old Java class. The Model is a combination of the business data (like the state of a Shopping Cart) and the methods (rules) that operate on that data. 


How J2EE fits into this?

A fully-compliant J2EE application server must have both a web Container and an EJB Container.
Tomcat is just a web Container!
EJB: Enterprise JavaBeans


Apache: HTTP Web Server
Tomcat: Web Container

  • Use a DD (Deployment Descriptor) to Invoke a Servlet
Servlet Name: HelloWorldServlet.java
To invoke a servlet directly (EX: http://localhost:8080/FirstServlet/HelloWorldServlet), you have to add the following code into Apache-Tomcat/conf/web.xml
<servlet-mapping>
        <servlet-name>invoker</servlet-name>
        <url-pattern>/servlet/*</url-pattern>
</servlet-mapping>

But this is not safe, user know you file name if so.
The much better way of invoking a servlet is by providing an explicit mapping for it. This is accomplished by using a pair of tags in your web application's web.xml file. This is not the same file as mentioned above. This web.xml file (which you will probably need to create) will reside in your web-application's WEB-INF/ directory. For each servlet you want to call, provide a pair of tags like the following:
This XML file is the Deployment Descriptor
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  id="WebApp_ID" version="3.0">
<display-name>FirstServlet</display-name>
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>com.theopentutorials.servlets.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern> 
</servlet-mapping>
</web-app>

Order of elements in web.xml is very important. So when you go to create your second 'couplet', make sure all your <servlet> tags are declared before your <servlet-mapping> tags. 



Sunday, November 4, 2012

Java Web Server


How Java Web Servers Work


Servlet Overview

Servlets and the Servlet Container

Unlike a Java client program, a servlet has no static main() method. Therefore, a servlet must execute under the control of an external container.
Servlet containers, sometimes referred to as servlet engines, execute and manage servlets.

Monday, October 29, 2012

What does it mean to flush a socket?

There's a certain amount of overhead involved in writing to a network socket and sending data. If data were sent every time byte entered the socket, you'd end up with 40+ bytes of TCP header for every byte of actual data. (Assuming you're using a TCP socket, of course. Other sockets will have different values). In order to avoid such inefficiency, the socket maintains a local buffer, which is usually somewhat over 1000 bytes. When that buffer is filled, a header is wrapped around the data and the packet is sent off to its destination.
In many cases, you don't need each packet to be sent immediately; if you're transferring a file, early data may not be of any use without the final data of the file, so this works well. If you need to force data to be sent immediately, however, flushing the buffer will send any data which has not yet been sent.
Note that when you close a socket, it automatically flushes any remaning data, so there's no need to flush before you close.

your source code is correct and it IS working! think about a buffer like a toilet. only when the toilet is filled with water does flushing it have any impact. 

System.out.println("Enter your choice") automatically flushes the buffer. the "ln" of that method empties the toilet.. 

EX:

double radius = Double.parseDouble(jtf.getText().trim());
toServer.writeDouble(radius);
toServer.flush();//its size is not full a package size yet, but flush it immediately