package pk2;
public class LoginServlet implements Servlet{
@Override
public void service(Request request,Response response) {
response.print("<html>");
response.print("<haed>");
response.print("<title>");
response.print("服务器响应成功");
response.print("</title>");
response.print("</haed>");
response.print("<body>");
response.print("登录成功,欢迎回来2020 "+request.getParameter("name")+request.getParameter("pwd"));
response.print("<form method=\"get\" action=\"http://localhost:8889\">用户名:<input type=\"text\" name=\"name\" id=\"uname\"/>密码:<input type=\"password\" name=\"pwd\" id=\"pwd\"/><input type=\"submit\" value=\"GET\"/></form>");
response.print("<br>");
response.print("<form method=\"post\" action=\"http://localhost:8889?aaabbb=ccc\">用户名:<input type=\"text\" name=\"name\" id=\"uname\"/>密码:<input type=\"password\" name=\"pwd\" id=\"pwd\"/><input type=\"submit\" value=\"POST\"/></form>");
response.print("</body>");
response.print("</html>");
}
}
package pk2;
public class RegisterServlet implements Servlet{
@Override
public void service(Request request,Response response) {
response.print("<html>");
response.print("<haed>");
response.print("<title>");
response.print("服务器响应成功");
response.print("</title>");
response.print("</haed>");
response.print("<body>");
response.print("注册成功,欢迎回来2020 "+request.getParameter("name")+request.getParameter("pwd"));
response.print("<form method=\"get\" action=\"http://localhost:8889\">用户名:<input type=\"text\" name=\"name\" id=\"uname\"/>密码:<input type=\"password\" name=\"pwd\" id=\"pwd\"/><input type=\"submit\" value=\"GET\"/></form>");
response.print("<br>");
response.print("<form method=\"post\" action=\"http://localhost:8889?aaabbb=ccc\">用户名:<input type=\"text\" name=\"name\" id=\"uname\"/>密码:<input type=\"password\" name=\"pwd\" id=\"pwd\"/><input type=\"submit\" value=\"POST\"/></form>");
response.print("</body>");
response.print("</html>");
}
}
package pk2;
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 String CRLF="\r\n";
public Request(Socket client) throws IOException {
this(client.getInputStream());
}
public Request(InputStream in) {
parameterMap=new HashMap<String,List<String>>();
byte[] datas = new byte[1024 * 1024];
int len;
try {
len = in.read(datas);
requestinfo = new String(datas, 0, len);
} catch (IOException e) {
e.printStackTrace();
return;
}
//分解字符串
parseRequestinfo();
}
private void parseRequestinfo(){
System.out.println("分解开始");
System.out.println(requestinfo);
System.out.println("1.获取请求方式:开头到第一个/");
//GET、POST
this.method=this.requestinfo.substring(0,this.requestinfo.indexOf("/")).toLowerCase();
this.method=this.method.trim();
System.out.println("2.获取请求url:第一个/到HTTP/,可能包含请求参数?前面的url");
//1.获取/的位置
int startidx=this.requestinfo.indexOf("/")+1;//不要/+1
//2.获取HTTP/的位置
int endidx=this.requestinfo.indexOf("HTTP/");//不要/+1
//3.分割字符串
//URL
this.url=this.requestinfo.substring(startidx, endidx);
//4.获取?的位置
//queryStr请求参数
int queryidx=this.url.indexOf("?");
if(queryidx>=0){
String[] str=this.url.split("\\?");//需要转义\\
this.url=str[0];
this.queryStr=decode(str[1], "GBK");
}
System.out.println("3.获取请求参数:如果GET已经获取,如果是POST可能在请求体中");
if(method.equals("post")){
// System.out.println(queryStr);
String qStr = this.requestinfo.substring(this.requestinfo.lastIndexOf(CRLF)).trim();
if(queryStr==null){
queryStr=qStr;
}else{
queryStr+="&"+qStr;//地址栏有参数+表单参数
}
}
queryStr=null==queryStr?"":queryStr;
System.out.println("method:"+method+"-->"+"url:"+url+"-->"+"queryStr:"+queryStr);
//转成Map name=1&pwd=2
convertMap();
}
//处理请求参数为Map
private void convertMap(){
//1.'&'分割字符串
String[] keyValues=this.queryStr.split("&");
for(String temp:keyValues){
//2.'='分割字符串
String[] kv=temp.split("=");
kv=Arrays.copyOf(kv, 2);
//获取key和value
String key=kv[0];
String value=kv[1]==null?null:decode(kv[1],"GBK");
//存储到map中
if(!parameterMap.containsKey(key)){
parameterMap.put(key, new ArrayList<String>());
}
parameterMap.get(key).add(value);
}
}
//处理中文
private String decode(String value,String Unicode){
try {
return java.net.URLDecoder.decode(value,Unicode);//Unicode 指定字符集
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
//通过name获取对应的多个值
public String[] getParameterValues(String key){
List<String> list=this.parameterMap.get(key);
if(list==null||list.size()<1){
return null;
}
return list.toArray(new String[0]);
}
//通过name获取对应的一个值
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 pk2;
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 {
bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
headinfo = null;
}
}
public Response(OutputStream out) {
bw = new BufferedWriter(new OutputStreamWriter(out));
}
// 动态添加内容
public Response print(String info) {
// 3.正文
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;
}
// 构建头信息
private void createHeadInfo(int code) {
// 1.响应行
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;
}
// 2.响应头
headinfo.append("Date:").append(new Date()).append(CRLF);
headinfo.append("Server:").append("pmcse 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);
}
// 推送响应信息
public void pushToBrowser(int code) throws IOException {
if (headinfo == null) {
code=505;
}
createHeadInfo(code);
bw.append(headinfo);//头信息
bw.append(content);//正文
bw.flush();
}
}
package pk2;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
* 加入了Servlet解耦了业务代码
*
*/
public class Server6 {
private ServerSocket serversocket;
public static void main(String[] args){
// System.out.println("启动服务");
Server6 server=new Server6();
server.start();
}
//启动
public void start(){
try {
serversocket=new ServerSocket(8889);
this.receive();
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败。");
}
}
//停止服务
public void stop(){
}
//接收连接
public void receive(){
try {
Socket client= serversocket.accept();
System.out.println("一个客户端建立连接。");
//获取请求协议
Request request=new Request(client);
//返回数据
Response response=new Response(client);
Servlet servlet=null;
if(request.getUrl().equals("login")){
servlet= new LoginServlet();
}else if(request.getUrl().equals("reg")){
servlet=new RegisterServlet();
}else{
//首页
}
servlet.service(request, response);
//写到客户端
response.pushToBrowser(200);//状态写出开关
} catch (IOException e) {
e.printStackTrace();
System.out.println("连接失败。");
}
}
}
package pk2;
/**
* 服务器小脚本接口
* @author pmc
*
*/
public interface Servlet {
void service(Request request,Response response);
}