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();
}
Servlet培训笔记
最新推荐文章于 2013-11-15 11:21:24 发布