javaee(servlet)

来源:互联网 发布:成都学软件开发 编辑:程序博客网 时间:2024/06/09 19:46

 1.编码和解码

当内存中的数字被解释为字符(文字和符号)时,就是解码过程,把文字和符号用数字定义时就是编码。

        //服务器默认编码为ISO8859-1,它不支持中文,tomcat规定的        //resp.setCharacterEncoding("UTF-8");//指定对服务器响应进行重新编码的编码        //指定对服务器响应进行响应头的设置,告诉浏览器响应头的字符集格式是UTF-8。        //resp.setHeader("Content-Type","text/html;charset=utf-8");        //指定对服务器响应进行重新编码的编码,和告诉浏览器响应字符集格式是UTF-8。        resp.setContentType("text/html;charset=UTF-8");        ServletOutputStream outputStream = resp.getOutputStream();        outputStream.write("哈哈".getBytes("utf-8"));//默认采用本地编码gbk        PrintWriter writer = resp.getWriter();        writer.write("你好");

2.文件下载

文件名的编码问题,和设置响应头为下载

//通过路径得到一个输入流        String path = this.getServletContext().getRealPath("/WEB-INF/classes/05.jpg");        FileInputStream fis=new FileInputStream(path);        //创建输出流,输出浏览器        ServletOutputStream outputStream = resp.getOutputStream();        //得到要下载的文件名        String substring = path.substring(path.lastIndexOf("\\") + 1);        System.out.println(substring);        //设置文件名编码        URLEncoder.encode(substring,"UTF-8");        resp.setHeader("content-disposition","attachment;filename="+substring);        //执行输出        int len=0;        byte[] b=new byte[1024];        while((len=(fis.read(b)))!=-1){            outputStream.write(b,0,len);        }

3.验证码

设置验证码图片

@WebServlet(urlPatterns = "/demo3")public class ServletDemo3 extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        int width=110;        int height=25;        //在内存中创建一个图像对象        BufferedImage img=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);        //创建一个画笔        Graphics g=img.getGraphics();        //给图片添加背景色        g.setColor(Color.GREEN);        //xy为坐标,windth和height为高宽        g.fillRect(1,1,width-2,height-2);        //设置文本样式        g.setColor(Color.BLACK);        g.setFont(new Font("宋体",Font.BOLD,17));        //给图片添加文本        Random rand=new Random();        int position=20;        for (int i=0;i<4;i++){            g.drawString(rand.nextInt(10)+"",position,20);            position+=20;        }        //加上干扰线        for (int i=0;i<9;i++){            g.drawLine(rand.nextInt(width),rand.nextInt(height),rand.nextInt(width),rand.nextInt(height));        }        //将图片对象以流的方式输出客户端        ImageIO.write(img,"jpg",resp.getOutputStream());    }}
jsp页面
<script type="text/javascript">  function changeCode(){      var img=document.getElementsByTagName('img')[0];      //解决缓存问题      img.src="${pageContext.request.contextPath}/demo3?time="+new Date().getTime();  }</script><html>  <head>    <title>$Title$</title>  </head>  <body>  <form>    验证码:<input type="text"><img src="${pageContext.request.contextPath}/demo3">    <a href="javascript:changeCode()">看不清换一张</a>  </form>  </body></html>
可以使用工具类实现验证码,需要引入ValidateCode.jar

刷新并且跳转网页

resp.setIntHeader("refresh",1);//1秒刷新页面
resp.setHeader("refresh","3;url="xxxxx");//设置3秒跳转xxxxx页面

转发和重定向

转发:浏览器地址不变,可以带request和response

重定向:浏览器地址会变,并且不能带request和response

基础(理解302是重定向,location是转换地址)

@WebServlet(urlPatterns = "/demo4")public class ServletDemo4 extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        resp.setStatus(302);//响应码302,告诉浏览器是重定向        //重定向的位置        resp.setHeader("location","http://write.blog.csdn.net/");    }}
进阶(此方法是对上面的代码进行封装,所以无非封装的都是响应头,响应行,响应消息体,而已,以后在别的语言没有sendRedirect方法,我们也知道怎么创造轮子)

resp.sendRedirect("url");

判断不同浏览器

@WebServlet(urlPatterns = "/demo5")public class ServletDemo5 extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String header = req.getHeader("User-Agent");        System.out.println(header);        if(header.toLowerCase().contains("msie")){            System.out.println("你使用的是IE浏览器");        }else if(header.toLowerCase().contains("firefox")){            System.out.println("你使用的是火狐浏览器");        }else if(header.toLowerCase().contains("chrome")){            System.out.println("你使用谷歌浏览器");        }    }}

解决请求参数乱码问题

post 乱码问题

req.setCharacterEncoding("utf-8"); //设置请求编码格式 注:浏览器使用什么编码传过来就是什么编码

get乱码问题

String name=new String(name.getBytes("ISO-8859-1"),"UTF-8");



内省(Introspector) JavaBean

基础:开发框架时,经常需要使用java对象的属性来封装数据,每次用反射技术过于麻烦,所以sun公司提供了一套api,专门操作java对象的属性。

 public static void main(String[] args) throws IntrospectionException, InvocationTargetException, IllegalAccessException {        //创建Student对象        Student s=new Student();        //获取Student类中的name属性        PropertyDescriptor pd=new PropertyDescriptor("name",Student.class);        Method writeMethod = pd.getWriteMethod();        Method readMethod = pd.getReadMethod();        //设置s对象中name属性为小明        writeMethod.invoke(s,"小明");        //获取s对象中name的属性值        System.out.println(readMethod.invoke(s, null));    }

高级:使用内省对request的请求参数进行封装(前提,实体类和请求参数name一致!)

      Map<String, String[]> map = req.getParameterMap();        Student s=new Student();        for (Map.Entry<String,String[]> m:map.entrySet()) {            String key = m.getKey();            String[] value = m.getValue();            try {                //获取当前Student中表单对应的key对应的Student的属性                PropertyDescriptor descriptor = new PropertyDescriptor(key, Student.class);                //创建属性描述器                if(value.length==1){                    writeMethod.invoke(s,value[0]);//给一个值的变量赋值                }else{                    writeMethod.invoke(s,(Object) value);//多个值的变量赋值(如复选框)                }            } catch (IntrospectionException e) {                e.printStackTrace();            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            }        }

终极:使用commons-beanutils.jar对属性进行封装,使用前提还需要commons-logging.jar日志架包

   Map<String, String[]> map = req.getParameterMap();        Student s=new Student();        for (Map.Entry<String,String[]> m:map.entrySet()) {            String key = m.getKey();            String[] value = m.getValue();            try {                //使用beanUtiles框架的好处就是一步到位,简单                BeanUtils.populate(s,map);            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            }

请求包含

forward()方法

    • forward()方法的处理流程如下:(1)清空用于存放响应正文数据的缓冲区;(2)如果目标组件为Servlet或JSP,就调用它们的service()方法,把该方法产生的响应结果发送到客户端,如果目标组件为文件系统中的静态html文档,就读去文档中的数据并把它发送到客户端。
    • 由于forward()方法先清空用于存放响应正文数据的缓冲区,因此servlet源组件生成的响应结果不会被发送到客户端,只有目标组件生成的结果才会被发送到客户端;
    • 如果源组件在进行请求转发之前,已经提交了响应结果(例如调用了flushBuffer方法,或者close()方法),那么forward()方法会抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果。

  • include()方法
  • 源主键与被包含的组件输出的数据都将添加响应结果中
  • 在目标组件中对响应状态代码或者响应头所做的修改都会被忽略










原创粉丝点击