Servlet培训笔记

jsp两个功能:
显示:html 【擅长】
逻辑:java

servlet:
两个功能:
显示:html
逻辑:java 【擅长】

程序:jsp+servlet
1:使用向导创建第一个servlet程序:FirstServlet.java
2:解决修改java文件后tomcat不自动重启的问题
  修改tomcat下的一个配置文件:conf/context.xml,
  在context标签下加上属性:reloadable='true' //<Context reloadable="true">
3:手工创建servlet:HelloServlet.java
A:新建一个普通类:HelloServlet.java
B:继承HttpServlet.java
C:重写doGet,doPost方法
D:配置web.xml
E:编写页面:test2.jsp


7.3
-------------------
注意:在表单的提交action属性中使用绝对路径<%=request.getContextePath() %>去动态获取web应用程序名

专业的写法:
<form action="${pageContext.request.contextPath }/helloServlet"method="post">

路径:
out.print(req.getRequestURI()+"<br/>");
//  /servlet1/helloServlet
out.print(req.getServletPath()+"<br/>");
// http://localhost:8080/servlet/servlet1/helloServlet
out.print(req.getRequestURL()+"<br/>");
//  /servlet
out.print(req.getContextPath()+"<br/>");

总结:
A:servlet的url-pattern标签的配置必须以“/”开头,该路径为url中的工程名后的路径
   即web工程的webRoot后的路径
B:掌握四个获取路径的方法
C:表单提交后,action属性后使用绝对路径,以这个<%=request.getContextPath() %>开头,
   然后加上servlet路径,构成一个完整的访问路径
D:用户提交表单后到action所指定的路径去执行,默认调用servlet类中的service方法,然后
   容器(tomcat)会去根据用户是get/post请求,自动的去调用doGet/doPost方法

源码分析如下:
public void service(HttpServletRequest req,HttpServletResponse resp)
{
  //
  String method = req.getMethod();
  if("get".equals(method))
  {
     doGet(req,resp);
  }
  else if("post".equals(method))
  {
     doPost(req,resp);
  }
}

4:例子:使用servlet技术完成用户登录的逻辑
 A:编写页面:test3.jsp
 B:编写servlet:LoginServlet.java
 C:配置web.xml
 D:编写页面:test4.jsp

5:servlet的生命周期:LifeCycleServlet.java
7.4
----------
计算器程序:基于:jsp+servlet+MVC架构(简单)
逻辑:实现数据的+-*/
A:创建computer.jsp
B:创建action接口:Action.java
C:创建实现类:CalcuAction.java
D:编写控制器(servlet):Controller.java
E:配置web.xml
整个程序的运行思路:
1:单击"+"按钮,执行js脚本,提交表单
2:执行表单action属性中XX.do
3:执行控制器servlet:Controller.java,因为在web.xml中配置了执行XX.do时调用该控制器
4:第一次调用时,执行init方法初始化,在该初始化函数中将所有的业务类(action)和其相关请求
     以键值对的形式存入map集合
5:执行doGet方法
   A:获取url路径:request.getServletPath()
   B:根据字符串获取action对象:determinActionByPath
   C:执行该action的execute方法
   D:根据该execute方法的返回值(jsp页面),将其页面重定向或者转发出去

6:集成其它模块:
  A:创建页面:login.jsp
  B:编写action:LoginAction.java
  C:在控制器的init函数中将值存入map
  
7:待完善点:
  A:实现在一个action中写多个方法
  B:将控制器中初始化的内容写成可配置化。
  
7.5
-----------------
1、config.application对象如何获取web.xml文件中配置的值
	AppConfigServlet.java
2、回顾一下前面解决乱码问题
A:get请求:new String()
B:post请求:new String()  request.setCharacterEnconding("utf-8");
C:Filter过滤器 实现中文乱码问题
 	1、解决post请求
 	
3、编写字符编码过滤器:SetCharacterEncodingFilter.java
4、配置过滤器
5、扩展过滤器功能实现(get/post)
 	重新封装request对象,修正getParameter方法不支持中文的问题
 	A:通过Request对象的包装类,进行封装:RequestWrapper.java
 	
6、使用过滤器控制用户访问
如:当用户不是管理员帐号时,当其访问http://localhost:8080/servlet03/admin/index.jsp
    页面,服务器拒绝其访问
    A:编写过滤器:SecurityFilter.java
 	B:配置该过滤器

相关代码:
传参数:
<servlet>
     <servlet-name>appConfigServlet</servlet-name>
     <servlet-class>com.itany.servlet.AppConfigServlet</servlet-class>
     <init-param>
        <param-name>username</param-name>
        <param-value>张三</param-value>
     </init-param>
    
  </servlet>

	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.setContentType(CONTENT_TYPE);
		//获取config对象
		ServletConfig config=this.getServletConfig();
		String username=config.getInitParameter("username");
		PrintWriter out = resp.getWriter();
		out.print("username--->"+username);
		ServletContext application=this.getServletContext();
		String username1=application.getInitParameter("username1");
		out.print("username1---->"+username1);
	}


乱码:

public class SetCharacterEncodingFilter implements Filter{

	private String charset="";
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		//post请求
		//request.setCharacterEncoding(charset);
		//get/post
		HttpServletRequest httpReq = (HttpServletRequest)request;
		httpReq = new RequestWrapper(httpReq,charset);
		
		//出过滤器
		chain.doFilter(httpReq, response);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		charset = filterConfig.getInitParameter("charset");
	}

}


---------

public class RequestWrapper extends HttpServletRequestWrapper{
	private String charset="";
	public RequestWrapper(HttpServletRequest request) {
		// TODO Auto-generated constructor stub
		super(request);
	}
	
	public RequestWrapper(HttpServletRequest request,String charset) {
		// TODO Auto-generated constructor stub
		super(request);
		this.charset = charset;
	}
	
	@Override
	public String getParameter(String name) {
		//获取原字符串(可能是乱码)
		String oriParam=super.getParameter(name);
		//定义目标字符串(修正过后的字符串)
		String param="";
		if(oriParam!=null){
			try {
				param=new String(oriParam.getBytes("iso8859-1"),charset);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return oriParam;
			}
		}
		return param;
		
	}

}

用户控制访问:
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		HttpSession session=req.getSession();
		if("admin".equals(session.getAttribute("username"))){
			//出过滤器
			chain.doFilter(request, response);
		}
		else{
			//重定向到失效页面
			resp.sendRedirect(req.getContextPath()+"/failure.jsp");
		}
	}

自定义标签
-------
接口:Tag>IterationTag>BodyTag
实现类:TagSupport>BodyTagSupport
方法:doStartTag() doEndTag() doAfterBody()
常量:
SKIP_BODY:表示<x>…</x>之间的内容被忽略
EVAL_BODY_INCLUDE:表示标签之间的内容被正常处理
SKIP_PAGE:表示立刻停止执行网页,网页上未处理的静态内容和JSP程序均被忽略任何已有的输出内容立刻返回到客户的浏览器上
EVAL_PAGE:表示按照正常的流程继续执行后续JSP

IterationTag常量
EVAL_BODY_AGAIN:表示重复处理<x>…</x>之间的内容
BodyTag常量
EVAL_BODY_BUFFERED:Web容器会创建专门用于保存标签体内容的缓冲区,即BodyContent对象

1:实现一个简单的自定义标签
 A:创建页面case.jsp
 B:创建标签处理程序:CaseTag.java
 C:创建标签库描述文件:demo.tld,参考c.tld
 D:在web.xml文件中配额元素(可选)
 E: 在JSP文件中使用taglib指令引入标签库
 F: 使用标准格式调用自定义标签
 
 <required>false</required> //是否是必须的
 <rtexprvalue>false</rtexprvalue> //参数是否是表达式
 
 相关代码:
jsp页面:
 <w:case type="upper">welcome to My Home!</w:case><br/>
<w:case type="lower">welcome to My Home!</w:case><br/>
<w:case type="cap">welcome to My Home!</w:case><br/>
<w:case type="">welcome to My Home!</w:case><br/>
 
 web.xml
 	<!--配置自定义标签  -->
	<jsp-config>
		<taglib>
			<taglib-uri>http://www.itany.com/tag</taglib-uri>
			<taglib-location>/WEB-INF/demo.tld</taglib-location>
		</taglib>
	</jsp-config>
	
 java类:
 public class CaseTag extends BodyTagSupport
{
    private String type;
    
    public void setType(String type)
    {
        this.type = type;
    }
    
    @Override
    public int doAfterBody()
        throws JspException
    {
        //获取out对象
        JspWriter out = bodyContent.getEnclosingWriter();
        //获取标签体内容
        String str = bodyContent.getString();
        //拼接字符串<span style="text-transform:capitalize"> </span>
        String html = "<span style='text-transform:";
        if("upper".equals(type))
        {
            html+="uppercase'>";
        }
        else if("lower".equals(type))
        {
            html+="lowercase'>";
        }
        else if("cap".equals(type))
        {
            html+="capitalize'>";
        }
        else
        {
            html+="none'>";
        }
        html+=str+"</span>";
        
        try
        {
            out.print(html);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return super.doAfterBody();
    }
    
}
web-MyRecord4
----------
升级MyRecord3项目,使用技术:jsp+servlet+jdbc模板+MVC(复杂)架构
1:移植MVC框架:
   A:JAR包
   B:config对象
   C:struts.xml,rule.xml,ActionServlet.java
   D:配置web.xml
2:以下是学院员开发的代码:
  A:配置struts.xml;
   <action path="/discInfo" type="com.itany.discShop.action.DiscAction" 
   method="getDiscIndoList">
      <forward name="discInfo" path="/discInfo.jsp" redirect="false"/>
   </action>
   <action path="/orderProcess" type="com.itany.discShop.action.DiscAction" 
   method="getDiscCartList">
      <forward name="discCart" path="/discCart.jsp" redirect="true"/>
   </action>
  B:编写逻辑方法:
   DiscAction类中的getDiscIndoList方法,getDiscCartList方法
  C:编写页面:discInfo.jsp,discCart.jsp

rule.xml
----------
<?xml version="1.0" encoding="UTF-8"?>
<digester-rules>
  <pattern value="action-mappings">
     <pattern value="action">
         <object-create-rule classname="com.itany.discShop.config.ActionConfig"/>
         <set-next-rule methodname="addActionConfig"/>
         <set-properties-rule/>
	     <pattern value="forward">
	        <object-create-rule classname="com.itany.discShop.config.ForwardConfig"/>
	        <set-next-rule methodname="addForwardConfig"/>
	        <set-properties-rule/>
	     </pattern>
     </pattern>
  </pattern>
</digester-rules>

action.xml
-------------
<?xml version="1.0" encoding="UTF-8"?>
<action-mappings>
   <action path="/discInfo" type="com.itany.discShop.action.DiscAction" 
   method="getDiscIndoList">
      <forward name="discInfo" path="/discInfo.jsp" redirect="false"/>
   </action>
   <action path="/orderProcess" type="com.itany.discShop.action.DiscAction" 
   method="getDiscCartList">
      <forward name="discCart" path="/discCart.jsp" redirect="true"/>
   </action>
</action-mappings>

actionServlet.java
---------------
package com.itany.discShop.framework;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import com.itany.discShop.config.ActionConfig;
import com.itany.discShop.config.ForwardConfig;
import com.itany.discShop.config.ModuleConfig;

public class ActionServlet extends HttpServlet{

private ModuleConfig moduleConfig;
//定义存放action对象的集合
private Map<String,Object> actions = new HashMap<String, Object>(); 
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException {
	
	try {
		//1:获取表单中action的路径,如:"/hello.do",获取.do前面的字符串:"/hello"
		String path=req.getServletPath();
		path=path.substring(0,path.length()-3);
		//2:通过ModuleConfig对象的find方法找到path为/hello的ActionConfig对象
		ActionConfig actionConfig= moduleConfig.findActionConfig(path);
		//3:通过getType,getMethod方法取出相应字符串
//			System.out.println(actionConfig.getType());
//			System.out.println(actionConfig.getMethod());
		//从缓存中取该path所对应的action对象
		Object action = actions.get(path);
		if(action==null){
			//4:通过反射机制调用相应的某个方法如hello方法(重点)
			String type=actionConfig.getType();				
			action=Class.forName(type).newInstance();
			actions.put(path,action);
		}
		String method=actionConfig.getMethod();
		Method m= action.getClass().getMethod
		(method,HttpServletRequest.class,HttpServletResponse.class);
		String name=(String)m.invoke(action, req,resp);
		//5:根据该方法的返回值,调用actionConfig的find方法,找到相关的ForwardConfig对象
		ForwardConfig forwardConfig=actionConfig.findForwardConfig(name);
		String forward = forwardConfig.getPath();
		//6:根据redirect属性是true还是false,重定向或者转发path所对应的页面
		if(forwardConfig.isRedirect()){
			resp.sendRedirect(req.getContextPath()+forward);
		}
		else{
			req.getRequestDispatcher(forward).forward(req, resp);
		}
		
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	
}

/**
 * 初始化信息,将struts.xml中的数据加载到ModuleConfig对象中
 */
@Override
public void init() throws ServletException {
	//根据rule.xml文件常见创建Disgester对象
	Digester digester = DigesterLoader.createDigester(
			ActionServlet.class.getClassLoader().getResource("rule.xml"));
	//创建ModuleConfig对象
	moduleConfig = new ModuleConfig();
	//将moduleConfig压入digester栈中
	digester.push(moduleConfig);
	//根据rule.xml,将struts.xml文件中的数据填充到moduleConfig中
	try {
		digester.parse(
				ActionServlet.class.getClassLoader().getResourceAsStream("struts.xml"));
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}
----------
1:加载log4j.properties
A:定义内容输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

B:定义消息内容输出到文件
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d:/oa.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

C:设置默认哪种优先级别(以上)会输出到文件或控制台
log4j.rootLogger=warn, stdout,file
注意:默认是按照Log4j.rootLogger进行输出
如果莫个包下面的类的信息的输出优先级不同于默认,则需要单独定义。
log4j.logger.com.itany.test = warn
优先级有低到高依次为:All debug info warn error fatal off

2:编写测试类:LogTest1.java
A:使用log4j实现类
B:使用commons-logging接口(log4j是该接口的一个实现)LogTest2.java

//实现类
Logger logger = Logger.getLogger(LogTest1.class);
//commons-logging接口(建议使用)
Log logger = LogFactory.getLog(LogTest2.class);


code:
------
/**
 * 该代码主要实现2个功能 1:随机生成4个字符(0-9|a-z|A-Z) 2:将这4个字符绘制成一张图片
 * 
 * @author ccc
 * 
 */
public class CodeServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 1:随机生成4个字符(0-9|a-z|A-Z)
		Random random = new Random();
		String code = "";
		for(int i = 0; i < 4; i++) {			
			int n=random.nextInt(62);
			//n<10--->输出n:0-9
			if(n<10){
				code+=n;
			}
			//大于等于10,小于36:输出:a-z
			else if(n<36){
				code+=(char)(n-10+'a');
			}
			//大于等于36小于62---》输出:A-Z
			else{
				code+=(char)(n-36+'A');
			}			
		}
		System.out.println(code);
		//2:将这4个字符绘制成一张图片
	    HttpSession session = req.getSession();
	    session.setAttribute("code",code);
	    //创建img对象:宽度68px,高度:28px
	    BufferedImage image=  new BufferedImage
	    (68,28,BufferedImage.TYPE_INT_RGB);
	    //获取绘图所用的画笔
	    Graphics gra=image.getGraphics();
		//设置画笔的颜色
	    gra.setColor(Color.YELLOW);
	    //绘制边框
	    gra.fillRect(2, 2, 64, 24);
	    //构建一个字体
	    Font font = new Font("Courier New",Font.ITALIC|Font.BOLD,20);
	    //设置字体
	    gra.setFont(font);
	    //遍历这4个字符,依次绘制图片
	    for(int i=0;i<code.length();i++){
	    	String ch=code.substring(i,i+1);
	    	//给文字设置颜色
	    	gra.setColor(Color.black);
	    	//绘制图片
	    	gra.drawString(ch,i*16+5,18);
	    }
	    resp.setContentType("image/jpeg");
	    //获取输出流
	    OutputStream out = resp.getOutputStream();
	    //在该输出流上创建一个图像编码器
	    JPEGImageEncoder encode=JPEGCodec.createJPEGEncoder(out);
	    //将图像写入到流中
	    encode.encode(image);
	    //刷新到客户端
	    out.flush();
	    //关闭输出流
	    out.close();
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值