在 servlet 中使用 request.getSession() 将数据获取到 servlet 的最佳方式?

发布于 2024-10-20 09:43:17 字数 3346 浏览 1 评论 0原文

我将参数传递到 servlet 中以生成 Excel 电子表格。然后我意识到这在某些情况下可能很危险。特别是如果用户可以猜测参数并从另一家公司找到信息(就我而言)。然后我尝试使用 @Inject 注入 ViewLines sessionbean,但这似乎不起作用。然后我看着 使用 request.getSession() 方法从 BalusC 发布。这工作得很好,这只是从会话中提取我需要的对象,而不必传递它们。这是最好的方法吗?

谢谢。

@WebServlet(value = "/Excel")
public class ExcelServlet extends HttpServlet {

    public static int TIME_STAMP = 1;
    public static int OUNCES = 2;
    public static int REV = 3;
    public static int BENCHMARK = 4;
    public static int WORKBOOK = 0;
    @EJB
    PkgLoadService pkgLoadService;
    @EJB
    PkgLineService pkgLineService;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ");

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        OutputStream out = null;

        try {

            ViewLines viewLines = (ViewLines) request.getSession().getAttribute("viewLines");

            /*Date startDate = sdf.parse(request.getParameter("dateStart"));
            Date endDate = sdf.parse(request.getParameter("dateEnd"));
            PkgLine pkgLine = pkgLineService.find(Integer.parseInt(request.getParameter("pkgLineId")));
             * 
             */

            Date startDate = viewLines.getStartDate();
            Date endDate = viewLines.getEndDate();
            PkgLine pkgLine = viewLines.getSelectedPkgLine();

            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");

            WritableWorkbook workBook = Workbook.createWorkbook(response.getOutputStream());
            WritableSheet sheet = workBook.createSheet(pkgLine.getShortname(), WORKBOOK);
            WritableCellFormat dateFormat = new WritableCellFormat(DateFormats.FORMAT9);

            WritableCellFormat ouncesOverFormat = new WritableCellFormat();
            ouncesOverFormat.setBackground(Colour.RED);

            setupCellViews(sheet);
            setupColumnLables(sheet);

            List<PkgLoad> pkgLoadList = pkgLoadService.findBetweenDates(pkgLine, startDate, endDate);

            int row = 1;

            for (PkgLoad pkgLoad : pkgLoadList) {

                sheet.addCell(new Number(0, row, row));
                sheet.addCell(new DateTime(TIME_STAMP, row, pkgLoad.getTimeStamp(), dateFormat));

                if (pkgLoad.getOunces() > pkgLoad.getWrapSpecId().getBenchmark()) {
                    sheet.addCell(new Number(OUNCES, row, pkgLoad.getOunces(), ouncesOverFormat));
                } else {
                    sheet.addCell(new Number(OUNCES, row, pkgLoad.getOunces()));
                }
                sheet.addCell(new Number(REV, row, pkgLoad.getRevolutions()));
                sheet.addCell(new Number(BENCHMARK, row, pkgLoad.getWrapSpecId().getBenchmark()));

                row++;
            }

            workBook.write();
            workBook.close();

        } catch (Exception e) {
            throw new ServletException("Exception in Excel Servlet", e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

I was passing parameters into a servlet to generate an excel spreadsheet. I then realized this could be dangerous in some cases. Especially if a user could guess parameters and find out information from another company(in my case). I then tried to use @Inject to inject the ViewLines sessionbean but that didn't seem to work. Then I was looking at a post from BalusC using the request.getSession() method. This works fine and this just pulls the objects I need from session without having to pass them. Is this the best way to do this?

Thanks.

@WebServlet(value = "/Excel")
public class ExcelServlet extends HttpServlet {

    public static int TIME_STAMP = 1;
    public static int OUNCES = 2;
    public static int REV = 3;
    public static int BENCHMARK = 4;
    public static int WORKBOOK = 0;
    @EJB
    PkgLoadService pkgLoadService;
    @EJB
    PkgLineService pkgLineService;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ");

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        OutputStream out = null;

        try {

            ViewLines viewLines = (ViewLines) request.getSession().getAttribute("viewLines");

            /*Date startDate = sdf.parse(request.getParameter("dateStart"));
            Date endDate = sdf.parse(request.getParameter("dateEnd"));
            PkgLine pkgLine = pkgLineService.find(Integer.parseInt(request.getParameter("pkgLineId")));
             * 
             */

            Date startDate = viewLines.getStartDate();
            Date endDate = viewLines.getEndDate();
            PkgLine pkgLine = viewLines.getSelectedPkgLine();

            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");

            WritableWorkbook workBook = Workbook.createWorkbook(response.getOutputStream());
            WritableSheet sheet = workBook.createSheet(pkgLine.getShortname(), WORKBOOK);
            WritableCellFormat dateFormat = new WritableCellFormat(DateFormats.FORMAT9);

            WritableCellFormat ouncesOverFormat = new WritableCellFormat();
            ouncesOverFormat.setBackground(Colour.RED);

            setupCellViews(sheet);
            setupColumnLables(sheet);

            List<PkgLoad> pkgLoadList = pkgLoadService.findBetweenDates(pkgLine, startDate, endDate);

            int row = 1;

            for (PkgLoad pkgLoad : pkgLoadList) {

                sheet.addCell(new Number(0, row, row));
                sheet.addCell(new DateTime(TIME_STAMP, row, pkgLoad.getTimeStamp(), dateFormat));

                if (pkgLoad.getOunces() > pkgLoad.getWrapSpecId().getBenchmark()) {
                    sheet.addCell(new Number(OUNCES, row, pkgLoad.getOunces(), ouncesOverFormat));
                } else {
                    sheet.addCell(new Number(OUNCES, row, pkgLoad.getOunces()));
                }
                sheet.addCell(new Number(REV, row, pkgLoad.getRevolutions()));
                sheet.addCell(new Number(BENCHMARK, row, pkgLoad.getWrapSpecId().getBenchmark()));

                row++;
            }

            workBook.write();
            workBook.close();

        } catch (Exception e) {
            throw new ServletException("Exception in Excel Servlet", e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

再见回来 2024-10-27 09:43:17

另一种方法是将 Excel 的内容重构为如下方法:

void writeExcelSheet(ViewLines viewLines, OutputStream output) throws IOException

然后您可以在 JSF 操作方法中完成这项工作,而无需将其重定向到 servlet:

FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");
writeExcelSheet(viewLines, externalContext.getResponseOutputStream());
facesContext.responseComplete();

如有必要,可以在 servlet 中重用相同的内容(我不这样做)不这么认为,看到你现在遇到的问题:)):

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");
writeExcelSheet(viewLines, response.getOutputStream());

An alternative is to refactor that Excel thing to a method like follows:

void writeExcelSheet(ViewLines viewLines, OutputStream output) throws IOException

Then you can just do the job in a JSF action method without the need to redirect it to the servlet:

FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");
writeExcelSheet(viewLines, externalContext.getResponseOutputStream());
facesContext.responseComplete();

And reuse the same in the servlet, if necessary (I don't think it is, seeing the problem you have now :) ):

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=" + pkgLine.getShortname() + ".xls");
writeExcelSheet(viewLines, response.getOutputStream());
原野 2024-10-27 09:43:17

特别是如果用户可以猜测参数并从另一家公司找到信息(就我而言)。

假设您引用的是 URL 参数,例如 /Excel?companyid=1234,那么另一种方法是在您的 Servlet/控制器中检查是否允许当前用户查看他们请求的对象(您不这里没有某种身份验证和授权,不是吗?)。

Especially if a user could guess parameters and find out information from another company(in my case).

Assuming you are referring to URL parameters, like /Excel?companyid=1234, then another approach is to check within your Servlet/controller if the current user is allowed to view the object they are requesting (you don't have some sort of authentication and authorization here, don't you?).

缱倦旧时光 2024-10-27 09:43:17

如果您只需要请求范围的对象,请使用 request.setAttribute()
如果你把东西放在会话中,你就会面临内存问题的风险。通常,会话是为了维护浏览器请求之间的会话状态。听起来你的应用程序不需要状态。

If you only need objects for the request scope, use the request.setAttribute()
If you put things in the session you risk memory problems. Typically, the session is to maintain conversational state between browser requests. Sounds like your app doesn't need state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文