Servlet培训笔记

来源:互联网 发布:财务审批流程软件 编辑:程序博客网 时间:2024/05/20 11:26
jsp两个功能:显示:html 【擅长】逻辑:javaservlet:两个功能:显示:html逻辑:java 【擅长】程序:jsp+servlet1:使用向导创建第一个servlet程序:FirstServlet.java2:解决修改java文件后tomcat不自动重启的问题  修改tomcat下的一个配置文件:conf/context.xml,  在context标签下加上属性:reloadable='true' //<Context reloadable="true">3:手工创建servlet:HelloServlet.javaA:新建一个普通类:HelloServlet.javaB:继承HttpServlet.javaC:重写doGet,doPost方法D:配置web.xmlE:编写页面:test2.jsp7.3-------------------注意:在表单的提交action属性中使用绝对路径<%=request.getContextePath() %>去动态获取web应用程序名专业的写法:<form action="${pageContext.request.contextPath }/helloServlet"method="post">路径:out.print(req.getRequestURI()+"<br/>");//  /servlet1/helloServletout.print(req.getServletPath()+"<br/>");// http://localhost:8080/servlet/servlet1/helloServletout.print(req.getRequestURL()+"<br/>");//  /servletout.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.jsp5:servlet的生命周期:LifeCycleServlet.java7.4----------计算器程序:基于:jsp+servlet+MVC架构(简单)逻辑:实现数据的+-*/A:创建computer.jspB:创建action接口:Action.javaC:创建实现类:CalcuAction.javaD:编写控制器(servlet):Controller.javaE:配置web.xml整个程序的运行思路:1:单击"+"按钮,执行js脚本,提交表单2:执行表单action属性中XX.do3:执行控制器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.java2、回顾一下前面解决乱码问题A:get请求:new String()B:post请求:new String()  request.setCharacterEnconding("utf-8");C:Filter过滤器 实现中文乱码问题 1、解决post请求 3、编写字符编码过滤器:SetCharacterEncodingFilter.java4、配置过滤器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="";@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {// TODO Auto-generated method stub//post请求//request.setCharacterEncoding(charset);//get/postHttpServletRequest httpReq = (HttpServletRequest)request;httpReq = new RequestWrapper(httpReq,charset);//出过滤器chain.doFilter(httpReq, response);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// TODO Auto-generated method stubcharset = filterConfig.getInitParameter("charset");}}---------public class RequestWrapper extends HttpServletRequestWrapper{private String charset="";public RequestWrapper(HttpServletRequest request) {// TODO Auto-generated constructor stubsuper(request);}public RequestWrapper(HttpServletRequest request,String charset) {// TODO Auto-generated constructor stubsuper(request);this.charset = charset;}@Overridepublic 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 blocke.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:表示按照正常的流程继续执行后续JSPIterationTag常量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.xml2:以下是学院员开发的代码:  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.jsprule.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>(); @Overrideprotected 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 blocke.printStackTrace();} }/** * 初始化信息,将struts.xml中的数据加载到ModuleConfig对象中 */@Overridepublic 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 blocke.printStackTrace();}}}----------1:加载log4j.propertiesA:定义内容输出到控制台log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%nB:定义消息内容输出到文件log4j.appender.file=org.apache.log4j.FileAppenderlog4j.appender.file.File=d:/oa.loglog4j.appender.file.layout=org.apache.log4j.PatternLayoutlog4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%nC:设置默认哪种优先级别(以上)会输出到文件或控制台log4j.rootLogger=warn, stdout,file注意:默认是按照Log4j.rootLogger进行输出如果莫个包下面的类的信息的输出优先级不同于默认,则需要单独定义。log4j.logger.com.itany.test = warn优先级有低到高依次为:All debug info warn error fatal off2:编写测试类:LogTest1.javaA:使用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 {@Overrideprotected 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-9if(n<10){code+=n;}//大于等于10,小于36:输出:a-zelse if(n<36){code+=(char)(n-10+'a');}//大于等于36小于62---》输出:A-Zelse{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();}

原创粉丝点击