package pmcse.server;
public interface Servlet {
void service(Request req,Response response);
// void doGet(Request req,Response response);
// void doPost(Request req,Response response);
}
package pmcse.server;
import java.util.Date;
//LoginServlet
public class LoginServlet implements Servlet {
@Override
public void service(Request req, Response response) {
response.print("<html>");
response.print("<head>");
response.print("<title>");
response.print("服务器相应成功");
response.print("</title>");
response.print("</head>");
response.print("<body>");
Date time=new Date();
response.print("欢迎回来:"+time+" "+req.getParameter("name"));
response.print("</body>");
response.print("</html>");
}
}
package pmcse.server;
public class RegisterServlet implements Servlet {
@Override
public void service(Request req, Response response) {
response.print("注册成功");
}
}
package pmcse.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 封装请求协议:封装请求参数为Map
* @author pmc
*
*/
public class Request {
//协议信息
private String requestInfo;
//请求方式
private String method;
//请求url
private String url;
//请求参数
private String queryStr;
//存储参数
private Map<String,List<String>> parameterMap;
//换行符
private final String CRLF="\r\n";
public Request(Socket client) throws IOException{
this(client.getInputStream());
}
public Request(InputStream is){
this.parameterMap=new HashMap<String,List<String>>();
byte[] datas=new byte[1024*1024];
int len;
try {
len = is.read(datas);
this.requestInfo=new String(datas,0,len);
} catch (IOException e) {
e.printStackTrace();
return;
}
//分解字符串
this.paresRequestInfo();
}
private void paresRequestInfo(){
System.out.println(requestInfo);
System.out.println("-------1.请求方式:开头到第一个/-------");
//substring截取字符串从0到"/",tolowerCase转为小写
this.method=this.requestInfo.substring(0,this.requestInfo.indexOf("/")).toLowerCase().trim();
System.out.println(method);
System.out.println("-------2.获取url:第一个/到HTTP/-------");
System.out.println("-------可能包含请求参数?前面的url-------");
//1.获取第一个/
int startidx=this.requestInfo.indexOf("/")+1;
//2.获取HTTP/的位置
int endidx=this.requestInfo.indexOf("HTTP/");
//3.分割字符串
this.url=this.requestInfo.substring(startidx,endidx);
//4.获取?的位置
int queridx=this.url.indexOf("?");
System.out.println(queridx);
if(queridx>=0){//存在请求参数
String[] urlArray=this.url.split("\\?");
this.url=urlArray[0];
queryStr=urlArray[1];
}
System.out.println(this.url);
System.out.println(this.queryStr);
System.out.println("-------3.获取请求参数:如果是GET已经获取,如果是POST可能在请求体中-------");
if(method.equals("post")){
String qStr=this.requestInfo.substring(this.requestInfo.lastIndexOf(CRLF)).trim();
if(null==queryStr){
queryStr=qStr;
}else{
queryStr=queryStr.trim();
queryStr+="&"+qStr;
}
}
System.out.println(method+"-->"+url.trim()+"-->"+queryStr);
//转成Map fav=1&fav=2&name=123&age18
this.convertMap();
}
//处理请求参数为Map
private void convertMap(){
//1.分割字符串
String[] keyValues=this.queryStr.split("&");
for(String temp:keyValues){
try {
System.out.println(decode(temp,"GBK"));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//2.在此分割字符串"="
String[] k=temp.split("=");
k=Arrays.copyOf(k, 2);//最后一个保证是2个长度
//获取key和alue
String key=k[0];
String value;
try {
value = k[1]==null?null:decode(k[1], "GBK");
//存储到Map中
if(!parameterMap.containsKey(key)){//containsKey是否存在,不存在则创建
parameterMap.put(key, new ArrayList<String>());
}
parameterMap.get(key).add(value);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
/**
* 处理中文
* java.net.URLDecoder.decode
* @return
* @throws UnsupportedEncodingException
*/
private String decode(String value,String enc) throws UnsupportedEncodingException{
return java.net.URLDecoder.decode(value, enc);
}
/**
* 通过name获取对应的多个值
* @param key
* @return
*/
public String[] getParameterValues(String key){
List<String> list=this.parameterMap.get(key);
if(null==list||list.size()<1){
return null;
}
return list.toArray(new String[0]);
}
public String getParameter(String key){
String[] values=getParameterValues(key);
return values==null?null:values[0];
}
public String getMethod() {
return method;
}
public String getUrl() {
return url;
}
public String getQueryStr() {
return queryStr;
}
}
package pmcse.server;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;
public class Response {
//写
private BufferedWriter bw;
//正文
private StringBuilder content;
//协议头信息(状态行与请求头、回车)
private StringBuilder headInfo;
private int len;//正文的字节数
private final String BLANK="";
private final String CRLF="\r\n";
private Response(){
content=new StringBuilder();
headInfo=new StringBuilder();
len=0;
}
public Response(Socket client){
this();
try {
this.bw=new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
headInfo=null;
}
}
// public Response(OutputStream os){
// this();
// this.bw=new BufferedWriter(new OutputStreamWriter(os));
// }
//动态添加内容
public Response print(String info){
content.append(info);
len+=info.getBytes().length;
return this;
}
public Response println(String info){
content.append(info).append(CRLF);
len+=(info+CRLF).getBytes().length;
return this;
}
//推送响应头信息
public void pushToBrowser(int code) throws IOException{
if(null==headInfo){
code=505;
}
createHeadInfo(code);//头信息
bw.append(headInfo);
bw.append(content);
bw.flush();
}
//构建头信息
private void createHeadInfo(int code){
//1.响应行:HTTP/1.1 200 OK
headInfo.append("HTTP/1.1").append(BLANK);
headInfo.append(code).append(BLANK);
switch(code){
case 200:
headInfo.append("OK").append(CRLF);
break;
case 404:
headInfo.append("NOT FOUND").append(CRLF);
break;
case 505:
headInfo.append("SERVER ERROR ").append(CRLF);
break;
}
//响应头最后一行有空行
headInfo.append("Date:").append(new Date()).append(CRLF);
headInfo.append("Server:").append("shsxt Server/0.0.1;charset=GBK").append(CRLF);
headInfo.append("Content-type:text/html").append(CRLF);
headInfo.append("Content-length:").append(len).append(CRLF);
headInfo.append(CRLF);
}
}
package pmcse.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
* 目标:加入了Servlet解耦了业务代码
*
* @author pmc
*
*/
public class Server06 {
private ServerSocket serverSocket;
public static void main(String[] args) {
System.out.println("启动服务");
Server06 server=new Server06();
server.start();
}
// 启动服务
public void start() {
try {
serverSocket=new ServerSocket(8889);
receive();
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
//接受连接处理
public void receive() {
try {
Socket client=serverSocket.accept();
System.out.println("一个客户端建立连接");
//获取请求协议
Request req=new Request(client);
//获取响应协议
Response response=new Response(client);
Servlet ls= null;
if(req.getUrl().equals("login")){
ls=new LoginServlet();
}else if(req.getUrl().equals("reg")){
ls=new RegisterServlet();
}else{
}
ls.service(req, response);
//关注了状态码
response.pushToBrowser(200);
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端错误");
}
}
//停止服务
public void stop() {
}
}