JavaEE

WEB开发中
前端jsp 定位统一绝对定位/网站名/**/** inc 只能相对路径 inc/**
后端 存照片转发等/**/** 重定向特殊 要加网站名 response.sendRedirect("/BwfBook/manage/admin/home");session已经存入内容 那么重定向也可以
cookie2.setPath("/Book"); cook尽量设置在网站名下
@WebServlet("/manage/admin/*")

数据库data类型 可以用java字符串插入
ajax请求时如果统一用JSON对象传输 那么穿的字符串也要转JSON
String xxx="{"name":"dasd"}";
JSONObject j =JSONObject.fromObject(xxx);

URL 统一资源定位符·
http://127.0.0.1:8080/examples/index.html
协议 ip port 资源网络路径
从页面读取数据 设utf8 request.setcha...
<%@include file="" %>
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bwfbook?useUnicode=true&characterEncoding=utf-8",
"root", "root");
if (seleCate(sql, cid).size() > 0) {
return true;
if (admin == null) {
request.setAttribute("msg", "不要越界");
request.getRequestDispatcher("admin-login.jsp").forward(request, response);
//return;???
必须return
}
<h1>JSP上的EL:表达式语言</h1>
<p>${3 + 5 } : ${ 3 + 5 }</p>
<p>${3 * 5 } : ${ 3 * 5 }</p>
<p>${3 % 5 } : ${ 3 % 5 }</p>
<p>${3 mod 5 } : ${ 3 mod 5 }</p>
<p>${3 &lt; 5 } : ${ 3 lt 5 }</p>
<p>${3 &gt; 5 } : ${ 3 gt 5 }</p>
<p>${3 &lt;= 5 } : ${ 3 le 5 }</p>
<p>${3 &gt;= 5 } : ${ 3 ge 5 }</p>
<p>${3 == 5 } : ${ 3 eq 5 }</p>
<p>${3 != 5 } : ${ 3 != 5 }</p>
核心标签库:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:forEach items="${ newsList }" var="n" varStatus="sta">
<li ${sta.count % 2 == 1 ? "style='color:red;'" : " " }>${ n }</li>
</c:forEach>
<c:set value="25" var="age" scope="request" />
<c:out value="${ teacher }" default="暂无老师"></c:out>
<c:choose>
<c:when test="${ score >= 90 }">
<span style="color: red;">优秀</span>
</c:when>
<c:when test="${ score >= 80 }">
<span style="color: orange;">良好</span>
</c:when>
<c:when test="${ score >= 60 }">
<span style="color: blue;">中等</span>
</c:when>
<c:otherwise>

</c:otherwise>
</c:choose>
<c:if test="${ 6 < 5 }">
ok
</c:if>
JSP中的内置对象/隐式对象:
1、request:请求对象
request.setCharacterEncoding("utf-8");
request.getRequestDispatcher("book-mgr.jsp").forward(request, response);
request.getRequestURL() 当前url 跳转时候可以用
Response.sendRedirect(“aa.jsp”);
2、response:响应对象
3、session:会话
session.invalidate();会话失效
session.setMaxInactiveInterval(10*60) 10秒会话时效
4、application:整个网站应用程序
5、pageContext:页面作用域
6、out:输出对象
7、page:代表JSP页面本身
8、config:配置对象(Servlet中)
9、exception:异常对象(只能在错误处理JSP中使用)

EL:表达式语言(Expression Language),只能在JSP中用,基本语法:${ 表达式 }
1、赋值运算符、算数表达式、关系表达式、逻辑表达式、三元运算符
2、pageScope、reqeustScope、sessionScope、applicationScope中的属性(可以省略)
3、对象.属性、对象.方法([参数列表])
4、列表[索引]、map[key]
5、[not] empty 集合

JSTL:JSP标准标签库(JSP Standard Tag Library)

使用标签库的步骤:
(1)在JSP中使用 taglib 指令 导入要用的标签库
(2)在JSP中使用导入的标签库中的标签

forEach标签:
(1) 遍历集合
(2) 循环

if标签:
国际化标签
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="f"%>
<%
String x = (String) request.getParameter("lang");
if (x != null) {
session.setAttribute("x1", x);
} else if (session.getAttribute("x1") == null) {
session.setAttribute("x1", request.getLocale().toString());
}
%>
<f:setLocale value="${x1 }" />
<f:bundle basename="res">
<f:message key="a" />
</f:bundle>
在do页面传参时
String x= (String)session.getAttribute("x1"); // "en_US"
Locale locale = new Locale(x.substring(0,x.indexOf("_")), x.substring(x.indexOf("_")+1));

ResourceBundle x3= ResourceBundle.getBundle("res", locale);
request.setAttribute("msg", x3.getString("admin.login.fail.message"));
request.getRequestDispatcher("admin-login.jsp").forward(request, response);

错误页面打印
<%@ page language="java" contentType="text/html; charset=UTF-8"
isErrorPage="true" pageEncoding="UTF-8"%>
<%
out.print(exception);
%>
错误页面声明
<%@page import="com.Xyz.service.AdminService,com.Xyz.entity.*,java.util.*"
errorPage="error.jsp"%>
///////////////////////////////////////////////////////////////////////
在查询所有书的bookdao里面 如果list是全局变量 bookservice bookdao也是全局变量 那么getallbooks 如果调用两次 那么
返回的list就add两次le 要么 bookdao不是全局变量 要么 list
不是全局 或者两个都不是
///////////////////////////////////////////////////////////////////////
今天在eclipse想把之前的Tomcat 6删掉,重新配置一个,不料没有下一步

Cannot create a server using the selected type 这句话出现在窗口上面,应该不是很解决的问题.......

重启下 eclipse,还是不行哦

出绝招了,呵呵.....上网搜搜

还真的找到解决的方法了,如下:

1.退出 eclipse

2.到[工程目录下]/.metadata/.plugins/org.eclipse.core.runtime

3.把org.eclipse.wst.server.core.prefs和 org.eclipse.jst.server.tomcat.core.prefs这两个文件去掉

4.重启eclipse
//////////////////////////////////////////////////////////////////////////////////////////////////////
分页显示类
package com.Xyz.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class Paging {

private int totalCount;//总条数
private int pageSize;// 每页个数
private int pageTotal;// 一共多少页
private int pageNO; //当前页
private int pageNext; // 后一页
private int pagePrev; //前一页

public Paging(int totalCount, int pageSize, HttpServletRequest request, String pageNOName) { //pageNOName 不同类型的分页
this.totalCount = totalCount; //传入总条数
this.pageSize = pageSize; //传入每页个数
//String url = request.getRequestURL().toString();

//根据要分页的数据的总数量,及pageSize,计算出共有多少页
this.pageTotal = this.totalCount % this.pageSize == 0 ?
this.totalCount / this.pageSize : this.totalCount / this.pageSize + 1;
pageTotal = pageTotal == 0 ? 1 : pageTotal; //如果没有 那么必须是第一页

HttpSession session = request.getSession();
//尝试从session中获取当前要看的某一页的属性
if(session.getAttribute(pageNOName) == null) {
session.setAttribute(pageNOName, 1);//如果没有获取到属性 那么必定第一次打开 属性默认为1
}
//request中有pageNO参数的时候,更新session中的当前要看的某一页的值
if(request.getParameter("pageNO") != null) { //点击上下页首尾页会传入pageNO 如果没有 走上面 属性默认为1
try {
session.setAttribute(pageNOName, Integer.parseInt(request.getParameter("pageNO")));
//如果有 那么转成int
} catch(NumberFormatException ex) {
}
}
pageNO = (Integer)session.getAttribute(pageNOName); //取出当前页 在session
if(pageNO < 1) {
pageNO = 1; //如果小于1 那么就是1
}
if(pageNO > pageTotal) {
pageNO = pageTotal; //如果小于最大页数 那么就是最大页数
}
session.setAttribute(pageNOName, pageNO); //把当前页存在session里

pagePrev = pageNO == 1 ? 1 : pageNO - 1; //前一页 为-1 最小为1
pageNext = pageNO == pageTotal ? pageNO : pageNO + 1; //后一页 为+1 最大为最大页数
}

public int getTotalCount() {
return totalCount;
}

public int getPageSize() {
return pageSize;
}

public int getPageTotal() {
return pageTotal;
}

public int getPageNO() {
return pageNO;
}

public int getPageNext() {
return pageNext;
}

public int getPagePrev() {
return pagePrev;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
文件上传
action="do_bookSave.jsp" method="post" enctype="multipart/form-data" 这个jsp一定要注意空格 不会报错会引发下面file报错!!!
<input type="file" name="bphoto" />
处理界面 导包com.jspsmart.upload.*
SmartUpload su = new SmartUpload();
su.initialize(pageContext);
su.upload();
File file = su.getFiles().getFile(0);
String newName = new java.text.SimpleDateFormat("yyyyMMddHHmmssSSS").format(new java.util.Date())
.concat(file.getFileName()+file.getFileExt()); //这个必须要电脑开了拓展名显示才可以实现
file.saveAs("/photo/" + newName);
String bauthor = su.getRequest().getParameter("bauthor");
////////////////////////////////////////////////////////////////////////////////////////////////////
购物车物品

购物车
////////////////////////////////////////////////////////////////////////////////////////////////////
记住密码
<tr>
<td style="text-align: right;">登录账号:</td>
<td><input type="text" name="loginId" class="txt" value="${ cookie['userId'].value}" /></td>
</tr>
<tr>
<td style="text-align: right;">登录密码:</td>
<td><input type="password" name="loginPsw" class="txt"
value="${ cookie['userPwd'].value}" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>记住密码<input type="checkbox" name="c1" ${cookie['userId'].value==null?'':'checked' }/></td>
Cookie cookie1= new Cookie("loginId",admin.getaLoginID());
Cookie cookie2= new Cookie("loginPsw",admin.getaLoginPsw());
if(request.getParameter("remember")!=null){
cookie1.setMaxAge(2*7*24*60*60);
cookie2.setMaxAge(2*7*24*60*60);
}else{
cookie1.setMaxAge(0);
cookie2.setMaxAge(0);

}
response.addCookie(cookie1);
response.addCookie(cookie2);
////////////////////////////////////////////////////////////////////////////////////////////////////
Servlet
web.xml
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>servlet.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/t1</url-pattern>
</servlet-mapping>
class FirstServlet extends HttpServlet
重写doGet doPost方法 throws ServletException, IOException
resp.setContentType("text/html;charset=utf-8"); // header里面直接声明
PrintWriter out = resp.getWriter(); 输出对象
out.write(50) 和 out.print(50); 前者字符并且不能打印对象 后者直接输出 并且直接tostring
out.flush();
out.close();
Server let:服务器端的小程序


request
response

HttpSession session = request.getSession();
ServletContext application = session.getServletContext();

PrintWriter out = response.getWriter();
生命周期
public MyFirstServlet() {
System.out.println("MyFirstServlet 被实例化了.... : " + this);
}

@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("MyFirstServlet 被初始化了.... " + this);
this.uploadSavePath = config.getInitParameter("uploadSavePath");
System.out.println(this.uploadSavePath);
}

@Override
public void destroy() {
System.out.println("MyFirstServlet 被销毁了.... " + this);
}
web.xml
<servlet>
<servlet-name>MyFirstServlet</servlet-name>
<servlet-class>com.bwf.group11.book.web.servlet.MyFirstServlet</servlet-class>
<init-param>
<param-name>uploadSavePath</param-name>
<param-value>/photo/</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
////////////////////////////////////////////////////////////////////////////////////////////////////
验证码
<script type="text/javascript">
function changecode(){
var x= document.getElementById("img");
x.src="code.jsp?r="+Math.random()
}
</script>
<img id="img" src="code.jsp" onclick="changecode()"/>
<a href="javascript:changecode()" style="color: #64A26F;">换张图</a></td>
判断session.getAttribute("rand").equals(request.getParameter("code"))
////////////////////////////////////////////////////////////////////////////////////////////////////
过滤器filter implements Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.bwf.group11.book.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>ec</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
初始化编码
public void init(FilterConfig config) throws ServletException {
this.encoding = config.getInitParameter("ec");
if(this.encoding == null) {
this.encoding = "utf-8";
}
System.out.println(" CharacterEncodingFilter init..." + encoding);
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
req.setCharacterEncoding(encoding);
chain.doFilter(req, resp);
}
控制器controller extends HttpServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String uri = request.getRequestURI();
if(uri.equals("/BwfBook/user/loginForm")) {
loginForm(request, response);
protected void loginForm(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/jsp/common/user-login.jsp").forward(request, response);
}
监听器listener implements HttpSessionListener
public void sessionCreated(HttpSessionEvent event) {
event.getSession().setAttribute("cart", new Cart());
System.out.println("有用户会话建立了,我们向该会话中存储了一个购物车对象Cart!");
}
AJAX:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
当你前端用的JSON 请求 后端只返回字符串,就把字符串转皇城JSON字符串对象
比如验证注册时账户是否存在:
window.onload = function() {
// 为“账号文本框”绑定“失去焦点事件”的处理方法
document.getElementById("txtLoginId").onblur= checkLoginId;
}
// 当“账号文本框”失去焦点时,验证格式是否正确,可以注册!
function checkLoginId() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
var r = xhr.responseText; // 当服务器响应完成时,通过这个属性获取服务器响应的具体内容
if(r == "a") {
document.getElementById("tipLoginId").innerHTML = "账号已经存在,不能注册";
} else if(r == "b") {
document.getElementById("tipLoginId").innerHTML = "账号可以注册";
}
}
}
xhr.open("POST", "/BwfBook/user/checkLoginId");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("loginId=" + this.value);如果多个参数 那么中间用xmlhttp.send("fname=Bill&lname=Gates");
控制器写法
protected void checkloginId(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String loginId = request.getParameter("loginId");
String msg = "a";
if(userService.getUserDetailsByLoginId(loginId) == null) {
msg = "b";
}
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print(msg);
out.flush();
out.close();
}
比如加载分类以及分类里面的删除和保存:
window.onload = function() {
loadCategories();
document.getElementById("btnSave").onclick = saveNewCategory;

}
function loadCategories() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200) {
// xhr.responseText : "[{"name": "小说", "id": 1}, {"name":
"历史", "id": 3}, {"id": 6, "name": "哲学"}]";
var arr = JSON.parse(xhr.responseText);
var trs = "";
trs = "<tr>";
trs += "<td class="header" width="200">图书分类</td>";
trs += "<td class="header" width="60">操作</td>";
trs += "</tr>";
for(var i in arr) {
var o = arr[i];
trs += "<tr>";
trs += "<td>" + o.name + "</td>";
trs += "<td><a id='ad-" + o.id + "' href='javascript://'>删除</a></td>";
trs += "</tr>";
}
document.getElementById("ctable").innerHTML = trs;
var aList = document.getElementsByTagName("a");
for(var i = 0; i < aList.length; i++) {
var a = aList[i];
if(a.innerHTML == "删除") {
a.onclick = deleteConfirm;
}
}
}
}
xhr.open("GET", "/BwfBook/manage/category/getAllCategories");
xhr.send(null);
控制器private void getAllCategories(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
Category c = new Category();
c.setId(444);
c.setName("言情小说");
// 根据java中的单个对象,生成JSON串的方法
System.out.println(JSONObject.fromObject(c));
*/

// 把java中的数组、集合转换成JSON串
List<Category> all = service.getAllCategories();
JSONArray jsonArr = new JSONArray();
jsonArr.addAll(all);
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(jsonArr);
out.flush();
out.close();
}
控制器function deleteConfirm() {
var cid = this.id.substring(3);

if(confirm("是否要删除该分类信息?")) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200) {
var result = xhr.responseText;
if(result == "1") {
document.getElementById("tipDelete").innerHTML = "分类信息删除成功!";
loadCategories();
} else if(result == "-1"){
document.getElementById("tipDelete").innerHTML = "分类信息保存失败:该分类可能刚刚被别的管理员删除!";
loadCategories();
} else if(result == "0") {
document.getElementById("tipDelete").innerHTML = "分类信息保存失败:该分类下还有图书信息,无法删除!";
}
}
}
xhr.open("GET", "/BwfBook/manage/category/delete?cid=" + cid);
xhr.send(null);
}

}
前段 protected void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取要删除的图书分类ID参数,并转成int类型
int id = Integer.parseInt(request.getParameter("cid"));
Category c = new Category();
c.setId(id);
int result = service.deleteCategory(c);
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(result);
out.flush();
out.close();
}
AJAX文件上传
需要用到jquery
function saveNewBook() {
var title = $("[name='btitle']").val();
var author = $("[name='bauthor']").val();
var cid = $("[name='bcategoryid']").val();
var price = $("[name='bprice']").val();
var publisher = $("[name='bpublisher']").val();
var data = {"btitle": title, "bauthor": author, "bcategoryid": cid, "bprice": price, "bpublisher": publisher};
$.ajaxFileUpload({
"url" : "/BwfBook/manage/book/save", // 要提交到的URL(一般是servlet的虚拟路径)
"type" : "post", // 设置提交方法
"fileElementId" : "bphoto", //要上传的文件域标签的id属性(注意,必须同时写明name属性)
"data": data, //要提交的其他参数
"dataType": "text", //希望服务器返回的内容的类型
"success": function(result){ //当服务器响应后,调用该方法
var tip = "录入新图书信息失败:未知服务器异常,稍后再尝试";
if(result == "0") {
tip = "录入新图书信息失败:上传图书图片时未知异常!";
} else if(result == "1") {
tip = "录入新图书信息失败:上传的图书图片太大了,不能超过500KB!";
} else if(result == "2") {
tip = "录入新图书信息失败:上传的图书图片文件类型错误,不是一个图片文件!";
} else if(result == "3") {
tip = "录入新图书信息失败:上传的图书图片文件在存储到服务器时,异常!";
} else if(result == "4") {
tip = "录入新图书信息成功!";
var pageNO = $("#pageNO").html();
changePage(pageNO);
}
$("#tipSaveBook").html(tip);
}
});
}
两个AJAX请求,一个涉及文件上传,一个不涉及;
function openEditDialog(bid) {
$("#dialog-edit-book").dialog({
"autoOpen":true,
"open": function(){
$.getJSON("/BwfBook/manage/book/edit", {"bid": bid}, function(book){
$("#mbtitle").val(book.title);
$("#mbauthor").val(book.author);
$("#mbcategoryid").val(book.category.id);
$("#mbprice").val(book.price);
$("#mbpublisher").val(book.publisher);
$("#mbOldPhoto").attr("src", "/BwfBook/photo/" + book.photo);
$("#photoOld").val(book.photo);
$("#mbphoto").val("");
$("#tipModifyBook").html("");
});
} ,
"buttons" : {
"修改" : function(){
var title = $("#mbtitle").val();
var author = $("#mbauthor").val();
var cid = $("#mbcategoryid").val();
var price = $("#mbprice").val();
var publisher = $("#mbpublisher").val();
var photoOld = $("#photoOld").val();
var data = {"bookId": bid, "bphotoOld": photoOld, "btitle": title, "bauthor": author,
"bcategoryid": cid, "bprice": price, "bpublisher": publisher};

$.ajaxFileUpload({
"url": "/BwfBook/manage/book/modify",
"type": "post",
"fileElementId": "mbphoto",
"data": data,
"dataType": "text",
"success": function(result){
var tip = "修改图书信息失败:未知服务器异常,稍后再尝试";
if(result == "0") {
tip = "修改图书信息失败:上传图书图片时未知异常!";
} else if(result == "1") {
tip = "修改图书信息失败:上传的图书图片太大了,不能超过500KB!";
} else if(result == "2") {
tip = "修改图书信息失败:上传的图书图片文件类型错误,不是一个图片文件!";
} else if(result == "3") {
tip = "修改图书信息失败:上传的图书图片文件在存储到服务器时,异常!";
} else if(result == "4") {
tip = "修改图书信息成功!";
var $tr = $("#tr-" + bid);
$tr.find("td:eq(0)").html("《" + title + "》");
$tr.find("td:eq(1)").html(author);
var sel = document.getElementById("mbcategoryid");
var selectedName = sel.options[sel.selectedIndex].text;
$tr.find("td:eq(2)").html(selectedName);
$tr.find("td:eq(3)").html("¥" + price);
}
$("#tipModifyBook").html(tip);
}
});
},
"取消" : function(){
$(this).dialog("close");
}
}
});
}
AJAX UI
相当于windows.onload(){
}
$(function(){
$("#btnSave").on("click", saveNewBook);
// 整个网页文档加载完成时,定制了一个默认不打开的对话框组件
$("#dialog-edit-book").dialog({
"autoOpen": false, //设置对话框初始化的时候被隐藏
"modal": true, //设置对话框为“模态”对话框
"width": 400
});
})
<div id="dialog-edit-book" title="测试标题">
<div style="text-align: left;">
<input type="hidden" id="photoOld" />
<p>图书书名:<input type="text" id="mbtitle" /></p>
<p>图书作者:<input type="text" id="mbauthor" /></p>
<p>图书分类:
<select id="mbcategoryid">
<c:forEach items="${ allCategories }" var="c">
<option value="${c.id }">${c.name }</option>
</c:forEach>
</select>
</p>
<p>图书售价:<input type="text" id="mbprice" /></p>
<p>图书出版社:<input type="text" id="mbpublisher" /></p>
<p>当前图片:<img id="mbOldPhoto" src="/BwfBook/" width="90" height="120" /></p>
<p>图书图片:<input type="file" id="mbphoto" name="mbphoto" /></p>
<label id="tipModifyBook"></label>
</div>
</div>

/* 处理获取当前页图书信息的ajax请求 */
protected void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Paging paging = new Paging(bookService.getBookTotalCount(), 5, request, "bookPageNO");
List<Book> books = bookService.getBooks(paging.getPageNO(), paging.getPageSize());

/* 把分页对象和图书列表对象,转换成JSON字符串 */
JSONObject jsonMap = new JSONObject();
jsonMap.accumulate("p", paging);
jsonMap.accumulate("bs", books);

response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print(jsonMap);
out.flush();
out.close();
}

/* 处理图书编辑的ajax请求 */
protected void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int bid =Integer.parseInt(request.getParameter("bid"));
JSONObject jsonBook = JSONObject.fromObject(bookService.getBookById(bid));
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println(jsonBook);
out.flush();
out.close();
}

原文地址:https://www.cnblogs.com/lifusen/p/7278855.html