Filter to intercept server output - servlet-filters

I have to write a filter that will change the server's output. Here is my code:
#WebServlet("/ServerClass")
public class ServerClass extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String text = request.getParameter("text");
PrintWriter pw = new PrintWriter(response.getOutputStream());
pw.write(text);
pw.close();
}
}
The filter implementation:
#WebFilter("/TextFilter")
public class TextFilter implements Filter {
public TextFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
PrintWriter out = response.getWriter();
TextResponseWrapper wrapper = new TextResponseWrapper((HttpServletResponse)response);
chain.doFilter(request, wrapper);
String responseText = wrapper.toString();
responseText.replaceAll("text", "****");
response.setContentLength(responseText.getBytes().length);
out.println(responseText);
out.close();
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
class TextResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public TextResponseWrapper(HttpServletResponse response){
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter(){
return new PrintWriter(output);
}
}
web.xml
<filter>
<filter-name>TextFilter</filter-name>
<filter-class>TextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TextFilter</filter-name>
<servlet-name>ServerClass</servlet-name>
</filter-mapping>
The problem is that I am getting the following error:
java.lang.IllegalStateException: getWriter() has already been called for this response
at org.apache.catalina.connector.Response.getOutputStream(Response.java:604)
at org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:197)
at javax.servlet.ServletResponseWrapper.getOutputStream(ServletResponseWrapper.java:96)
at ServerClass.doPost(ServerClass.java:19)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at TextFilter.doFilter(TextFilter.java:33)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
So from what I understood after some research, is that this error is caused by the fact that I open the OutputStream from both ServerClass and TextFilter. But how can I intercept the server output without doing so? Which is the correct approach in this situation?

The servlet is calling getOutputStream, not getWriter. Your class TextResponseWrapper does not override getOutputStream.
So you have two choices:
Override getOutputStream to return your wrapping stream.
Change the servlet's code from PrintWriter pw = new PrintWriter(response.getOutputStream()); to PrintWriter pw = new PrintWriter(response.getWriter());

Related

CFX SOAP call getting SSL error readHandshakeRecord

I am using SOAP call using cxf, and getting ssl readHandshakeRecord exception
unwinding now org.apache.cxf.interceptor.Fault: Could not send Message.
 at
reason:
java.base/java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLException: SSLException invoking https://myservice/Services: readHandshakeRecord
 at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at
.......
I also try to skip ssl validation with trust all certs
static {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
} };
SSLContext sc = null;
try {
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
} catch (Exception e) {
log.error("Exception ssl ",e);
}
HostnameVerifier allHostsValid = new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
};
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
but still getting error
I also tries with TLSClientParameters
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(Hello.class);
factory.setAddress(address);
Hello portType = (Hello) factory.create();
try {
HostnameVerifier allHostsValid = new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
};
HTTPConduit httpCon = (HTTPConduit) ClientProxy.getClient(portType).getConduit();
TLSClientParameters parameters = new TLSClientParameters();
parameters.setSSLSocketFactory(sslSocketFactory);
parameters.setDisableCNCheck(true);
parameters.setHostnameVerifier(allHostsValid);
parameters.setTrustManagers(new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws java.security.cert.CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws java.security.cert.CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}});
httpCon.setTlsClientParameters(parameters);
} catch (Exception e) {
System.out.ptintln( e);
}
but still getting same error
Need your valuable help
thank you in advance!

Browser not prompting for credentials using basic authentication

My goal is to provide authentication to a single resource on the server, for this I am using custom filter. I am not using #NameBinding because of constraint of using JAVA 1.6.Using Response.header(HttpHeaders.WWW_AUTHENTICATE,"Basic") is not prompting for credentials.
Using ContainerRequestFilter is not helping my cause as it will put filter on every resource of server.
Filter
#Provider
public class AuthenticationFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
System.out.println("Entered authentication filter");
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.AUTHORIZATION,"Basic")
.entity("Credentials are required to access this resource.")
.build());
// chain.doFilter(req, resp);
}
#Override
public void init(FilterConfig arg0) throws ServletException {}
#Override
public void destroy() {}
}
web.xml mapping
<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>Utils.LDAPAuthentication.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/download</url-pattern>
</filter-mapping>
The response I am getting on hitting the webservice is
So as suggested by Paul , I used HttpServletResponse.
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if(request.getHeader("Authorization")==null){
response.setHeader(HttpHeaders.WWW_AUTHENTICATE,"Basic");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
else{
String credentials = request.getHeader("Authorization");
}

How to resolve java.lang.NullPointerException in Page Object Model in Selenium?

TestBase Class:-
public class TestBase {
public static WebDriver driver;
public static Properties prop;
// TestBase class constructor is used to initialize the properties object to
// fetch config variables from config.properties file.
public TestBase() {
try {
// File src = new File("./src/main/java/com/config/config.properties");
File src = new File(".\\src\\main\\java\\com\\config\\config.properties");
FileInputStream fs = new FileInputStream(src);
prop = new Properties();
prop.load(fs);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void initialization() throws InterruptedException {
String browserName = prop.getProperty("Browser");
if (browserName.equals("chrome")) {
System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
} else {
System.out.println("Oops! Exception has Caught");
}
driver.manage().window().maximize();
driver.get(prop.getProperty("URL"));
}
}
HomePage Class:-
public class HomePage extends TestBase {
TestUtil testUtil;
#FindBy(xpath = "//a[#title='Update your profile, personal settings, and more']")
WebElement updateProfile;
#FindBy(xpath = "//a[#title='Create a New Post']")
WebElement createNewPost;
#FindBy(xpath="(//span[#class='count'])[2]")
WebElement drafts;
#FindBy(xpath="//a[#class='button masterbar__recent-drafts-see-all is-compact is-borderless']")
WebElement seeAll;
public HomePage() {
PageFactory.initElements(driver, this);
}
public ProfilePage updateYourProfile() throws AWTException, InterruptedException {
updateProfile.click();
Thread.sleep(3000);
return new ProfilePage();
}
public NewPostPage createNewPost() throws InterruptedException {
createNewPost.click();
Thread.sleep(3000);
return new NewPostPage();
}
public DraftsPage draftsPage() throws InterruptedException {
createNewPost.click();
Thread.sleep(3000);
drafts.click();
Thread.sleep(3000);
seeAll.click();
Thread.sleep(3000);
return new DraftsPage();
}
}
DraftsPage Class:-
public class DraftsPage extends TestBase {
#FindBy(xpath="(//button[#title='Toggle menu'])[1]")
WebElement toggleMenu;
#FindBy(xpath="(//button[#role='menuitem'])[2]")
WebElement trash;
public void toggleMenu() throws InterruptedException {
toggleMenu.click();
Thread.sleep(3000);
trash.click();
Thread.sleep(3000);
}
}
DraftsPageTest Class:-
public class DraftsPageTest extends TestBase {
ProfilePage myProfile;
LoginPage loginpage;
HomePage homepage;
NewPostPage newPostPage;
DraftsPage draftspage;
public DraftsPageTest() {
super();
}
#BeforeMethod
public void setUp() throws InterruptedException {
initialization();
loginpage = new LoginPage();
loginpage.login();
Thread.sleep(3000);
loginpage.userName(prop.getProperty("username"));
Thread.sleep(3000);
homepage = loginpage.password(prop.getProperty("password"));
Thread.sleep(3000);
myProfile = new ProfilePage();
Thread.sleep(3000);
newPostPage = new NewPostPage();
Thread.sleep(3000);
draftspage = new DraftsPage();
Thread.sleep(3000);
}
#Test
public void DraftsPageTest() throws InterruptedException {
homepage.draftsPage();
Thread.sleep(3000);
draftspage.toggleMenu();
Thread.sleep(3000);
}
#AfterMethod
public void close() {
driver.close();
}
}
Error Message:-
FAILED: DraftsPageTest
java.lang.NullPointerException
at com.pages.DraftsPage.toggleMenu(DraftsPage.java:18)
at com.testCases.DraftsPageTest.DraftsPageTest(DraftsPageTest.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Description:-
I am trying to develop TestNG Framework with the help of Selenium.
I have developed HomePage, LoginPage, ProfilePage, NewPostPage, DraftsPage. While I was running the DraftsPageTest.java, #BeforeMethod was working fine
and the moment control comes to #Test, homepage.draftsPage(); is also working fine. But the moment control comes to draftspage.toggleMenu(); it is throwing
java.lang.NullPointerException.
Any help will be highly appreciated.
Thanks in advance:)
There's a bug in your code.
Please add a constructor which calls PageFactory.initElements(driver, this); to your com.pages.DraftsPage class [ similar to the HomePage constructor in your shared code ]. That should fix the problem.
The reason behind the NullPointerException is because, there's no call to PageFactory.initElements() the WebElement toggleMenu is not being initialised.

extent report 2.41 throws null pointer when logger is in method ( class 1) called from method (class 2)

java.lang.NullPointerException
at runnerClasses.Class1.meth1(Class1.java:106)
at runnerClasses.Class2.meth2(Class2.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:661)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:744)
at org.testng.TestRunner.run(TestRunner.java:602)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
at org.testng.SuiteRunner.run(SuiteRunner.java:289)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
at org.testng.TestNG.runSuites(TestNG.java:1144)
at org.testng.TestNG.run(TestNG.java:1115)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Here is the code
public class Class1Method1{
public ExtentReports report;
ExtentTest logger;
#BeforeClass
public void somemeth(){
report = new ExtentReports(System.getProperty("user.dir") + "\\src\\test\\java\\Reports\\TestReport.html", false, DisplayOrder.NEWEST_FIRST);
report.loadConfig(new File(System.getProperty("user.dir") + "\\src\\test\\java\\Reports\\extent-config.xml"));
logger = report.startTest("desc", "Test1");
}
#Test()
public void meth1(String some1){
logger.log(LogStatus.PASS, "desc");
}
#AfterClass
public void afterreports(){
report.flush();
driver.quit();
}
}
Class2Method2{
public ExtentReports report;
ExtentTest logger;
#BeforeClass
public void somemeth1(){
report = new ExtentReports(System.getProperty("user.dir") + "\\src\\test\\java\\Reports\\TestReport.html", false, DisplayOrder.NEWEST_FIRST);
report.loadConfig(new File(System.getProperty("user.dir") + "\\src\\test\\java\\Reports\\extent-config.xml"));
logger = report.startTest("desc", "Test1");
}
#Test()
public void meth2() throws InterruptedException {
class1.meth1("Para1")
}
#AfterClass
public void afterreports(){
report.flush();
driver.quit();
}
}
extent report 2.41 throws null pointer when logger is in method ( class 1) called from method (class 2)
extent logger is in method of class1 which is being called in method of class2.
if I comment the extent report logger in Class1Method1, code works well..am i missing something???
unable to edit here anymore...

Unit testing a jee filter

I am trying to test this filter:
public class HttpMethodOverrideHeaderFilter extends OncePerRequestFilter {
private static final String X_HTTP_METHOD_OVERRIDE_HEADER = "X-HTTP-Method-Override";
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (isMethodOverriden(request)) {
HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, request.getHeader(X_HTTP_METHOD_OVERRIDE_HEADER).toUpperCase(Locale.ENGLISH));
filterChain.doFilter(wrapper, response);
}
else {
filterChain.doFilter(request, response);
}
}
private boolean isMethodOverriden(HttpServletRequest request) {
String methodOverride = request.getHeader(X_HTTP_METHOD_OVERRIDE_HEADER);
return RequestMethod.POST.name().equalsIgnoreCase(request.getMethod()) &&
(RequestMethod.PUT.name().equalsIgnoreCase(methodOverride) || RequestMethod.DELETE.name().equalsIgnoreCase(methodOverride));
}
protected static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
private final String method;
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
super(request);
this.method = method;
}
#Override
public String getMethod() {
return this.method;
}
}
}
And this is the unit test:
#RunWith(MockitoJUnitRunner.class)
public class HttpMethodOverrideHeaderFilterTest {
private static final String X_HTTP_METHOD_OVERRIDE_HEADER = "X-HTTP-Method-Override";
private HttpMethodOverrideHeaderFilter httpMethodOverrideHeaderFilter;
#Mock
private HttpServletRequest httpServletRequest;
#Mock
private HttpServletResponse httpServletResponse;
#Mock
private FilterChain filterChain;
#Before
public void setUp() {
httpMethodOverrideHeaderFilter = new HttpMethodOverrideHeaderFilter();
}
#Test
public void testDoFilterInternalWithPUTMethodAsOverrideHeader() throws Exception {
when(httpServletRequest.getHeader(X_HTTP_METHOD_OVERRIDE_HEADER)).thenReturn("PUT");
when(httpServletRequest.getMethod()).thenReturn("POST");
HttpServletRequest wrapper = new HttpMethodOverrideHeaderFilter.HttpMethodRequestWrapper(httpServletRequest, "PUT");
httpMethodOverrideHeaderFilter.doFilterInternal(httpServletRequest, httpServletResponse, filterChain);
verify(filterChain).doFilter(wrapper, httpServletResponse);
}
}
The test is not passing as wrapper is not the same instance. Basically what I need to know is if the wrapper was set the PUT method. Any ideas?
I found a way to do it:
#Test
public void testDoFilterInternalWithPUTMethodAsOverrideHeader() throws Exception {
when(httpServletRequest.getHeader(X_HTTP_METHOD_OVERRIDE_HEADER)).thenReturn("PUT");
when(httpServletRequest.getMethod()).thenReturn("POST");
httpMethodOverrideHeaderFilter.doFilterInternal(httpServletRequest, httpServletResponse, filterChain);
ArgumentCaptor<ServletRequest> requestCaptor = ArgumentCaptor.forClass(ServletRequest.class);
ArgumentCaptor<ServletResponse> responseCaptor = ArgumentCaptor.forClass(ServletResponse.class);
verify(filterChain).doFilter(requestCaptor.capture(), responseCaptor.capture());
HttpMethodOverrideHeaderFilter.HttpMethodRequestWrapper wrapper = (HttpMethodOverrideHeaderFilter.HttpMethodRequestWrapper) requestCaptor.getValue();
assertEquals(wrapper.getMethod(), "PUT");
}
if anyone know any better way, let me know!!!