To begin I am a bit new to java.
I have a web application I have been assigned to work on. It collects various user inputs via form and sends them via an a4j commandButton to a method in my jar folder. The method uses the form data to construct a web service client call. Part of the requirement is that I pass, as an element in the web service call, the current JSESSIONID from the request.
Steps I have taken:
In the class that contains the method I am calling I have set up getters and setters (outside of the helper class below).
I have added a helper class to my class as follows:
class GetSessionId extends HttpServlet {
private String sessionid;
public void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
sessionid = session.getId();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public String getSessionId(){
return sessionid;
}
public void setSessionId(String sessionid){
this.sessionid=sessionid;
}
}
When I need the get the sessionid I used:
GetSessionId session_ID = new GetSessionId();
String sessionid = session_ID.getSessionId();
String sessionId = sessionid;
System.out.println("show me = " + sessionId);
But in the console (testing on my localhost) sessionid is null.
What am I doing wrong?
Related
I'm not familiar with Junit testing. For example, how can I write a Unit test for this servlet?
I really don't know where to start, please!!!
Obviously he accesses the database and I don't know how to do the test to check if the credentials entered are present in the db. Could you give me an example about this servlet please?
/**
* Servlet implementation class LoginPatient
*/
#WebServlet("/LoginPatient")
public class LoginPatient extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public LoginPatient() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fiscal_code=request.getParameter("fiscal_code");
String user_password= request.getParameter("user_password");
PrintWriter out=response.getWriter();
ProfileManager pM=new ProfileManager();
UserBean patient= pM.ReturnPatientByKey(fiscal_code, user_password);
if(patient != null) {
HttpSession session= request.getSession();
session.setAttribute( "user" , patient);
session.setMaxInactiveInterval(-1);
out.println("1");
}
else {
out.println("0");
}
}
}
A unit test for this servlet should not actually access the DB. It should test that the servlet behaves correctly given the various results ProfileManager may return.
You need to use dependency injection so that you can mock ProfileManager in your unit test.
How you do this depends on your framework. In spring you would say:
#Component
public class LoginPatient extends HttpServlet {
...
#Autowired
public LoginPatient(ProfileManager profileManager) { ... }
...
}
Then in your test use Mockito (this is a sketch not compilable code)
public void testPresent() {
// mock the request and response, and the session
HttpServletRequest req = mock(HttpServletRequest.class);
Session session = mock(HttpSession.class);
when(req.getSession()).thenReturn(session);
...
// you might want to mock the UserBean instance too
ProfileManager pm = mock(ProfileManager.class);
when(pm.ReturnPatientByKey("aCode", "aPassword")).thenReturn(new UserBean(...));
LoginPatient servlet = new LoginPatient(pm);
servlet.doPost(req, res);
// verify that the session had the right things done to it
}
I just want to understand the purpose behind returning back to the calling servlet, after the execution of forwarded servlet.
Below example simply shows that after execution of forwarded servlet, control returns back to calling servlet.
//servlet1 Code (Forwarding to servlet2)
#WebServlet("/servlet1")
public class Login extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher rd = request.getRequestDispatcher("servlet2");
rd.forward(request, response);
System.out.println("Returned to Calling Servlet");
}
}
//servlet2 Code (returning control to servlet1)
#WebServlet("/servlet2")
public class WelcomeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String n = "to Servlet2";
out.print("Welcome " + n);
}
}
Output ::
Welcome to Servlet2 (on Browser)
Returned to Calling Servlet (on Console)
Need clarification :
After committing response, why it's returning back to servlet1
I would like to upload a string to a server in java. I would not like to just upload a file I would like to upload a string
String toupload = "Cheese"; Upload(toupload);
like this
You can upload it using both POST method, and GET methods:
If you use the GET method: you pass the string in the url.
ex: localhost:8080/yourwebproject/yourservlet?nameofyourstring=itsvalue
And then in your servlet you can do something like:
public myServlet extends HttpServlet(HttpServletRequest request, HttpServletResponse response)
public myServlet() {
super();
}
/*This method will be called by your web-container if you used the get method..*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
//here we go
String str = request.getParameter("nameOfyourString");
}`
}
If you use the POST method, you have to implement the doPost with same logic..
I am working in Netbeans IDE and i have wrote JS-code for sending HTTP Request to server:
function applyFilter(){
idFilterJS = getRadioValue();
var url = "applyfilter?action=applyfilterXML&id=" + idFilterJS;
req = initRequest();
req.open("GET", url, true);
req.onreadystatechange = applyFilterCallBack;
req.send(null);
}
Next, I had a breakpoint in ApplyFilterServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
session = request.getSession();
String action = request.getParameter("action");
}
I have two questions:
What does MonitorRequestWraper mean for request variable during debug mode?
"request.getParameter("action");" returns null. Why?
Thanks!
It extends the request. Dig down into the attributes under "inherited" to find your attributes.
public class MonitorRequestWrapper extends HttpServletRequestWrapper
I am working on a filter, this code fails to execute/response.write if there is a 'forward' involved in the request. But it works fine for basic servlets that simply steam HTML content to the user. How can address "forwards" with this code.
For example, here is the filter that simple captures text content and attempts to manipulate that content.
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession(false);
CharResponseWrapper responseWrapper = new CharResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, responseWrapper);
final boolean commit1 = responseWrapper.isCommitted();
final boolean commit2 = response.isCommitted();
if (!commit2) {
final String res = responseWrapper.toString().replaceAll("(?i)</form>", "<input type=\"hidden\" name=\"superval\" value=\""+superval"\"/></form>");
response.getWriter().write(res);
}
return;
}
...
This works for most basic servlets, the goal is at the line with the "replaceAll".
Now, if I create a servlet with a 'forward' the code does not work, it fails at the line with 'if (!commit2)' because the stream is already committed apparently?
For example, if I make a request to this servlet and tie the filter to this servlet, then the filter does not execute completely.
public class TestCommitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("TestCommitServlet2").forward(req, resp);
}
#Override
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
And here is the servlet that I am forwarding to:
public class TestCommitServlet2 extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final PrintWriter out = resp.getWriter();
resp.setContentType("text/html");
out.println("<html><body>(v-1)testing<form action='test'><input type='submit' value='Run' /> </form></body></html>");
}
#Override
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Tl;dr : Do I have to make this call 'if (!commit2) {' The code works without it. Under this code, how would I avoid Response already committed or IllegalStateExceptions (around the line with response.getWriter().write(res);
More on the issue here:
https://codereview.stackexchange.com/questions/41260/capturing-content-within-a-j2ee-filter-and-then-replacing-this-text-request-for
I´m using Servlet API 3.0 to check this scenario.
What I found is the following. Using your code for the servlet and the filters when I call the TestCommitServlet2 , I´m able to see the following output.
http://localhost:8080/Question/TestCommitServlet2
(v-1)testing
Button here
com.koitoer.CharResponseWrapper#5b5b6746
When I call the servlet TestCommitServlet , Im able to see the following.
http://localhost:8080/Question/TestCommitServlet
(v-1)testing
Button here
this shown that filter is not apply to this forwarded request at all.
So, I remember that some filters can act in diverse DispatcherTypes as FORWARD, INCLUDE, ERROR, ASYNC and the commong REQUEST, what I decide is change the filter declaration to.
#WebFilter(filterName = "/MyFilter", urlPatterns = { "/TestCommitServlet2" }, dispatcherTypes = {
DispatcherType.FORWARD, DispatcherType.REQUEST })
public class MyFilter implements Filter {
Then when I excecute a GET over the servlet TestCommitServlet I got:
(v-1)testing
Button
com.koitoer.CharResponseWrapper#1b3bea22
the above shown that Filter is now applied to the forward request.
Also if I remove or comment lines for if (!commit2) { code still works, so there is no IllegalStateException as request need to pass over the filter which is who invoke the doChain method.
One note more, if you try to replace the content of the response using this.
responseWrapper.toString().replaceAll
You are doing it wrong as responseWrapper.toString() returns something like this CharResponseWrapper#5b5b6746, not the content, if you want to modify the response use a Wrapper that extends from HttpServletResponseWrapper and override the correct methos to manipulate the outpustream.